Code Monkey home page Code Monkey logo

sonic-py-swsssdk's Introduction

Total alerts Language grade: Python

Python SwSS SDK

Python utility library for SONiC Switch State Service database access

See the SONiC Website for more information about the SONiC project

Database names are defined by Switch State Service. See the sonic-swss-common project.

Example Usage

>>> import swsssdk
>>> swss = swsssdk.SonicV2Connector()
>>> swss.db_list
dict_keys(['COUNTERS_DB', 'ASIC_DB', 'APPL_DB'])
>>> dir(swss)
['APPL_DB', 'ASIC_DB', 'CONNECT_RETRY_WAIT_TIME', 'COUNTERS_DB', 'DATA_RETRIEVAL_WAIT_TIME', 'KEYSPACE_EVENTS', 'KEYSPACE_PATTERN', 'PUB_SUB_MAXIMUM_DATA_WAIT', 'PUB_SUB_NOTIFICATION_TIMEOUT', 'REDIS_HOST', 'REDIS_PORT', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_connection_error_handler', '_onetime_connect', '_persistent_connect', '_subscribe_keyspace_notification', '_unavailable_data_handler', 'close', 'connect', 'db_list', 'db_map', 'get', 'get_all', 'get_dbid', 'get_redis_client', 'keys', 'keyspace_notification_channels', 'redis_clients', 'set']
>>> swss.connect(swss.APPL_DB)
>>> swss.keys(swss.APPL_DB)
[b'PORT_TABLE:Ethernet8', b'INTF_TABLE:Ethernet16:10.0.0.8/31', b'LLDP_ENTRY_TABLE:Ethernet4', b'PORT_TABLE:Ethernet76', b'PORT_TABLE_VALUE_QUEUE', b'NEIGH_TABLE:eth0:10.3.147.40', ...]

sonic-py-swsssdk's People

Contributors

abdosi avatar anilkpandey avatar dzhangalibaba avatar jleveque avatar judyjoseph avatar junchao-mellanox avatar keboliu avatar lguohan avatar liorghub avatar liuh-80 avatar liushilongbuaa avatar madhupalu avatar maipbui avatar marian-pritsak avatar mlok-nokia avatar mykolaf avatar oleksandrivantsiv avatar pavel-shirshov avatar prsunny avatar qiluo-msft avatar rajendra-dendukuri avatar renukamanavalan avatar stepanblyschak avatar suvarnameenakshi avatar tacappleman avatar tahmed-dev avatar taoyl-ms avatar vganesan-nokia avatar xumia avatar ysmanman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sonic-py-swsssdk's Issues

Configure SONiC using sonic-py-swsssdk

Hi All,

I have the following function to add an IP interface to SONiC. After calling this function I can see the newly created entry using redis-cli but look like new configuration hasn't been applied to HW.
I couldn't find the new interface with "ifconfig", "show interface summary" and ping commands

What else do we need to do here to notify the syncd service to write changes to ASIC?

Thanks,

def add_ip_inf(self, infName, ipAddr, mask):
db = swsssdk.ConfigDBConnector()
db.connect()
fullAddr = "{}/{}".format(ipAddr, mask)

    # Add IP interface
    try:
        if infName.startswith("Ethernet"):
            resp = db.set_entry("INTERFACE", (infName, fullAddr), {"NULL": "NULL"})
        elif infName.startswith("PortChannel"):
            resp = db.set_entry("PORTCHANNEL_INTERFACE", (infName, fullAddr), {"NULL": "NULL"})
        elif infName.startswith("Vlan"):
            resp = db.set_entry("VLAN_INTERFACE", (infName, fullAddr), {"NULL": "NULL"})
        status = True
    except Exception as e:
        status = False
        resp = str(e)

    return status

`sonic-db-cli PING` doesn't support to only ping dbs in certain redis server instance.

Sonic counts on DBInterface code here to set notify-keyspace-events as AKE for each db. This is done through calling sonic-db-cli in postStart() from database.sh.
It worked well as long as we start redis server from docker-database container for all dbs. Now we start to support sonic voq chassis and have a separate container, docker-database-chassis, to start all chassis dbs in new redis server instance. The chassis container starts before database container, as a result, sonic-db-cli PING wont work for it since not all dbs are available at that time.
The solution is to enhance sonic-db-cli to ping dbs from a given redis server instance, something like this: sonic-db-cl PING -i redis-chassis

Add opcode for notification in configdb.py

Hi all,

I think it's good to add opcode for notification in configdb.py to verify the difference between these:

"AAA": null
"AAA": {}

So I want to contribute a PR with this patch as bellow, but I have no access for push and merge PR? How to deal with this?

commit f547f9c02347e7b42962278005bcba973892a18b
Author: sam <[email protected]>
Date:   Tue Nov 27 11:31:27 2018 +0800

    add opcode in redis notification

diff --git a/src/swsssdk/configdb.py b/src/swsssdk/configdb.py
index e255979..87cad6e 100644
--- a/src/swsssdk/configdb.py
+++ b/src/swsssdk/configdb.py
@@ -76,10 +76,10 @@ class ConfigDBConnector(SonicV2Connector):
         if self.handlers.has_key(table):
             self.handlers.pop(table)

-    def __fire(self, table, key, data):
+    def __fire(self, table, key, data, op_str='add'):
         if self.handlers.has_key(table):
             handler = self.handlers[table]
-            handler(table, key, data)
+            handler(table, key, data, op_str)

     def listen(self):
         """Start listen Redis keyspace events and will trigger corresponding handlers when content of a table changes.
@@ -94,7 +94,11 @@ class ConfigDBConnector(SonicV2Connector):
                     if self.handlers.has_key(table):
                         client = self.redis_clients[self.CONFIG_DB]
                         data = self.__raw_to_typed(client.hgetall(key))
-                        self.__fire(table, row, data)
+                        op = client.keys(key)
+                        op_str = 'add'
+                        if len(op) == 0:
+                            op_str = 'del'
+                        self.__fire(table, row, data, op_str)
                 except ValueError:
                     pass    #Ignore non table-formated redis entries

race condition in __wait_for_db_init() ?

Based on the description in https://redis.io/topics/notifications:
"
Because Redis Pub/Sub is fire and forget currently there is no way to use this feature if your application demands reliable notification of events, that is, if your Pub/Sub client disconnects, and reconnects later, all the events delivered during the time the client was disconnected are lost.
"
It looks to me there is possibility the INIT_INDICATOR is set between client.get() and pubsub.psubscribe(pattern), the notification might get missed and pubsub.listen() will be blocked there, unless client buffers all notification from the moment of client.pubsub()

def __wait_for_db_init(self):
    client = self.redis_clients[self.CONFIG_DB]
    pubsub = client.pubsub()
    initialized = client.get(self.INIT_INDICATOR)
    if not initialized:
        pattern = "__keyspace@{}__:{}".format(self.db_map[self.CONFIG_DB]['db'], self.INIT_INDICATOR)
        pubsub.psubscribe(pattern)
        for item in pubsub.listen():

get_table() function not returning empty table entries

From: [email protected] [mailto:[email protected]] On Behalf Of Haiyang Zheng
Sent: Wednesday, October 25, 2017 7:02 PM
To: sonicproject [email protected]
Subject: Re: [SONiC] configdb.py unable to get tables with NULL Value

Thanks Taoyu for the quick reply.

sonic-cfggen -d -v NTP_SERVER also works for me.
However, I'm trying to using the config db python sdk, which return {} for the NTP_SERVER without my change.

admin@OCPSCH01040HHLF:~$  sonic-cfggen -d -v NTP_SERVER
{'10.34.14.107': {}}
admin@OCPSCH01040HHLF:~$ sudo sw config ntp -i 10.34.14.123 -s 10.34.14.107
{}
admin@OCPSCH01040HHLF:~$ cat /usr/lib/python2.7/dist-packages/switch/switch.py
@click.command()
@click.option('-i','--src-ip', required=True, help="Set the source ip")
@click.option('-s','--server-list', required=True, help="Set the server list with , as delimiter, e.g. Server1,Server2,...")
def ntp(src_ip, server_list):
    """Set the ntp src_ip and server_list"""
    config_db = ConfigDBConnector()
    config_db.connect()
    data = config_db.get_table('NTP_SERVER')
    print data  ==> this is returning {}
    for key in data:
        print "NTP_SERVER key: "+key
        set_config_db_entry('NTP_SERVER', key, None)

suggest support mset in swss-common

lldp-syncd generate LLDP_ENTRY_TABLE and sync to redis one field after one.
this may cause the snmp agent with below syslog from time to time, because snmp agent update may interleaving the hset operations.

i suggest the py-swsssdk support hmset command, and lldp-syncd use this interface to avoid the syslog.

Jul 16 18:16:42.268005 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Error updating remote mgmt addr: b'lldp_rem_time_mark'
Jul 16 19:04:20.220476 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Exception when updating lldpRemTable: b'lldp_rem_time_mark'
Jul 16 21:45:27.373210 dut-testbed-225 WARNING snmp#snmp-subagent message repeated 4 times: [ [sonic_ax_impl] WARNING: Exception when updating lldpRemTable: b'lldp_rem_time_mark']
Jul 16 21:45:27.373210 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Error updating remote mgmt addr: b'lldp_rem_time_mark'
Jul 16 21:49:50.834105 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Exception when updating lldpRemTable: b'lldp_rem_time_mark'
Jul 17 03:55:51.676539 dut-testbed-225 WARNING snmp#snmp-subagent message repeated 11 times: [ [sonic_ax_impl] WARNING: Exception when updating lldpRemTable: b'lldp_rem_time_mark']
Jul 17 03:55:51.676835 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Error updating remote mgmt addr: b'lldp_rem_time_mark'
Jul 17 04:19:30.444283 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Exception when updating lldpRemTable: b'lldp_rem_time_mark'
Jul 17 06:46:16.750943 dut-testbed-225 WARNING snmp#snmp-subagent message repeated 4 times: [ [sonic_ax_impl] WARNING: Exception when updating lldpRemTable: b'lldp_rem_time_mark']
Jul 17 06:46:16.751034 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Error updating remote mgmt addr: b'lldp_rem_time_mark'
Jul 17 06:48:38.603073 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Exception when updating lldpRemTable: b'lldp_rem_time_mark'

TypeError Exception raised when calling ConfigDBConnector().get_config in Python3

root@sonic:~# python3
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.

import swsssdk
db = swsssdk.ConfigDBConnector()
db.connect()
cfg = db.get_config()
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python3.5/dist-packages/swsssdk-2.0.1-py3.5.egg/swsssdk/configdb.py", line 284, in get_config
(table_name, row) = key.split(self.TABLE_NAME_SEPARATOR, 1)
TypeError: a bytes-like object is required, not 'str'

FIX:
Current code:
for key in keys:
try:
(table_name, row) = key.split(self.TABLE_NAME_SEPARATOR, 1)

Proposed code change:
for key in keys:
if PY3K:
key = key.decode('utf-8')
try:
(table_name, row) = key.split(self.TABLE_NAME_SEPARATOR, 1)

Exception seen when trying to connect and database service is not responding

  1. Stop all services including database and verify that none of the containers are running.

root@sonic:/home/admin# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
root@sonic:/home/admin#

2 Now try to initiate a connection with retry option. A py exception is observed.

root@sonic:/home/admin# cat test.py
#!/usr/bin/env python2.7
from swsssdk import SonicV2Connector

state_db = SonicV2Connector(host='17.0.0.1')
state_db.connect(state_db.STATE_DB,True)
root@sonic:/home/admin#

root@sonic:/home/admin# ./test.py
Traceback (most recent call last):
File "./test.py", line 5, in
state_db.connect(state_db.STATE_DB,True)
File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 255, in connect
super(SonicV2Connector, self).connect(db_id, retry_on)
File "/usr/local/lib/python2.7/dist-packages/swsssdk/interface.py", line 169, in connect
self._persistent_connect(db_id)
File "/usr/local/lib/python2.7/dist-packages/swsssdk/interface.py", line 198, in _persistent_connect
self.close(db_id)

File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 258, in close
db_id = self.get_dbid(db_name)
File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 277, in get_dbid
return SonicDBConfig.get_dbid(db_name, self.namespace)
File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 215, in get_dbid
SonicDBConfig.db_name_validation(db_name, namespace)
File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 143, in db_name_validation
raise RuntimeError(msg)
RuntimeError: 6 is not a valid database name in configuration file
root@sonic:/home/admin#

Use redis hset instead of set for CONFIG_DB_INITIALIZED

Similar to portTable ConfigDone, it will be good for py swsssdk to be consistent with existing c++ swss-common library to use hset instead of set for CONFIG_DB_INITIALIZED.

The flag is to be checked by all app modules which need access to configDB. Using redis operation which is not supported by c++ swss-common library causes unnecessary extra work in c++ modules.

SonicV2Connector.connect method keeps on connecting infinitely even with wrong password.

If created SonicV2Connector object with wrong password and try connecting to a database like following:
sonic_db=swsssdk.SonicV2Connector(password="wrong_password")
sonic_db.connect("COUNTERS_DB")

swsssdk infinitely logging following warning messages and application is blocked forever, In case of wrong password a specific exception should be raised and function interface.py->_persistent_connect() should return immediately rather than retrying infinitely.

[2022-09-13 16:37:21,960][WARNING][swsssdk] Connecting to DB '2 COUNTERS_DB' failed, will retry in 10s

related issue - https://github.com/STORDIS/monsoon/issues/7

could sonic-db-cli return JSON string for hgetall ?

Sometimes, sonic-mgmt need check values in redis db by calling "sonic-db-cli $DB HGETALL $KEY". And it would be great if the output of such command can be parsed to a python dictionary easily.

However, sonic-db-cli now return raw string for hgetall comamnd. For example:

admin@r-leopard-01:~$ sonic-db-cli CONFIG_DB HGETALL "TELEMETRY|gnmi"
{'client_auth': 'false', 'log_level': '2', 'port': '50051'}

Python json module cannot parse such string to a dictionary:

{'client_auth': 'false', 'log_level': '2', 'port': '50051'}

I would suggest to change the following code in sonic-db-cli from:

        if resp is None:
            print()
        elif isinstance(resp, list):
            print("\n".join(resp))
        else:
            print(resp)

to

        if resp is None:
            print()
        elif isinstance(resp, list):
            print("\n".join(resp))
        elif isinstance(resp, dict):
            json.dumps(resp)
        else:
            print(resp)

Any thought?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.