def __init__(self, args=None): self._args = args self._fabric_rt_inst_obj = None # Initialize discovery client self._disc = None if self._args.disc_server_ip and self._args.disc_server_port: self._disc = client.DiscoveryClient( self._args.disc_server_ip, self._args.disc_server_port, ModuleNames[Module.SCHEMA_TRANSFORMER]) # Initialize logger self.logger = SchemaTransformerLogger(self._disc, args) # Initialize amqp self._vnc_amqp = STAmqpHandle(self.logger, self._REACTION_MAP, self._args) self._vnc_amqp.establish() try: # Initialize cassandra self._object_db = SchemaTransformerDB(self, _zookeeper_client) DBBaseST.init(self, self.logger, self._object_db) DBBaseST._sandesh = self.logger._sandesh DBBaseST._vnc_lib = _vnc_lib ServiceChain.init() self.reinit() self._vnc_amqp._db_resync_done.set() except Exception as e: # If any of the above tasks like CassandraDB read fails, cleanup # the RMQ constructs created earlier and then give up. self._vnc_amqp.close() raise e
def __init__(self, st_logger=None, args=None): self._args = args self._fabric_rt_inst_obj = None self.timer_obj = self.STtimer(self._args.zk_timeout) if st_logger is not None: self.logger = st_logger else: # Initialize logger self.logger = SchemaTransformerLogger(args) # Initialize amqp self._vnc_amqp = STAmqpHandle(self.logger, self.REACTION_MAP, self._args, timer_obj=self.timer_obj) self._vnc_amqp.establish() SchemaTransformer._schema_transformer = self try: # Initialize cassandra self._object_db = SchemaTransformerDB(self, _zookeeper_client) DBBaseST.init(self, self.logger, self._object_db) DBBaseST._sandesh = self.logger._sandesh DBBaseST._vnc_lib = _vnc_lib ServiceChain.init() self.reinit() self._vnc_amqp._db_resync_done.set() except Exception as e: self._vnc_amqp._db_resync_done.set() # If any of the above tasks like CassandraDB read fails, cleanup # the RMQ constructs created earlier and then give up. SchemaTransformer.destroy_instance() SchemaTransformer._schema_transformer = None raise
def main(args_str=None): global _zookeeper_client if not args_str: args_str = ' '.join(sys.argv[1:]) args = parse_args(args_str) args._args_list = args_str if args.cluster_id: client_pfx = args.cluster_id + '-' zk_path_pfx = args.cluster_id + '/' else: client_pfx = '' zk_path_pfx = '' # randomize collector list args.random_collectors = args.collectors if args.collectors: args.random_collectors = random.sample(args.collectors, len(args.collectors)) # Initialize logger without introspect thread st_logger = SchemaTransformerLogger(args, http_server_port=-1) # Initialize AMQP handler then close it to be sure remain queue of a # precedent run is cleaned vnc_amqp = STAmqpHandle(st_logger, SchemaTransformer.REACTION_MAP, args) vnc_amqp.establish() vnc_amqp.close() st_logger.debug("Removed remained AMQP queue") # Waiting to be elected as master node if 'host_ip' in args: host_ip = args.host_ip else: host_ip = socket.gethostbyname(socket.getfqdn()) _zookeeper_client = ZookeeperClient(client_pfx+"schema", args.zk_server_ip, host_ip, zk_timeout=args.zk_timeout) st_logger.notice("Waiting to be elected as master...") _zookeeper_client.master_election(zk_path_pfx + "/schema-transformer", os.getpid(), run_schema_transformer, st_logger, args)
class SchemaTransformer(object): _REACTION_MAP = { 'routing_instance': { 'self': ['virtual_network'], }, 'virtual_machine_interface': { 'self': ['virtual_machine', 'port_tuple', 'virtual_network', 'bgp_as_a_service'], 'virtual_network': ['virtual_machine', 'port_tuple', 'bgp_as_a_service'], 'logical_router': ['virtual_network'], 'instance_ip': ['virtual_machine', 'port_tuple', 'bgp_as_a_service', 'virtual_network'], 'floating_ip': ['virtual_machine', 'port_tuple'], 'alias_ip': ['virtual_machine', 'port_tuple'], 'virtual_machine': ['virtual_network'], 'port_tuple': ['virtual_network'], 'bgp_as_a_service': [], }, 'virtual_network': { 'self': ['network_policy', 'route_table'], 'routing_instance': ['network_policy'], 'network_policy': [], 'virtual_machine_interface': [], 'route_table': [], }, 'virtual_machine': { 'self': ['service_instance'], 'virtual_machine_interface': ['service_instance'], 'service_instance': ['virtual_machine_interface'] }, 'port_tuple': { 'self': ['service_instance'], 'virtual_machine_interface': ['service_instance'], 'service_instance': ['virtual_machine_interface'] }, 'service_instance': { 'self': ['network_policy', 'virtual_machine', 'port_tuple'], 'route_table': ['network_policy', 'virtual_machine', 'port_tuple'], 'routing_policy': ['network_policy'], 'route_aggregate': ['network_policy'], 'virtual_machine': ['network_policy'], 'port_tuple': ['network_policy'], 'network_policy': ['virtual_machine', 'port_tuple'] }, 'network_policy': { 'self': ['virtual_network', 'network_policy', 'service_instance'], 'service_instance': ['virtual_network'], 'network_policy': ['virtual_network'], 'virtual_network': ['virtual_network', 'network_policy', 'service_instance'] }, 'security_group': { 'self': ['security_group'], 'security_group': [], }, 'route_table': { 'self': ['virtual_network', 'service_instance', 'logical_router'], 'virtual_network': ['service_instance'], 'logical_router': ['service_instance'], }, 'logical_router': { 'self': ['route_table'], 'virtual_machine_interface': [], 'route_table': [], }, 'floating_ip': { 'self': ['virtual_machine_interface'], }, 'alias_ip': { 'self': ['virtual_machine_interface'], }, 'instance_ip': { 'self': ['virtual_machine_interface'], }, 'bgp_as_a_service': { 'self': ['bgp_router'], 'virtual_machine_interface': ['bgp_router'] }, 'bgp_router': { 'self': [], 'bgp_as_a_service': [], }, 'global_system_config': { 'self': [], }, 'routing_policy': { 'self': ['service_instance'], }, 'route_aggregate': { 'self': ['service_instance'], } } def __init__(self, args=None): self._args = args self._fabric_rt_inst_obj = None # Initialize discovery client self._disc = None if self._args.disc_server_ip and self._args.disc_server_port: self._disc = client.DiscoveryClient( self._args.disc_server_ip, self._args.disc_server_port, ModuleNames[Module.SCHEMA_TRANSFORMER]) # Initialize logger self.logger = SchemaTransformerLogger(self._disc, args) # Initialize amqp self._vnc_amqp = STAmqpHandle(self.logger, self._REACTION_MAP, self._args) self._vnc_amqp.establish() try: # Initialize cassandra self._object_db = SchemaTransformerDB(self, _zookeeper_client) DBBaseST.init(self, self.logger, self._object_db) DBBaseST._sandesh = self.logger._sandesh DBBaseST._vnc_lib = _vnc_lib ServiceChain.init() self.reinit() self._vnc_amqp._db_resync_done.set() except Exception as e: # If any of the above tasks like CassandraDB read fails, cleanup # the RMQ constructs created earlier and then give up. self._vnc_amqp.close() raise e # end __init__ # Clean up stale objects def reinit(self): GlobalSystemConfigST.reinit() BgpRouterST.reinit() LogicalRouterST.reinit() vn_list = list(VirtualNetworkST.list_vnc_obj()) vn_id_list = set([vn.uuid for vn in vn_list]) ri_dict = {} service_ri_dict = {} ri_deleted = {} for ri in DBBaseST.list_vnc_obj('routing_instance'): delete = False if ri.parent_uuid not in vn_id_list: delete = True ri_deleted.setdefault(ri.parent_uuid, []).append(ri.uuid) else: # if the RI was for a service chain and service chain no # longer exists, delete the RI sc_id = RoutingInstanceST._get_service_id_from_ri( ri.get_fq_name_str()) if sc_id: if sc_id not in ServiceChain: delete = True else: service_ri_dict[ri.get_fq_name_str()] = ri else: ri_dict[ri.get_fq_name_str()] = ri if delete: try: ri_obj = RoutingInstanceST(ri.get_fq_name_str(), ri) ri_obj.delete_obj() except NoIdError: pass except Exception as e: self.logger.error( "Error while deleting routing instance %s: %s"%( ri.get_fq_name_str(), str(e))) # end for ri sg_list = list(SecurityGroupST.list_vnc_obj()) sg_id_list = [sg.uuid for sg in sg_list] sg_acl_dict = {} vn_acl_dict = {} for acl in DBBaseST.list_vnc_obj('access_control_list'): delete = False if acl.parent_type == 'virtual-network': if acl.parent_uuid in vn_id_list: vn_acl_dict[acl.uuid] = acl else: delete = True elif acl.parent_type == 'security-group': if acl.parent_uuid in sg_id_list: sg_acl_dict[acl.uuid] = acl else: delete = True else: delete = True if delete: try: _vnc_lib.access_control_list_delete(id=acl.uuid) except NoIdError: pass except Exception as e: self.logger.error( "Error while deleting acl %s: %s"%( acl.uuid, str(e))) # end for acl gevent.sleep(0.001) for sg in sg_list: SecurityGroupST.locate(sg.get_fq_name_str(), sg, sg_acl_dict) # update sg rules after all SG objects are initialized to avoid # rewriting of ACLs multiple times for sg in SecurityGroupST.values(): sg.update_policy_entries() gevent.sleep(0.001) RouteTargetST.reinit() for vn in vn_list: if vn.uuid in ri_deleted: vn_ri_list = vn.get_routing_instances() or [] new_vn_ri_list = [vn_ri for vn_ri in vn_ri_list if vn_ri['uuid'] not in ri_deleted[vn.uuid]] vn.routing_instances = new_vn_ri_list VirtualNetworkST.locate(vn.get_fq_name_str(), vn, vn_acl_dict) for ri_name, ri_obj in ri_dict.items(): RoutingInstanceST.locate(ri_name, ri_obj) # Initialize service instance RI's after Primary RI's for si_ri_name, si_ri_obj in service_ri_dict.items(): RoutingInstanceST.locate(si_ri_name, si_ri_obj) NetworkPolicyST.reinit() gevent.sleep(0.001) VirtualMachineInterfaceST.reinit() gevent.sleep(0.001) InstanceIpST.reinit() gevent.sleep(0.001) FloatingIpST.reinit() AliasIpST.reinit() gevent.sleep(0.001) for si in ServiceInstanceST.list_vnc_obj(): si_st = ServiceInstanceST.locate(si.get_fq_name_str(), si) if si_st is None: continue for ref in si.get_virtual_machine_back_refs() or []: vm_name = ':'.join(ref['to']) vm = VirtualMachineST.locate(vm_name) si_st.virtual_machines.add(vm_name) props = si.get_service_instance_properties() if not props.auto_policy: continue si_st.add_properties(props) gevent.sleep(0.001) RoutingPolicyST.reinit() gevent.sleep(0.001) RouteAggregateST.reinit() gevent.sleep(0.001) PortTupleST.reinit() BgpAsAServiceST.reinit() RouteTableST.reinit() # evaluate virtual network objects first because other objects, # e.g. vmi, depend on it. for vn_obj in VirtualNetworkST.values(): vn_obj.evaluate() for cls in DBBaseST.get_obj_type_map().values(): if cls is VirtualNetworkST: continue for obj in cls.values(): obj.evaluate() self.process_stale_objects() # end reinit def cleanup(self): # TODO cleanup sandesh context pass # end cleanup def process_stale_objects(self): for sc in ServiceChain.values(): if sc.created_stale: sc.destroy() if sc.present_stale: sc.delete() for rinst in RoutingInstanceST.values(): if rinst.stale_route_targets: rinst.update_route_target_list( rt_del=rinst.stale_route_targets) # end process_stale_objects def reset(self): for cls in DBBaseST.get_obj_type_map().values(): cls.reset() self._vnc_amqp.close() # end reset def sighup_handler(self): if self._conf_file: config = ConfigParser.SafeConfigParser() config.read(self._conf_file) if 'DEFAULTS' in config.sections(): try: collectors = config.get('DEFAULTS', 'collectors') if type(collectors) is str: collectors = collectors.split() new_chksum = hashlib.md5("".join(collectors)).hexdigest() if new_chksum != self._chksum: self._chksum = new_chksum config.random_collectors = random.sample(collectors, len(collectors)) self.logger.sandesh_reconfig_collectors(config) except ConfigParser.NoOptionError as e: pass
class SchemaTransformer(object): REACTION_MAP = { 'routing_instance': { 'self': ['virtual_network'], }, 'virtual_machine_interface': { 'self': [ 'virtual_machine', 'port_tuple', 'virtual_network', 'bgp_as_a_service' ], 'virtual_network': ['virtual_machine', 'port_tuple', 'bgp_as_a_service'], 'logical_router': ['virtual_network'], 'instance_ip': [ 'virtual_machine', 'port_tuple', 'bgp_as_a_service', 'virtual_network' ], 'floating_ip': ['virtual_machine', 'port_tuple'], 'alias_ip': ['virtual_machine', 'port_tuple'], 'virtual_machine': ['virtual_network'], 'port_tuple': ['virtual_network'], 'bgp_as_a_service': [], }, 'virtual_network': { 'self': ['network_policy', 'route_table'], 'routing_instance': ['network_policy'], 'network_policy': [], 'virtual_machine_interface': [], 'route_table': [], 'bgpvpn': [], }, 'virtual_machine': { 'self': ['service_instance'], 'virtual_machine_interface': ['service_instance'], 'service_instance': ['virtual_machine_interface'] }, 'port_tuple': { 'self': ['service_instance'], 'virtual_machine_interface': ['service_instance'], 'service_instance': ['virtual_machine_interface'] }, 'service_instance': { 'self': ['network_policy', 'virtual_machine', 'port_tuple'], 'route_table': ['network_policy', 'virtual_machine', 'port_tuple'], 'routing_policy': ['network_policy'], 'route_aggregate': ['network_policy'], 'virtual_machine': ['network_policy'], 'port_tuple': ['network_policy'], 'network_policy': ['virtual_machine', 'port_tuple'] }, 'network_policy': { 'self': [ 'security_logging_object', 'virtual_network', 'network_policy', 'service_instance' ], 'service_instance': ['virtual_network'], 'network_policy': ['virtual_network'], 'virtual_network': ['virtual_network', 'network_policy', 'service_instance'] }, 'security_group': { 'self': ['security_group', 'security_logging_object'], 'security_group': [], }, 'security_logging_object': { 'self': [], 'network_policy': [], 'security_group': [], }, 'route_table': { 'self': ['virtual_network', 'service_instance', 'logical_router'], 'virtual_network': ['service_instance'], 'logical_router': ['service_instance'], }, 'logical_router': { 'self': ['route_table'], 'virtual_machine_interface': [], 'route_table': [], 'bgpvpn': [], }, 'floating_ip': { 'self': ['virtual_machine_interface'], }, 'alias_ip': { 'self': ['virtual_machine_interface'], }, 'instance_ip': { 'self': ['virtual_machine_interface'], }, 'bgp_as_a_service': { 'self': ['bgp_router'], 'virtual_machine_interface': ['bgp_router'] }, 'bgp_router': { 'self': [], 'bgp_as_a_service': [], }, 'global_system_config': { 'self': [], }, 'routing_policy': { 'self': ['service_instance'], }, 'route_aggregate': { 'self': ['service_instance'], }, 'bgpvpn': { 'self': ['virtual_network', 'logical_router'], 'virtual_network': [], 'logical_router': [], }, } _schema_transformer = None def __init__(self, st_logger=None, args=None): self._args = args self._fabric_rt_inst_obj = None if st_logger is not None: self.logger = st_logger else: # Initialize logger self.logger = SchemaTransformerLogger(args) # Initialize amqp self._vnc_amqp = STAmqpHandle(self.logger, self.REACTION_MAP, self._args) self._vnc_amqp.establish() SchemaTransformer._schema_transformer = self try: # Initialize cassandra self._object_db = SchemaTransformerDB(self, _zookeeper_client) DBBaseST.init(self, self.logger, self._object_db) DBBaseST._sandesh = self.logger._sandesh DBBaseST._vnc_lib = _vnc_lib ServiceChain.init() self.reinit() self._vnc_amqp._db_resync_done.set() except Exception as e: # If any of the above tasks like CassandraDB read fails, cleanup # the RMQ constructs created earlier and then give up. SchemaTransformer.destroy_instance() SchemaTransformer._schema_transformer = None raise # end __init__ # Clean up stale objects def reinit(self): GlobalSystemConfigST.reinit() BgpRouterST.reinit() BgpvpnST.reinit() LogicalRouterST.reinit() gevent.sleep(0.001) for si in ServiceInstanceST.list_vnc_obj(): try: si_st = ServiceInstanceST.locate(si.get_fq_name_str(), si) if si_st is None: continue for ref in si.get_virtual_machine_back_refs() or []: vm_name = ':'.join(ref['to']) vm = VirtualMachineST.locate(vm_name) si_st.virtual_machines.add(vm_name) props = si.get_service_instance_properties() if not props.auto_policy: continue si_st.add_properties(props) except Exception as e: self.logger.error("Error in reinit service instance %s: %s" % (si.get_fq_name_str(), str(e))) vn_list = list(VirtualNetworkST.list_vnc_obj()) vn_id_list = set([vn.uuid for vn in vn_list]) ri_dict = {} service_ri_dict = {} ri_deleted = {} for ri in DBBaseST.list_vnc_obj('routing_instance'): delete = False if ri.parent_uuid not in vn_id_list: delete = True ri_deleted.setdefault(ri.parent_uuid, []).append(ri.uuid) else: try: # if the RI was for a service chain and service chain no # longer exists, delete the RI sc_id = RoutingInstanceST._get_service_id_from_ri( ri.get_fq_name_str()) if sc_id: if sc_id not in ServiceChain: delete = True else: service_ri_dict[ri.get_fq_name_str()] = ri else: ri_dict[ri.get_fq_name_str()] = ri except Exception as e: self.logger.error( "Error while reinitializing routing instance %s: %s" % (ri.get_fq_name_str(), str(e))) if delete: try: ri_obj = RoutingInstanceST(ri.get_fq_name_str(), ri) ri_obj.delete_obj() except NoIdError: pass except Exception as e: self.logger.error( "Error while deleting routing instance %s: %s" % (ri.get_fq_name_str(), str(e))) # end for ri sg_list = list(SecurityGroupST.list_vnc_obj()) sg_id_list = [sg.uuid for sg in sg_list] sg_acl_dict = {} vn_acl_dict = {} for acl in DBBaseST.list_vnc_obj('access_control_list', fields=['access_control_list_hash']): delete = False if acl.parent_type == 'virtual-network': if acl.parent_uuid in vn_id_list: vn_acl_dict[acl.uuid] = acl else: delete = True elif acl.parent_type == 'security-group': if acl.parent_uuid in sg_id_list: sg_acl_dict[acl.uuid] = acl else: delete = True else: delete = True if delete: try: _vnc_lib.access_control_list_delete(id=acl.uuid) except NoIdError: pass except Exception as e: self.logger.error("Error while deleting acl %s: %s" % (acl.uuid, str(e))) # end for acl gevent.sleep(0.001) for sg in sg_list: try: SecurityGroupST.locate(sg.get_fq_name_str(), sg, sg_acl_dict) except Exception as e: self.logger.error("Error in reinit security-group %s: %s" % (sg.get_fq_name_str(), str(e))) # update sg rules after all SG objects are initialized to avoid # rewriting of ACLs multiple times for sg in SecurityGroupST.values(): try: sg.update_policy_entries() except Exception as e: self.logger.error("Error in updating SG policies %s: %s" % (sg.name, str(e))) gevent.sleep(0.001) RouteTargetST.reinit() for vn in vn_list: if vn.uuid in ri_deleted: vn_ri_list = vn.get_routing_instances() or [] new_vn_ri_list = [ vn_ri for vn_ri in vn_ri_list if vn_ri['uuid'] not in ri_deleted[vn.uuid] ] vn.routing_instances = new_vn_ri_list try: VirtualNetworkST.locate(vn.get_fq_name_str(), vn, vn_acl_dict) except Exception as e: self.logger.error("Error in reinit virtual network %s: %s" % (vn.get_fq_name_str(), str(e))) for ri_name, ri_obj in ri_dict.items(): try: RoutingInstanceST.locate(ri_name, ri_obj) except Exception as e: self.logger.error("Error in reinit routing instance %s: %s" % (ri_name, str(e))) # Initialize service instance RI's after Primary RI's for si_ri_name, si_ri_obj in service_ri_dict.items(): try: RoutingInstanceST.locate(si_ri_name, si_ri_obj) except Exception as e: self.logger.error("Error in reinit routing instance %s: %s" % (si_ri_name, str(e))) NetworkPolicyST.reinit() gevent.sleep(0.001) VirtualMachineInterfaceST.reinit() gevent.sleep(0.001) InstanceIpST.reinit() gevent.sleep(0.001) FloatingIpST.reinit() AliasIpST.reinit() gevent.sleep(0.001) RoutingPolicyST.reinit() gevent.sleep(0.001) RouteAggregateST.reinit() gevent.sleep(0.001) PortTupleST.reinit() BgpAsAServiceST.reinit() RouteTableST.reinit() # evaluate virtual network objects first because other objects, # e.g. vmi, depend on it. for vn_obj in VirtualNetworkST.values(): try: vn_obj.evaluate() except Exception as e: self.logger.error( "Error in reinit evaluate virtual network %s: %s" % (vn_obj.name, str(e))) for cls in DBBaseST.get_obj_type_map().values(): if cls is VirtualNetworkST: continue for obj in cls.values(): try: obj.evaluate() except Exception as e: self.logger.error("Error in reinit evaluate %s %s: %s" % (cls.obj_type, obj.name, str(e))) self.process_stale_objects() # end reinit def cleanup(self): # TODO cleanup sandesh context pass # end cleanup def process_stale_objects(self): for sc in ServiceChain.values(): if sc.created_stale: sc.destroy() if sc.present_stale: sc.delete() for rinst in RoutingInstanceST.values(): if rinst.stale_route_targets: rinst.update_route_target_list( rt_del=rinst.stale_route_targets) # end process_stale_objects @classmethod def get_instance(cls): return cls._schema_transformer @classmethod def destroy_instance(cls): inst = cls.get_instance() inst._vnc_amqp.close() for obj_cls in DBBaseST.get_obj_type_map().values(): obj_cls.reset() DBBase.clear() inst._object_db = None cls._schema_transformer = None def sighup_handler(self): if self._conf_file: config = ConfigParser.SafeConfigParser() config.read(self._conf_file) if 'DEFAULTS' in config.sections(): try: collectors = config.get('DEFAULTS', 'collectors') if type(collectors) is str: collectors = collectors.split() new_chksum = hashlib.md5( "".join(collectors)).hexdigest() if new_chksum != self._chksum: self._chksum = new_chksum config.random_collectors = random.sample( collectors, len(collectors)) # Reconnect to achieve load-balance irrespective of list self.logger.sandesh_reconfig_collectors(config) except ConfigParser.NoOptionError as e: pass
class SchemaTransformer(object): _REACTION_MAP = { 'routing_instance': { 'self': ['virtual_network'], }, 'virtual_machine_interface': { 'self': [ 'virtual_machine', 'port_tuple', 'virtual_network', 'bgp_as_a_service' ], 'virtual_network': ['virtual_machine', 'port_tuple', 'bgp_as_a_service'], 'logical_router': ['virtual_network'], 'instance_ip': [ 'virtual_machine', 'port_tuple', 'bgp_as_a_service', 'virtual_network' ], 'floating_ip': ['virtual_machine', 'port_tuple'], 'alias_ip': ['virtual_machine', 'port_tuple'], 'virtual_machine': ['virtual_network'], 'port_tuple': ['virtual_network'], 'bgp_as_a_service': [], }, 'virtual_network': { 'self': ['network_policy', 'route_table'], 'routing_instance': ['network_policy'], 'network_policy': [], 'virtual_machine_interface': [], 'route_table': [], }, 'virtual_machine': { 'self': ['service_instance'], 'virtual_machine_interface': ['service_instance'], 'service_instance': ['virtual_machine_interface'] }, 'port_tuple': { 'self': ['service_instance'], 'virtual_machine_interface': ['service_instance'], 'service_instance': ['virtual_machine_interface'] }, 'service_instance': { 'self': ['network_policy', 'virtual_machine', 'port_tuple'], 'route_table': ['network_policy', 'virtual_machine', 'port_tuple'], 'routing_policy': ['network_policy'], 'route_aggregate': ['network_policy'], 'virtual_machine': ['network_policy'], 'port_tuple': ['network_policy'], 'network_policy': ['virtual_machine', 'port_tuple'] }, 'network_policy': { 'self': ['virtual_network', 'network_policy', 'service_instance'], 'service_instance': ['virtual_network'], 'network_policy': ['virtual_network'], 'virtual_network': ['virtual_network', 'network_policy', 'service_instance'] }, 'security_group': { 'self': ['security_group'], 'security_group': [], }, 'route_table': { 'self': ['virtual_network', 'service_instance', 'logical_router'], 'virtual_network': ['service_instance'], 'logical_router': ['service_instance'], }, 'logical_router': { 'self': ['route_table'], 'virtual_machine_interface': [], 'route_table': [], }, 'floating_ip': { 'self': ['virtual_machine_interface'], }, 'alias_ip': { 'self': ['virtual_machine_interface'], }, 'instance_ip': { 'self': ['virtual_machine_interface'], }, 'bgp_as_a_service': { 'self': ['bgp_router'], 'virtual_machine_interface': ['bgp_router'] }, 'bgp_router': { 'self': [], 'bgp_as_a_service': [], }, 'global_system_config': { 'self': [], }, 'routing_policy': { 'self': ['service_instance'], }, 'route_aggregate': { 'self': ['service_instance'], } } def __init__(self, args=None): self._args = args self._fabric_rt_inst_obj = None # Initialize discovery client self._disc = None if self._args.disc_server_ip and self._args.disc_server_port: self._disc = client.DiscoveryClient( self._args.disc_server_ip, self._args.disc_server_port, ModuleNames[Module.SCHEMA_TRANSFORMER]) # Initialize logger self.logger = SchemaTransformerLogger(self._disc, args) # Initialize amqp self._vnc_amqp = STAmqpHandle(self.logger, self._REACTION_MAP, self._args) self._vnc_amqp.establish() try: # Initialize cassandra self._cassandra = SchemaTransformerDB(self, _zookeeper_client) DBBaseST.init(self, self.logger, self._cassandra) DBBaseST._sandesh = self.logger._sandesh DBBaseST._vnc_lib = _vnc_lib ServiceChain.init() self.reinit() self._vnc_amqp._db_resync_done.set() except Exception as e: # If any of the above tasks like CassandraDB read fails, cleanup # the RMQ constructs created earlier and then give up. self._vnc_amqp.close() raise e # end __init__ # Clean up stale objects def reinit(self): GlobalSystemConfigST.reinit() BgpRouterST.reinit() LogicalRouterST.reinit() vn_list = list(VirtualNetworkST.list_vnc_obj()) vn_id_list = set([vn.uuid for vn in vn_list]) ri_dict = {} service_ri_dict = {} ri_deleted = {} for ri in DBBaseST.list_vnc_obj('routing_instance'): delete = False if ri.parent_uuid not in vn_id_list: delete = True ri_deleted.setdefault(ri.parent_uuid, []).append(ri.uuid) else: # if the RI was for a service chain and service chain no # longer exists, delete the RI sc_id = RoutingInstanceST._get_service_id_from_ri( ri.get_fq_name_str()) if sc_id: if sc_id not in ServiceChain: delete = True else: service_ri_dict[ri.get_fq_name_str()] = ri else: ri_dict[ri.get_fq_name_str()] = ri if delete: try: ri_obj = RoutingInstanceST(ri.get_fq_name_str(), ri) ri_obj.delete_obj() except NoIdError: pass except Exception as e: self.logger.error( "Error while deleting routing instance %s: %s", ri.get_fq_name_str(), str(e)) # end for ri sg_list = list(SecurityGroupST.list_vnc_obj()) sg_id_list = [sg.uuid for sg in sg_list] sg_acl_dict = {} vn_acl_dict = {} for acl in DBBaseST.list_vnc_obj('access_control_list'): delete = False if acl.parent_type == 'virtual-network': if acl.parent_uuid in vn_id_list: vn_acl_dict[acl.uuid] = acl else: delete = True elif acl.parent_type == 'security-group': if acl.parent_uuid in sg_id_list: sg_acl_dict[acl.uuid] = acl else: delete = True else: delete = True if delete: try: _vnc_lib.access_control_list_delete(id=acl.uuid) except NoIdError: pass except Exception as e: self.logger.error("Error while deleting acl %s: %s", acl.uuid, str(e)) # end for acl gevent.sleep(0.001) for sg in sg_list: SecurityGroupST.locate(sg.get_fq_name_str(), sg, sg_acl_dict) # update sg rules after all SG objects are initialized to avoid # rewriting of ACLs multiple times for sg in SecurityGroupST.values(): sg.update_policy_entries() gevent.sleep(0.001) RouteTargetST.reinit() for vn in vn_list: if vn.uuid in ri_deleted: vn_ri_list = vn.get_routing_instances() or [] new_vn_ri_list = [ vn_ri for vn_ri in vn_ri_list if vn_ri['uuid'] not in ri_deleted[vn.uuid] ] vn.routing_instances = new_vn_ri_list VirtualNetworkST.locate(vn.get_fq_name_str(), vn, vn_acl_dict) for ri_name, ri_obj in ri_dict.items(): RoutingInstanceST.locate(ri_name, ri_obj) # Initialize service instance RI's after Primary RI's for si_ri_name, si_ri_obj in service_ri_dict.items(): RoutingInstanceST.locate(si_ri_name, si_ri_obj) NetworkPolicyST.reinit() gevent.sleep(0.001) VirtualMachineInterfaceST.reinit() gevent.sleep(0.001) InstanceIpST.reinit() gevent.sleep(0.001) FloatingIpST.reinit() AliasIpST.reinit() gevent.sleep(0.001) for si in ServiceInstanceST.list_vnc_obj(): si_st = ServiceInstanceST.locate(si.get_fq_name_str(), si) if si_st is None: continue for ref in si.get_virtual_machine_back_refs() or []: vm_name = ':'.join(ref['to']) vm = VirtualMachineST.locate(vm_name) si_st.virtual_machines.add(vm_name) props = si.get_service_instance_properties() if not props.auto_policy: continue si_st.add_properties(props) gevent.sleep(0.001) RoutingPolicyST.reinit() gevent.sleep(0.001) RouteAggregateST.reinit() gevent.sleep(0.001) PortTupleST.reinit() BgpAsAServiceST.reinit() RouteTableST.reinit() # evaluate virtual network objects first because other objects, # e.g. vmi, depend on it. for vn_obj in VirtualNetworkST.values(): vn_obj.evaluate() for cls in DBBaseST.get_obj_type_map().values(): if cls is VirtualNetworkST: continue for obj in cls.values(): obj.evaluate() self.process_stale_objects() # end reinit def cleanup(self): # TODO cleanup sandesh context pass # end cleanup def process_stale_objects(self): for sc in ServiceChain.values(): if sc.created_stale: sc.destroy() if sc.present_stale: sc.delete() for rinst in RoutingInstanceST.values(): if rinst.stale_route_targets: rinst.update_route_target_list( rt_del=rinst.stale_route_targets) # end process_stale_objects def reset(self): for cls in DBBaseST.get_obj_type_map().values(): cls.reset() self._vnc_amqp.close()