def get_all_namespaces(): """ In case of Multi-Asic platform, Each ASIC will have a linux network namespace created. So we loop through the databases in different namespaces and depending on the sub_role decide whether this is a front end ASIC/namespace or a back end one. """ front_ns = [] back_ns = [] num_npus = get_num_npus() SonicDBConfig.load_sonic_global_db_config() if is_multi_npu(): for npu in range(num_npus): namespace = "{}{}".format(NPU_NAME_PREFIX, npu) config_db = ConfigDBConnector(use_unix_socket_path=True, namespace=namespace) config_db.connect() metadata = config_db.get_table('DEVICE_METADATA') if metadata['localhost']['sub_role'] == FRONTEND_ASIC_SUB_ROLE: front_ns.append(namespace) elif metadata['localhost']['sub_role'] == BACKEND_ASIC_SUB_ROLE: back_ns.append(namespace) return {'front_ns': front_ns, 'back_ns': back_ns}
def options_to_kwargs(options): args = {} if options.password: args['password'] = options.password if options.encoding: args['encoding'] = options.encoding # dump only if hasattr(options, 'pretty') and options.pretty: args['pretty'] = True if hasattr(options, 'keys') and options.keys: args['keys'] = options.keys # load only if hasattr(options, 'use_expireat') and options.use_expireat: args['use_expireat'] = True if hasattr(options, 'empty') and options.empty: args['empty'] = True if hasattr(options, 'backend') and options.backend: args['streaming_backend'] = options.backend if hasattr(options, 'dbname') and options.dbname: if options.conntype == 'tcp': args['host'] = SonicDBConfig.get_hostname(options.dbname) args['port'] = SonicDBConfig.get_port(options.dbname) args['db'] = SonicDBConfig.get_dbid(options.dbname) args['unix_socket_path'] = None elif options.conntype == "unix_socket": args['host'] = None args['port'] = None args['db'] = SonicDBConfig.get_dbid(options.dbname) args['unix_socket_path'] = SonicDBConfig.get_socket( options.dbname) else: raise TypeError('redis connection type is tcp or unix_socket') return args
def load_namespace_config(): # To support multi asic testing # SonicDBConfig load_sonic_global_db_config # is invoked to load multiple namespaces clean_up_config() SonicDBConfig.load_sonic_global_db_config(global_db_file_path=os.path.join( os.path.dirname(os.path.abspath(__file__)), 'database_global.json'))
def init_namespace_dbs(): db_conn = [] SonicDBConfig.load_sonic_global_db_config() for namespace in SonicDBConfig.get_ns_list(): db = SonicV2Connector(use_unix_socket_path=True, namespace=namespace) db_conn.append(db) return db_conn
def init_db(): """ Connects to DB :return: db_conn """ SonicDBConfig.load_sonic_global_db_config() # SyncD database connector. THIS MUST BE INITIALIZED ON A PER-THREAD BASIS. # Redis PubSub objects (such as those within swsssdk) are NOT thread-safe. db_conn = SonicV2Connector(**redis_kwargs) return db_conn
def main(): try: parser = argparse.ArgumentParser() parser.add_argument( '-o', dest='operation', metavar='operation (migrate, set_version, get_version)', type=str, required=False, choices=['migrate', 'set_version', 'get_version'], help='operation to perform [default: get_version]', default='get_version') parser.add_argument( '-s', dest='socket', metavar='unix socket', type=str, required=False, help='the unix socket that the desired database listens on', default=None) parser.add_argument( '-n', dest='namespace', metavar='asic namespace', type=str, required=False, help='The asic namespace whose DB instance we need to connect', default=None) args = parser.parse_args() operation = args.operation socket_path = args.socket namespace = args.namespace if args.namespace is not None: SonicDBConfig.load_sonic_global_db_config(namespace=args.namespace) if socket_path: dbmgtr = DBMigrator(namespace, socket=socket_path) else: dbmgtr = DBMigrator(namespace) result = getattr(dbmgtr, operation)() if result: print(str(result)) except Exception as e: log.log_error('Caught exception: ' + str(e)) traceback.print_exc() print(str(e)) parser.print_help() sys.exit(1)
def __init__(self): self.yang_acl = None self.requested_session = None self.mirror_stage = None self.current_table = None self.tables_db_info = {} self.rules_db_info = {} self.rules_info = {} # Load global db config. This call is no-op in single npu platforms SonicDBConfig.load_sonic_global_db_config() self.sessions_db_info = {} self.configdb = ConfigDBConnector() self.configdb.connect() self.statedb = SonicV2Connector(host="127.0.0.1") self.statedb.connect(self.statedb.STATE_DB) # For multi-npu architecture we will have both global and per front asic namespace. # Global namespace will be used for Control plane ACL which are via IPTables. # Per ASIC namespace will be used for Data and Everflow ACL's. # Global Configdb will have all ACL information for both Ctrl and Data/Evereflow ACL's # and will be used as souurce of truth for ACL modification to config DB which will be done to both Global DB and # front asic namespace self.per_npu_configdb = {} # State DB are used for to get mirror Session monitor port. # For multi-npu platforms each asic namespace can have different monitor port # dependinding on which route to session destination ip. So for multi-npu # platforms we get state db for all front asic namespace in addition to self.per_npu_statedb = {} # Getting all front asic namespace and correspding config and state DB connector namespaces = device_info.get_all_namespaces() for front_asic_namespaces in namespaces['front_ns']: self.per_npu_configdb[front_asic_namespaces] = ConfigDBConnector( use_unix_socket_path=True, namespace=front_asic_namespaces) self.per_npu_configdb[front_asic_namespaces].connect() self.per_npu_statedb[front_asic_namespaces] = SonicV2Connector( use_unix_socket_path=True, namespace=front_asic_namespaces) self.per_npu_statedb[front_asic_namespaces].connect( self.per_npu_statedb[front_asic_namespaces].STATE_DB) self.read_tables_info() self.read_rules_info() self.read_sessions_info() self.read_policers_info()
def connect_config_db_for_ns(namespace=DEFAULT_NAMESPACE): """ The function connects to the config DB for a given namespace and returns the handle If no namespace is provided, it will connect to the db in the default namespace. In case of multi ASIC, the default namespace is the database instance running the on the host Returns: handle to the config_db for a namespace """ SonicDBConfig.load_sonic_global_db_config() config_db = ConfigDBConnector(namespace=namespace) config_db.connect() return config_db
def connect_to_all_dbs_for_ns(namespace=DEFAULT_NAMESPACE): """ The function connects to the DBs for a given namespace and returns the handle If no namespace is provided, it will connect to the db in the default namespace. In case of multi ASIC, the default namespace is the database instance running the on the host In case of single ASIC, the namespace has to be DEFAULT_NAMESPACE Returns: handle to all the dbs for a namespaces """ SonicDBConfig.load_sonic_global_db_config() db = SonicV2Connector(namespace=namespace) for db_id in db.get_db_list(): db.connect(db_id) return db
def connect_SonicV2Connector(self, db_name, retry_on=True): ns_list = SonicDBConfig.get_ns_list() # In case of multiple namespaces, namespace string passed to # SonicV2Connector will specify the namespace or can be empty. # Empty namespace represents global or host namespace. if len(ns_list) > 1 and self.namespace == "": self.dbintf.redis_kwargs['namespace'] = "global_db" else: self.dbintf.redis_kwargs['namespace'] = self.namespace # Mock DB filename for unit-test self.dbintf.redis_kwargs['db_name'] = db_name _old_connect_SonicV2Connector(self, db_name, retry_on)
def load_database_config(): # Load local database_config.json for single namespace test scenario clean_up_config() SonicDBConfig.load_sonic_db_config(sonic_db_file_path=os.path.join( os.path.dirname(os.path.abspath(__file__)), 'database_config.json'))
def mock_get_num_asics(): ns_list = SonicDBConfig.get_ns_list() if len(ns_list) > 1: return(len(ns_list) - 1) else: return 1