Exemplo n.º 1
0
 def establish(self):
     q_name = '.'.join([self.q_name_prefix, socket.gethostname()])
     self._vnc_kombu = VncKombuClient(
             self._args.rabbit_server, self._args.rabbit_port,
             self._args.rabbit_user, self._args.rabbit_password,
             self._args.rabbit_vhost, self._args.rabbit_ha_mode,
             q_name, self._vnc_subscribe_callback,
             self.logger.log, rabbit_use_ssl=self._args.rabbit_use_ssl,
             kombu_ssl_version=self._args.kombu_ssl_version,
             kombu_ssl_keyfile=self._args.kombu_ssl_keyfile,
             kombu_ssl_certfile=self._args.kombu_ssl_certfile,
             kombu_ssl_ca_certs=self._args.kombu_ssl_ca_certs)
Exemplo n.º 2
0
 def establish(self):
     q_name = '.'.join([self.q_name_prefix, socket.gethostname()])
     self._vnc_kombu = VncKombuClient(
             self._rabbitmq_cfg['servers'], self._rabbitmq_cfg['port'],
             self._rabbitmq_cfg['user'], self._rabbitmq_cfg['password'],
             self._rabbitmq_cfg['vhost'], self._rabbitmq_cfg['ha_mode'],
             q_name, self._vnc_subscribe_callback,
             self.logger.log, rabbit_use_ssl=self._rabbitmq_cfg['use_ssl'],
             kombu_ssl_version=self._rabbitmq_cfg['ssl_version'],
             kombu_ssl_keyfile=self._rabbitmq_cfg['ssl_keyfile'],
             kombu_ssl_certfile=self._rabbitmq_cfg['ssl_certfile'],
             kombu_ssl_ca_certs=self._rabbitmq_cfg['ssl_ca_certs'])
class DeviceManager(object):
    _REACTION_MAP = {
        'physical_router': {
            'self': ['bgp_router', 'physical_interface', 'logical_interface'],
            'bgp_router': [],
            'physical_interface': [],
            'logical_interface': [],
            'virtual_network': [],
            'global_system_config': [],
        },
        'global_system_config': {
            'self': ['physical_router'],
            'physical_router': [],
        },
        'bgp_router': {
            'self': ['bgp_router', 'physical_router'],
            'bgp_router': ['physical_router'],
            'physical_router': [],
        },
        'physical_interface': {
            'self': ['physical_router', 'logical_interface'],
            'physical_router': ['logical_interface'],
            'logical_interface': ['physical_router'],
        },
        'logical_interface': {
            'self': ['physical_router', 'physical_interface',
                     'virtual_machine_interface'],
            'physical_interface': ['virtual_machine_interface'],
            'virtual_machine_interface': ['physical_router',
                                          'physical_interface'],
            'physical_router': ['virtual_machine_interface']
        },
        'virtual_machine_interface': {
            'self': ['logical_interface', 'virtual_network', 'floating_ip', 'instance_ip'],
            'logical_interface': ['virtual_network'],
            'virtual_network': ['logical_interface'],
            'floating_ip': ['virtual_network'],
            'instance_ip': ['virtual_network'],
        },
        'virtual_network': {
            'self': ['physical_router', 'virtual_machine_interface'],
            'routing_instance': ['physical_router',
                                 'virtual_machine_interface'],
            'physical_router': [],
            'virtual_machine_interface': ['physical_router'],
        },
        'routing_instance': {
            'self': ['routing_instance', 'virtual_network'],
            'routing_instance': ['virtual_network'],
            'virtual_network': []
        },
        'floating_ip': {
            'self': ['virtual_machine_interface'],
            'virtual_machine_interface': [],
        },
        'instance_ip': {
            'self': ['virtual_machine_interface'],
            'virtual_machine_interface': [],
        },
    }

    def __init__(self, args=None):
        self._args = args

        # 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.DEVICE_MANAGER])

        PushConfigState.set_repush_interval(int(self._args.repush_interval))
        PushConfigState.set_repush_max_interval(int(self._args.repush_max_interval))
        PushConfigState.set_push_delay_per_kb(float(self._args.push_delay_per_kb))
        PushConfigState.set_push_delay_max(int(self._args.push_delay_max))
        PushConfigState.set_push_delay_enable(bool(self._args.push_delay_enable))

        self._sandesh = Sandesh()
        # Reset the sandesh send rate limit value
        if self._args.sandesh_send_rate_limit is not None:
            SandeshSystem.set_sandesh_send_rate_limit( \
                self._args.sandesh_send_rate_limit)
        module = Module.DEVICE_MANAGER
        module_name = ModuleNames[module]
        node_type = Module2NodeType[module]
        node_type_name = NodeTypeNames[node_type]
        instance_id = INSTANCE_ID_DEFAULT
        hostname = socket.gethostname()
        self._sandesh.init_generator(
            module_name, hostname, node_type_name, instance_id,
            self._args.collectors, 'to_bgp_context',
            int(args.http_server_port),
            ['cfgm_common', 'device_manager.sandesh'], self._disc)
        self._sandesh.set_logging_params(enable_local_log=args.log_local,
                                         category=args.log_category,
                                         level=args.log_level,
                                         file=args.log_file,
                                         enable_syslog=args.use_syslog,
                                         syslog_facility=args.syslog_facility)
        PhysicalRouterDM._sandesh = self._sandesh
        ConnectionState.init(
            self._sandesh, hostname, module_name, instance_id,
            staticmethod(ConnectionState.get_process_state_cb),
            NodeStatusUVE, NodeStatus)

        # Retry till API server is up
        connected = False
        self.connection_state_update(ConnectionStatus.INIT)
        while not connected:
            try:
                self._vnc_lib = VncApi(
                    args.admin_user, args.admin_password,
                    args.admin_tenant_name, args.api_server_ip,
                    args.api_server_port, api_server_use_ssl=args.api_server_use_ssl)
                connected = True
                self.connection_state_update(ConnectionStatus.UP)
            except requests.exceptions.ConnectionError as e:
                # Update connection info
                self.connection_state_update(ConnectionStatus.DOWN, str(e))
                time.sleep(3)
            except ResourceExhaustionError:  # haproxy throws 503
                time.sleep(3)

        rabbit_servers = self._args.rabbit_server
        rabbit_port = self._args.rabbit_port
        rabbit_user = self._args.rabbit_user
        rabbit_password = self._args.rabbit_password
        rabbit_vhost = self._args.rabbit_vhost
        rabbit_ha_mode = self._args.rabbit_ha_mode

        self._db_resync_done = gevent.event.Event()

        q_name = 'device_manager.%s' % (socket.gethostname())
        self._vnc_kombu = VncKombuClient(rabbit_servers, rabbit_port,
                                         rabbit_user, rabbit_password,
                                         rabbit_vhost, rabbit_ha_mode,
                                         q_name, self._vnc_subscribe_callback,
                                         self.config_log)

        self._cassandra = DMCassandraDB.getInstance(self) 

        DBBaseDM.init(self, self._sandesh.logger(), self._cassandra)
        for obj in GlobalSystemConfigDM.list_obj():
            GlobalSystemConfigDM.locate(obj['uuid'], obj)

        for obj in GlobalVRouterConfigDM.list_obj():
            GlobalVRouterConfigDM.locate(obj['uuid'], obj)

        for obj in VirtualNetworkDM.list_obj():
            vn = VirtualNetworkDM.locate(obj['uuid'], obj)
            if vn is not None and vn.routing_instances is not None:
                for ri_id in vn.routing_instances:
                    ri_obj = RoutingInstanceDM.locate(ri_id)

        for obj in BgpRouterDM.list_obj():
            BgpRouterDM.locate(obj['uuid'], obj)

        pr_obj_list = PhysicalRouterDM.list_obj()
        pr_uuid_set = set([pr_obj['uuid'] for pr_obj in pr_obj_list])
        self._cassandra.handle_pr_deletes(pr_uuid_set)

        for obj in pr_obj_list:
            pr = PhysicalRouterDM.locate(obj['uuid'], obj)
            li_set = pr.logical_interfaces
            for pi_id in pr.physical_interfaces:
                pi = PhysicalInterfaceDM.locate(pi_id)
                if pi:
                    li_set |= pi.logical_interfaces
            vmi_set = set()
            for li_id in li_set:
                li = LogicalInterfaceDM.locate(li_id)
                if li and li.virtual_machine_interface:
                    vmi_set |= set([li.virtual_machine_interface])
            for vmi_id in vmi_set:
                vmi = VirtualMachineInterfaceDM.locate(vmi_id)

        for obj in InstanceIpDM.list_obj():
            InstanceIpDM.locate(obj['uuid'], obj)

        for obj in FloatingIpDM.list_obj():
            FloatingIpDM.locate(obj['uuid'], obj)

        for vn in VirtualNetworkDM.values():
            vn.update_instance_ip_map()

        for pr in PhysicalRouterDM.values():
            pr.set_config_state()

        self._db_resync_done.set()
        gevent.joinall(self._vnc_kombu.greenlets())
    # end __init__

    def connection_state_update(self, status, message=None):
        ConnectionState.update(
            conn_type=ConnectionType.APISERVER, name='ApiServer',
            status=status, message=message or '',
            server_addrs=['%s:%s' % (self._args.api_server_ip,
                                     self._args.api_server_port)])
    # end connection_state_update

    def config_log(self, msg, level):
        self._sandesh.logger().log(SandeshLogger.get_py_logger_level(level),
                                   msg)

    def _vnc_subscribe_callback(self, oper_info):
        self._db_resync_done.wait()
        dependency_tracker = None
        try:
            msg = "Notification Message: %s" % (pformat(oper_info))
            self.config_log(msg, level=SandeshLevel.SYS_DEBUG)
            obj_type = oper_info['type'].replace('-', '_')
            obj_class = DBBaseDM.get_obj_type_map().get(obj_type)
            if obj_class is None:
                return

            if oper_info['oper'] == 'CREATE':
                obj_dict = oper_info['obj_dict']
                obj_id = obj_dict['uuid']
                obj = obj_class.locate(obj_id, obj_dict)
                dependency_tracker = DependencyTracker(
                    DBBaseDM.get_obj_type_map(), self._REACTION_MAP)
                dependency_tracker.evaluate(obj_type, obj)
            elif oper_info['oper'] == 'UPDATE':
                obj_id = oper_info['uuid']
                obj = obj_class.get(obj_id)
                old_dt = None
                if obj is not None:
                    old_dt = DependencyTracker(
                        DBBaseDM.get_obj_type_map(), self._REACTION_MAP)
                    old_dt.evaluate(obj_type, obj)
                else:
                    obj = obj_class.locate(obj_id)
                obj.update()
                dependency_tracker = DependencyTracker(
                    DBBaseDM.get_obj_type_map(), self._REACTION_MAP)
                dependency_tracker.evaluate(obj_type, obj)
                if old_dt:
                    for resource, ids in old_dt.resources.items():
                        if resource not in dependency_tracker.resources:
                            dependency_tracker.resources[resource] = ids
                        else:
                            dependency_tracker.resources[resource] = list(
                                set(dependency_tracker.resources[resource]) |
                                set(ids))
            elif oper_info['oper'] == 'DELETE':
                obj_id = oper_info['uuid']
                obj = obj_class.get(obj_id)
                if obj is None:
                    return
                dependency_tracker = DependencyTracker(
                    DBBaseDM.get_obj_type_map(), self._REACTION_MAP)
                dependency_tracker.evaluate(obj_type, obj)
                obj_class.delete(obj_id)
            else:
                # unknown operation
                self.config_log('Unknown operation %s' % oper_info['oper'],
                                level=SandeshLevel.SYS_ERR)
                return

            if obj is None:
                self.config_log('Error while accessing %s uuid %s' % (
                                obj_type, obj_id))
                return

        except Exception:
            string_buf = cStringIO.StringIO()
            cgitb.Hook(file=string_buf, format="text").handle(sys.exc_info())
            self.config_log(string_buf.getvalue(), level=SandeshLevel.SYS_ERR)

        if not dependency_tracker:
            return

        for vn_id in dependency_tracker.resources.get('virtual_network', []):
            vn = VirtualNetworkDM.get(vn_id)
            if vn is not None:
                vn.update_instance_ip_map()

        for pr_id in dependency_tracker.resources.get('physical_router', []):
            pr = PhysicalRouterDM.get(pr_id)
            if pr is not None:
                pr.set_config_state()
    def __init__(self, args=None):
        self._args = args

        # 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.DEVICE_MANAGER])

        PushConfigState.set_repush_interval(int(self._args.repush_interval))
        PushConfigState.set_repush_max_interval(int(self._args.repush_max_interval))
        PushConfigState.set_push_delay_per_kb(float(self._args.push_delay_per_kb))
        PushConfigState.set_push_delay_max(int(self._args.push_delay_max))
        PushConfigState.set_push_delay_enable(bool(self._args.push_delay_enable))

        self._sandesh = Sandesh()
        # Reset the sandesh send rate limit value
        if self._args.sandesh_send_rate_limit is not None:
            SandeshSystem.set_sandesh_send_rate_limit( \
                self._args.sandesh_send_rate_limit)
        module = Module.DEVICE_MANAGER
        module_name = ModuleNames[module]
        node_type = Module2NodeType[module]
        node_type_name = NodeTypeNames[node_type]
        instance_id = INSTANCE_ID_DEFAULT
        hostname = socket.gethostname()
        self._sandesh.init_generator(
            module_name, hostname, node_type_name, instance_id,
            self._args.collectors, 'to_bgp_context',
            int(args.http_server_port),
            ['cfgm_common', 'device_manager.sandesh'], self._disc)
        self._sandesh.set_logging_params(enable_local_log=args.log_local,
                                         category=args.log_category,
                                         level=args.log_level,
                                         file=args.log_file,
                                         enable_syslog=args.use_syslog,
                                         syslog_facility=args.syslog_facility)
        PhysicalRouterDM._sandesh = self._sandesh
        ConnectionState.init(
            self._sandesh, hostname, module_name, instance_id,
            staticmethod(ConnectionState.get_process_state_cb),
            NodeStatusUVE, NodeStatus)

        # Retry till API server is up
        connected = False
        self.connection_state_update(ConnectionStatus.INIT)
        while not connected:
            try:
                self._vnc_lib = VncApi(
                    args.admin_user, args.admin_password,
                    args.admin_tenant_name, args.api_server_ip,
                    args.api_server_port, api_server_use_ssl=args.api_server_use_ssl)
                connected = True
                self.connection_state_update(ConnectionStatus.UP)
            except requests.exceptions.ConnectionError as e:
                # Update connection info
                self.connection_state_update(ConnectionStatus.DOWN, str(e))
                time.sleep(3)
            except ResourceExhaustionError:  # haproxy throws 503
                time.sleep(3)

        rabbit_servers = self._args.rabbit_server
        rabbit_port = self._args.rabbit_port
        rabbit_user = self._args.rabbit_user
        rabbit_password = self._args.rabbit_password
        rabbit_vhost = self._args.rabbit_vhost
        rabbit_ha_mode = self._args.rabbit_ha_mode

        self._db_resync_done = gevent.event.Event()

        q_name = 'device_manager.%s' % (socket.gethostname())
        self._vnc_kombu = VncKombuClient(rabbit_servers, rabbit_port,
                                         rabbit_user, rabbit_password,
                                         rabbit_vhost, rabbit_ha_mode,
                                         q_name, self._vnc_subscribe_callback,
                                         self.config_log)

        self._cassandra = DMCassandraDB.getInstance(self) 

        DBBaseDM.init(self, self._sandesh.logger(), self._cassandra)
        for obj in GlobalSystemConfigDM.list_obj():
            GlobalSystemConfigDM.locate(obj['uuid'], obj)

        for obj in GlobalVRouterConfigDM.list_obj():
            GlobalVRouterConfigDM.locate(obj['uuid'], obj)

        for obj in VirtualNetworkDM.list_obj():
            vn = VirtualNetworkDM.locate(obj['uuid'], obj)
            if vn is not None and vn.routing_instances is not None:
                for ri_id in vn.routing_instances:
                    ri_obj = RoutingInstanceDM.locate(ri_id)

        for obj in BgpRouterDM.list_obj():
            BgpRouterDM.locate(obj['uuid'], obj)

        pr_obj_list = PhysicalRouterDM.list_obj()
        pr_uuid_set = set([pr_obj['uuid'] for pr_obj in pr_obj_list])
        self._cassandra.handle_pr_deletes(pr_uuid_set)

        for obj in pr_obj_list:
            pr = PhysicalRouterDM.locate(obj['uuid'], obj)
            li_set = pr.logical_interfaces
            for pi_id in pr.physical_interfaces:
                pi = PhysicalInterfaceDM.locate(pi_id)
                if pi:
                    li_set |= pi.logical_interfaces
            vmi_set = set()
            for li_id in li_set:
                li = LogicalInterfaceDM.locate(li_id)
                if li and li.virtual_machine_interface:
                    vmi_set |= set([li.virtual_machine_interface])
            for vmi_id in vmi_set:
                vmi = VirtualMachineInterfaceDM.locate(vmi_id)

        for obj in InstanceIpDM.list_obj():
            InstanceIpDM.locate(obj['uuid'], obj)

        for obj in FloatingIpDM.list_obj():
            FloatingIpDM.locate(obj['uuid'], obj)

        for vn in VirtualNetworkDM.values():
            vn.update_instance_ip_map()

        for pr in PhysicalRouterDM.values():
            pr.set_config_state()

        self._db_resync_done.set()
        gevent.joinall(self._vnc_kombu.greenlets())
    def __init__(self, args=None):
        self._args = args

        # 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.DEVICE_MANAGER])

        self._sandesh = Sandesh()
        module = Module.DEVICE_MANAGER
        module_name = ModuleNames[module]
        node_type = Module2NodeType[module]
        node_type_name = NodeTypeNames[node_type]
        instance_id = INSTANCE_ID_DEFAULT
        hostname = socket.gethostname()
        self._sandesh.init_generator(module_name, hostname, node_type_name,
                                     instance_id, self._args.collectors,
                                     'to_bgp_context',
                                     int(args.http_server_port),
                                     ['cfgm_common', 'device_manager.sandesh'],
                                     self._disc)
        self._sandesh.set_logging_params(enable_local_log=args.log_local,
                                         category=args.log_category,
                                         level=args.log_level,
                                         file=args.log_file,
                                         enable_syslog=args.use_syslog,
                                         syslog_facility=args.syslog_facility)
        PhysicalRouterDM._sandesh = self._sandesh
        ConnectionState.init(
            self._sandesh, hostname, module_name, instance_id,
            staticmethod(ConnectionState.get_process_state_cb), NodeStatusUVE,
            NodeStatus)

        # Retry till API server is up
        connected = False
        self.connection_state_update(ConnectionStatus.INIT)
        while not connected:
            try:
                self._vnc_lib = VncApi(args.admin_user, args.admin_password,
                                       args.admin_tenant_name,
                                       args.api_server_ip,
                                       args.api_server_port)
                connected = True
                self.connection_state_update(ConnectionStatus.UP)
            except requests.exceptions.ConnectionError as e:
                # Update connection info
                self.connection_state_update(ConnectionStatus.DOWN, str(e))
                time.sleep(3)
            except ResourceExhaustionError:  # haproxy throws 503
                time.sleep(3)

        rabbit_servers = self._args.rabbit_server
        rabbit_port = self._args.rabbit_port
        rabbit_user = self._args.rabbit_user
        rabbit_password = self._args.rabbit_password
        rabbit_vhost = self._args.rabbit_vhost
        rabbit_ha_mode = self._args.rabbit_ha_mode

        self._db_resync_done = gevent.event.Event()

        q_name = 'device_manager.%s' % (socket.gethostname())
        self._vnc_kombu = VncKombuClient(rabbit_servers, rabbit_port,
                                         rabbit_user, rabbit_password,
                                         rabbit_vhost, rabbit_ha_mode, q_name,
                                         self._vnc_subscribe_callback,
                                         self.config_log)

        self._cassandra = DMCassandraDB.getInstance(self)

        DBBaseDM.init(self, self._sandesh.logger(), self._cassandra)
        for obj in GlobalSystemConfigDM.list_obj():
            GlobalSystemConfigDM.locate(obj['uuid'], obj)

        for obj in GlobalVRouterConfigDM.list_obj():
            GlobalVRouterConfigDM.locate(obj['uuid'], obj)

        for obj in VirtualNetworkDM.list_obj():
            vn = VirtualNetworkDM.locate(obj['uuid'], obj)
            if vn is not None and vn.routing_instances is not None:
                for ri_id in vn.routing_instances:
                    ri_obj = RoutingInstanceDM.locate(ri_id)

        for obj in BgpRouterDM.list_obj():
            BgpRouterDM.locate(obj['uuid'], obj)

        pr_obj_list = PhysicalRouterDM.list_obj()
        pr_uuid_set = set([pr_obj['uuid'] for pr_obj in pr_obj_list])
        self._cassandra.handle_pr_deletes(pr_uuid_set)

        for obj in pr_obj_list:
            pr = PhysicalRouterDM.locate(obj['uuid'], obj)
            li_set = pr.logical_interfaces
            for pi_id in pr.physical_interfaces:
                pi = PhysicalInterfaceDM.locate(pi_id)
                if pi:
                    li_set |= pi.logical_interfaces
            vmi_set = set()
            for li_id in li_set:
                li = LogicalInterfaceDM.locate(li_id)
                if li and li.virtual_machine_interface:
                    vmi_set |= set([li.virtual_machine_interface])
            for vmi_id in vmi_set:
                vmi = VirtualMachineInterfaceDM.locate(vmi_id)

        for obj in InstanceIpDM.list_obj():
            InstanceIpDM.locate(obj['uuid'], obj)

        for obj in FloatingIpDM.list_obj():
            FloatingIpDM.locate(obj['uuid'], obj)

        for vn in VirtualNetworkDM.values():
            vn.update_instance_ip_map()

        for pr in PhysicalRouterDM.values():
            pr.set_config_state()

        self._db_resync_done.set()
        while 1:
            # Just wait indefinitely
            time.sleep(5)
Exemplo n.º 6
0
class VncAmqpHandle(object):
    def __init__(self, logger, db_cls, reaction_map, q_name_prefix, args=None):
        self.logger = logger
        self.db_cls = db_cls
        self.reaction_map = reaction_map
        self.q_name_prefix = q_name_prefix
        self._db_resync_done = gevent.event.Event()
        self._args = args

    def establish(self):
        q_name = '.'.join([self.q_name_prefix, socket.gethostname()])
        self._vnc_kombu = VncKombuClient(
            self._args.rabbit_server,
            self._args.rabbit_port,
            self._args.rabbit_user,
            self._args.rabbit_password,
            self._args.rabbit_vhost,
            self._args.rabbit_ha_mode,
            q_name,
            self._vnc_subscribe_callback,
            self.logger.log,
            rabbit_use_ssl=self._args.rabbit_use_ssl,
            kombu_ssl_version=self._args.kombu_ssl_version,
            kombu_ssl_keyfile=self._args.kombu_ssl_keyfile,
            kombu_ssl_certfile=self._args.kombu_ssl_certfile,
            kombu_ssl_ca_certs=self._args.kombu_ssl_ca_certs)

    def msgbus_store_err_msg(self, msg):
        self.msg_tracer.error = msg

    def msgbus_trace_msg(self):
        self.msg_tracer.trace_msg(name='MessageBusNotifyTraceBuf',
                                  sandesh=self.logger._sandesh)

    def _vnc_subscribe_callback(self, oper_info):
        self._db_resync_done.wait()
        try:
            self.oper_info = oper_info
            self.vnc_subscribe_actions()

        except Exception:
            string_buf = cStringIO.StringIO()
            cgitb_hook(file=string_buf, format="text")
            self.logger.error(string_buf.getvalue())

            self.msgbus_store_err_msg(string_buf.getvalue())
            try:
                with open(self._args.trace_file, 'a') as err_file:
                    err_file.write(string_buf.getvalue())
            except IOError:
                pass
        finally:
            try:
                self.msgbus_trace_msg()
            except Exception:
                pass
            del self.oper_info
            del self.obj_type
            del self.obj_class
            del self.obj
            del self.dependency_tracker

    def create_msgbus_trace(self, request_id, oper, uuid):
        self.msg_tracer = MessageBusNotifyTrace(request_id=request_id,
                                                operation=oper,
                                                uuid=uuid)

    def vnc_subscribe_actions(self):
        msg = "Notification Message: %s" % (pformat(self.oper_info))
        self.logger.debug(msg)

        self.obj = None
        self.dependency_tracker = None
        self.obj_type = self.oper_info['type'].replace('-', '_')
        self.obj_class = self.db_cls.get_obj_type_map().get(self.obj_type)
        if self.obj_class is None:
            return

        oper = self.oper_info['oper']
        obj_id = self.oper_info['uuid']
        self.create_msgbus_trace(self.oper_info.get('request_id'), oper,
                                 obj_id)
        if oper == 'CREATE':
            self.handle_create()
        elif oper == 'UPDATE':
            self.handle_update()
        elif oper == 'DELETE':
            self.handle_delete()
        else:
            self.handle_unknown()
            return
        if self.obj is None:
            self.logger.error('Error while accessing %s uuid %s' %
                              (self.obj_type, obj_id))
            return
        self.evaluate_dependency()

    def handle_create(self):
        obj_dict = self.oper_info['obj_dict']
        obj_key = self.db_cls.get_key_from_dict(obj_dict)
        obj_id = self.oper_info['uuid']
        obj_fq_name = obj_dict['fq_name']
        self.db_cls._object_db.cache_uuid_to_fq_name_add(
            obj_id, obj_fq_name, self.obj_type)
        self.obj = self.obj_class.locate(obj_key)
        if self.obj is None:
            self.logger.info('%s id %s fq_name %s not found' %
                             (self.obj_type, obj_id, obj_fq_name))
            return
        self.dependency_tracker = DependencyTracker(
            self.db_cls.get_obj_type_map(), self.reaction_map)
        self.dependency_tracker.evaluate(self.obj_type, self.obj)

    def handle_update(self):
        obj_id = self.oper_info['uuid']
        self.obj = self.obj_class.get_by_uuid(obj_id)
        old_dt = None
        if self.obj is not None:
            old_dt = DependencyTracker(self.db_cls.get_obj_type_map(),
                                       self.reaction_map)
            old_dt.evaluate(self.obj_type, self.obj)
        else:
            self.logger.info('%s id %s not found' % (self.obj_type, obj_id))
            return

        try:
            self.obj.update()
        except NoIdError:
            obj_id = self.oper_info['uuid']
            self.logger.warning('%s uuid %s update caused NoIdError' %
                                (self.obj_type, obj_id))
            return

        self.dependency_tracker = DependencyTracker(
            self.db_cls.get_obj_type_map(), self.reaction_map)
        self.dependency_tracker.evaluate(self.obj_type, self.obj)
        if old_dt:
            for resource, ids in old_dt.resources.items():
                if resource not in self.dependency_tracker.resources:
                    self.dependency_tracker.resources[resource] = ids
                else:
                    self.dependency_tracker.resources[resource] = list(
                        set(self.dependency_tracker.resources[resource])
                        | set(ids))

    def handle_delete(self):
        obj_id = self.oper_info['uuid']
        self.obj = self.obj_class.get_by_uuid(obj_id)
        self.db_cls._object_db.cache_uuid_to_fq_name_del(obj_id)
        if self.obj is None:
            return
        self.dependency_tracker = DependencyTracker(
            self.db_cls.get_obj_type_map(), self.reaction_map)
        self.dependency_tracker.evaluate(self.obj_type, self.obj)
        obj_key = self.db_cls.get_key_from_dict(self.oper_info['obj_dict'])
        self.obj_class.delete(obj_key)

    def handle_unknown(self):
        # unknown operation
        self.logger.error('Unknown operation %s' % self.oper_info['oper'])

    def init_msgbus_fq_name(self):
        self.msg_tracer.fq_name = self.obj.name

    def init_msgbus_dtr(self):
        self.msg_tracer.dependency_tracker_resources = []

    def add_msgbus_dtr(self, res_type, res_id_list):
        dtr = DependencyTrackerResource(obj_type=res_type,
                                        obj_keys=res_id_list)
        self.msg_tracer.dependency_tracker_resources.append(dtr)

    def evaluate_dependency(self):
        if not self.dependency_tracker:
            return

        self.init_msgbus_fq_name()
        self.init_msgbus_dtr()

        for res_type, res_id_list in self.dependency_tracker.resources.items():
            if not res_id_list:
                continue
            self.add_msgbus_dtr(res_type, res_id_list)
            cls = self.db_cls.get_obj_type_map().get(res_type)
            if cls is None:
                continue
            for res_id in res_id_list:
                res_obj = cls.get(res_id)
                if res_obj is not None:
                    res_obj.evaluate()

    def close(self):
        self._vnc_kombu.shutdown()
Exemplo n.º 7
0
class SchemaTransformer(object):

    _REACTION_MAP = {
        'routing_instance': {
            'self': ['virtual_network'],
        },
        'virtual_machine_interface': {
            'self': ['virtual_machine', 'virtual_network'],
            'virtual_network': ['virtual_machine'],
            'logical_router': ['virtual_network'],
            'instance_ip': ['virtual_machine'],
            'floating_ip': ['virtual_machine'],
            'virtual_machine': [],
        },
        'virtual_network': {
            'self': ['network_policy'],
            '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']
        },
        'service_instance': {
            'self': ['network_policy'],
            'virtual_machine': ['network_policy'],
            'network_policy': ['virtual_machine']
        },
        'network_policy': {
            'self': ['virtual_network', 'network_policy', 'service_instance'],
            'service_instance': ['virtual_network'],
            'network_policy': ['virtual_network'],
            'virtual_network': ['virtual_network', 'network_policy']
        },
        'security_group': {
            'self': ['security_group'],
            'security_group': [],
        },
        'route_table': {
            'self': ['virtual_network'],
        },
        'logical_router': {
            'self': [],
            'virtual_machine_interface': [],
        },
        'floating_ip': {
            'self': ['virtual_machine_interface'],
        },
        'instance_ip': {
            'self': ['virtual_machine_interface'],
        },
        'bgp_router': {
            'self': [],
        },
        'global_system_config': {
            'self': [],
        }
    }

    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])

        self._sandesh = Sandesh()
        # Reset the sandesh send rate limit value
        if args.sandesh_send_rate_limit is not None:
            SandeshSystem.set_sandesh_send_rate_limit(
                args.sandesh_send_rate_limit)
        sandesh.VnList.handle_request = self.sandesh_vn_handle_request
        sandesh.RoutintInstanceList.handle_request = \
            self.sandesh_ri_handle_request
        sandesh.ServiceChainList.handle_request = \
            self.sandesh_sc_handle_request
        sandesh.StObjectReq.handle_request = \
            self.sandesh_st_object_handle_request
        module = Module.SCHEMA_TRANSFORMER
        module_name = ModuleNames[module]
        node_type = Module2NodeType[module]
        node_type_name = NodeTypeNames[node_type]
        instance_id = INSTANCE_ID_DEFAULT
        hostname = socket.gethostname()
        self._sandesh.init_generator(
            module_name,
            hostname,
            node_type_name,
            instance_id,
            self._args.collectors,
            'to_bgp_context',
            int(args.http_server_port),
            ['cfgm_common', 'schema_transformer.sandesh'],
            self._disc,
            logger_class=args.logger_class,
            logger_config_file=args.logging_conf)
        self._sandesh.set_logging_params(enable_local_log=args.log_local,
                                         category=args.log_category,
                                         level=args.log_level,
                                         file=args.log_file,
                                         enable_syslog=args.use_syslog,
                                         syslog_facility=args.syslog_facility)
        ConnectionState.init(
            self._sandesh, hostname, module_name, instance_id,
            staticmethod(ConnectionState.get_process_state_cb), NodeStatusUVE,
            NodeStatus)

        rabbit_servers = self._args.rabbit_server
        rabbit_port = self._args.rabbit_port
        rabbit_user = self._args.rabbit_user
        rabbit_password = self._args.rabbit_password
        rabbit_vhost = self._args.rabbit_vhost
        rabbit_ha_mode = self._args.rabbit_ha_mode

        self._db_resync_done = gevent.event.Event()

        q_name = 'schema_transformer.%s' % (socket.gethostname())
        self._vnc_kombu = VncKombuClient(rabbit_servers, rabbit_port,
                                         rabbit_user, rabbit_password,
                                         rabbit_vhost, rabbit_ha_mode, q_name,
                                         self._vnc_subscribe_callback,
                                         self.config_log)
        self._cassandra = SchemaTransformerDB(self, _zookeeper_client)
        DBBaseST.init(self, self._sandesh.logger(), self._cassandra)
        DBBaseST._sandesh = self._sandesh
        DBBaseST._vnc_lib = _vnc_lib
        ServiceChain.init()
        self.reinit()
        # create cpu_info object to send periodic updates
        sysinfo_req = False
        cpu_info = vnc_cpu_info.CpuInfo(module_name, instance_id, sysinfo_req,
                                        self._sandesh, 60)
        self._cpu_info = cpu_info
        self._db_resync_done.set()

    # end __init__

    def config_log(self, msg, level):
        self._sandesh.logger().log(SandeshLogger.get_py_logger_level(level),
                                   msg)

    def _vnc_subscribe_callback(self, oper_info):
        self._db_resync_done.wait()
        dependency_tracker = None
        try:
            msg = "Notification Message: %s" % (pformat(oper_info))
            self.config_log(msg, level=SandeshLevel.SYS_DEBUG)
            obj_type = oper_info['type'].replace('-', '_')
            obj_class = DBBaseST.get_obj_type_map().get(obj_type)
            if obj_class is None:
                return

            oper = oper_info['oper']
            obj_id = oper_info['uuid']
            notify_trace = MessageBusNotifyTrace(
                request_id=oper_info.get('request_id'),
                operation=oper,
                uuid=obj_id)
            if oper == 'CREATE':
                obj_dict = oper_info['obj_dict']
                obj_fq_name = ':'.join(obj_dict['fq_name'])
                obj = obj_class.locate(obj_fq_name)
                if obj is None:
                    self.config_log('%s id %s fq_name %s not found' %
                                    (obj_type, obj_id, obj_fq_name),
                                    level=SandeshLevel.SYS_INFO)
                    return
                dependency_tracker = DependencyTracker(
                    DBBaseST.get_obj_type_map(), self._REACTION_MAP)
                dependency_tracker.evaluate(obj_type, obj)
            elif oper == 'UPDATE':
                obj = obj_class.get_by_uuid(obj_id)
                old_dt = None
                if obj is not None:
                    old_dt = DependencyTracker(DBBaseST.get_obj_type_map(),
                                               self._REACTION_MAP)
                    old_dt.evaluate(obj_type, obj)
                else:
                    self.config_log('%s id %s not found' % (obj_type, obj_id),
                                    level=SandeshLevel.SYS_INFO)
                    return
                try:
                    obj.update()
                except NoIdError:
                    self.config_log('%s id %s update caused NoIdError' %
                                    (obj_type, obj_id),
                                    level=SandeshLevel.SYS_INFO)
                    return
                dependency_tracker = DependencyTracker(
                    DBBaseST.get_obj_type_map(), self._REACTION_MAP)
                dependency_tracker.evaluate(obj_type, obj)
                if old_dt:
                    for resource, ids in old_dt.resources.items():
                        if resource not in dependency_tracker.resources:
                            dependency_tracker.resources[resource] = ids
                        else:
                            dependency_tracker.resources[resource] = list(
                                set(dependency_tracker.resources[resource])
                                | set(ids))
            elif oper == 'DELETE':
                obj = obj_class.get_by_uuid(obj_id)
                if obj is None:
                    return
                dependency_tracker = DependencyTracker(
                    DBBaseST.get_obj_type_map(), self._REACTION_MAP)
                dependency_tracker.evaluate(obj_type, obj)
                obj_class.delete(obj.name)
            else:
                # unknown operation
                self.config_log('Unknown operation %s' % oper,
                                level=SandeshLevel.SYS_ERR)
                return

            if obj is None:
                self.config_log('Error while accessing %s uuid %s' %
                                (obj_type, obj_id))
                return

            notify_trace.fq_name = obj.name
            if not dependency_tracker:
                return

            notify_trace.dependency_tracker_resources = []
            for res_type, res_id_list in dependency_tracker.resources.items():
                if not res_id_list:
                    continue
                dtr = DependencyTrackerResource(obj_type=res_type,
                                                obj_keys=res_id_list)
                notify_trace.dependency_tracker_resources.append(dtr)
                cls = DBBaseST.get_obj_type_map().get(res_type)
                if cls is None:
                    continue
                for res_id in res_id_list:
                    res_obj = cls.get(res_id)
                    if res_obj is not None:
                        res_obj.evaluate()

            for vn_id in dependency_tracker.resources.get(
                    'virtual_network', []):
                vn = VirtualNetworkST.get(vn_id)
                if vn is not None:
                    vn.uve_send()
            # end for vn_id
        except Exception as e:
            string_buf = cStringIO.StringIO()
            cgitb.Hook(file=string_buf, format="text").handle(sys.exc_info())
            notify_trace.error = string_buf.getvalue()
            try:
                with open(self._args.trace_file, 'a') as err_file:
                    err_file.write(string_buf.getvalue())
            except IOError:
                self.config_log(string_buf.getvalue(),
                                level=SandeshLevel.SYS_ERR)
        finally:
            try:
                trace_msg(notify_trace, 'MessageBusNotifyTraceBuf',
                          self._sandesh)
            except Exception:
                pass

    # end _vnc_subscribe_callback

    # Clean up stale objects
    def reinit(self):
        for gsc in GlobalSystemConfigST.list_vnc_obj():
            GlobalSystemConfigST.locate(gsc.uuid, gsc)
        for bgpr in BgpRouterST.list_vnc_obj():
            if bgpr.get_bgp_router_parameters():
                BgpRouterST.locate(bgpr.get_fq_name_str(), bgpr)
        for lr in LogicalRouterST.list_vnc_obj():
            LogicalRouterST.locate(lr.get_fq_name_str(), lr)
        vn_list = list(VirtualNetworkST.list_vnc_obj())
        vn_id_list = [vn.uuid for vn in vn_list]
        ri_dict = {}
        for ri in DBBaseST.list_vnc_obj('routing_instance'):
            delete = False
            if ri.parent_uuid not in vn_id_list:
                delete = True
            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 and sc_id not in ServiceChain:
                    delete = True
                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._sandesh._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._sandesh._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)
        for rt in RouteTargetST.list_vnc_obj():
            rt_name = rt.get_fq_name_str()
            RouteTargetST.locate(rt_name, RouteTarget(rt_name))
        for vn in vn_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)

        for policy in NetworkPolicyST.list_vnc_obj():
            NetworkPolicyST.locate(policy.get_fq_name_str(), policy)
        gevent.sleep(0.001)
        for vmi in VirtualMachineInterfaceST.list_vnc_obj():
            VirtualMachineInterfaceST.locate(vmi.get_fq_name_str(), vmi)

        gevent.sleep(0.001)
        for iip in InstanceIpST.list_vnc_obj():
            InstanceIpST.locate(iip.get_fq_name_str(), iip)
        gevent.sleep(0.001)
        for fip in FloatingIpST.list_vnc_obj():
            FloatingIpST.locate(fip.get_fq_name_str(), fip)

        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)

        for cls in DBBaseST.get_obj_type_map().values():
            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()

    # end process_stale_objects

    def sandesh_ri_build(self, vn_name, ri_name):
        vn = VirtualNetworkST.get(vn_name)
        sandesh_ri_list = []
        for riname in vn.routing_instances:
            ri = RoutingInstanceST.get(riname)
            sandesh_ri = sandesh.RoutingInstance(name=ri.obj.get_fq_name_str())
            sandesh_ri.service_chain = ri.service_chain
            sandesh_ri.connections = list(ri.connections)
            sandesh_ri_list.append(sandesh_ri)
        return sandesh_ri_list

    # end sandesh_ri_build

    def sandesh_ri_handle_request(self, req):
        # Return the list of VNs
        ri_resp = sandesh.RoutingInstanceListResp(routing_instances=[])
        if req.vn_name is None:
            for vn in VirtualNetworkST:
                sandesh_ri = self.sandesh_ri_build(vn, req.ri_name)
                ri_resp.routing_instances.extend(sandesh_ri)
        elif req.vn_name in VirtualNetworkST:
            self.sandesh_ri_build(req.vn_name, req.ri_name)
            ri_resp.routing_instances.extend(sandesh_ri)
        ri_resp.response(req.context())

    # end sandesh_ri_handle_request

    def sandesh_vn_build(self, vn_name):
        vn = VirtualNetworkST.get(vn_name)
        sandesh_vn = sandesh.VirtualNetwork(name=vn_name)
        sandesh_vn.policies = vn.network_policys.keys()
        sandesh_vn.connections = list(vn.connections)
        sandesh_vn.routing_instances = vn.routing_instances
        if vn.acl:
            sandesh_vn.acl = vn.acl.get_fq_name_str()
        if vn.dynamic_acl:
            sandesh_vn.dynamic_acl = vn.dynamic_acl.get_fq_name_str()

        return sandesh_vn

    # end sandesh_vn_build

    def sandesh_vn_handle_request(self, req):
        # Return the list of VNs
        vn_resp = sandesh.VnListResp(vn_names=[])
        if req.vn_name is None:
            for vn in VirtualNetworkST:
                sandesh_vn = self.sandesh_vn_build(vn)
                vn_resp.vn_names.append(sandesh_vn)
        elif req.vn_name in VirtualNetworkST:
            sandesh_vn = self.sandesh_vn_build(req.vn_name)
            vn_resp.vn_names.append(sandesh_vn)
        vn_resp.response(req.context())

    # end sandesh_vn_handle_request

    def sandesh_sc_handle_request(self, req):
        sc_resp = sandesh.ServiceChainListResp(service_chains=[])
        if req.sc_name is None:
            for sc in ServiceChain.values():
                sandesh_sc = sc.build_introspect()
                sc_resp.service_chains.append(sandesh_sc)
        elif req.sc_name in ServiceChain:
            sandesh_sc = ServiceChain[req.sc_name].build_introspect()
            sc_resp.service_chains.append(sandesh_sc)
        sc_resp.response(req.context())

    # end sandesh_sc_handle_request

    def sandesh_st_object_handle_request(self, req):
        st_resp = sandesh.StObjectListResp()
        obj_type_map = DBBaseST.get_obj_type_map()
        if req.object_type is not None:
            if req.object_type not in obj_type_map:
                return st_resp
            obj_cls_list = [obj_type_map[req.object_type]]
        else:
            obj_cls_list = obj_type_map.values()
        for obj_cls in obj_cls_list:
            id_or_name = req.object_id_or_fq_name
            if id_or_name:
                obj = obj_cls.get(id_or_name) or obj_cls.get_by_uuid(
                    id_or_name)
                if obj is None:
                    continue
                st_resp.objects.append(obj.handle_st_object_req())
            else:
                for obj in obj_cls.values():
                    st_resp.objects.append(obj.handle_st_object_req())
        return st_resp

    # end sandesh_st_object_handle_request

    def reset(self):
        for cls in DBBaseST.get_obj_type_map().values():
            cls.reset()
        self._vnc_kombu.shutdown()
Exemplo n.º 8
0
    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])

        self._sandesh = Sandesh()
        # Reset the sandesh send rate limit value
        if args.sandesh_send_rate_limit is not None:
            SandeshSystem.set_sandesh_send_rate_limit(
                args.sandesh_send_rate_limit)
        sandesh.VnList.handle_request = self.sandesh_vn_handle_request
        sandesh.RoutintInstanceList.handle_request = \
            self.sandesh_ri_handle_request
        sandesh.ServiceChainList.handle_request = \
            self.sandesh_sc_handle_request
        sandesh.StObjectReq.handle_request = \
            self.sandesh_st_object_handle_request
        module = Module.SCHEMA_TRANSFORMER
        module_name = ModuleNames[module]
        node_type = Module2NodeType[module]
        node_type_name = NodeTypeNames[node_type]
        instance_id = INSTANCE_ID_DEFAULT
        hostname = socket.gethostname()
        self._sandesh.init_generator(
            module_name,
            hostname,
            node_type_name,
            instance_id,
            self._args.collectors,
            'to_bgp_context',
            int(args.http_server_port),
            ['cfgm_common', 'schema_transformer.sandesh'],
            self._disc,
            logger_class=args.logger_class,
            logger_config_file=args.logging_conf)
        self._sandesh.set_logging_params(enable_local_log=args.log_local,
                                         category=args.log_category,
                                         level=args.log_level,
                                         file=args.log_file,
                                         enable_syslog=args.use_syslog,
                                         syslog_facility=args.syslog_facility)
        ConnectionState.init(
            self._sandesh, hostname, module_name, instance_id,
            staticmethod(ConnectionState.get_process_state_cb), NodeStatusUVE,
            NodeStatus)

        rabbit_servers = self._args.rabbit_server
        rabbit_port = self._args.rabbit_port
        rabbit_user = self._args.rabbit_user
        rabbit_password = self._args.rabbit_password
        rabbit_vhost = self._args.rabbit_vhost
        rabbit_ha_mode = self._args.rabbit_ha_mode

        self._db_resync_done = gevent.event.Event()

        q_name = 'schema_transformer.%s' % (socket.gethostname())
        self._vnc_kombu = VncKombuClient(rabbit_servers, rabbit_port,
                                         rabbit_user, rabbit_password,
                                         rabbit_vhost, rabbit_ha_mode, q_name,
                                         self._vnc_subscribe_callback,
                                         self.config_log)
        self._cassandra = SchemaTransformerDB(self, _zookeeper_client)
        DBBaseST.init(self, self._sandesh.logger(), self._cassandra)
        DBBaseST._sandesh = self._sandesh
        DBBaseST._vnc_lib = _vnc_lib
        ServiceChain.init()
        self.reinit()
        # create cpu_info object to send periodic updates
        sysinfo_req = False
        cpu_info = vnc_cpu_info.CpuInfo(module_name, instance_id, sysinfo_req,
                                        self._sandesh, 60)
        self._cpu_info = cpu_info
        self._db_resync_done.set()
Exemplo n.º 9
0
class VncAmqpHandle(object):

    def __init__(self, sandesh, logger, db_cls, reaction_map, q_name_prefix,
                 rabbitmq_cfg, trace_file=None):
        self.sandesh = sandesh
        self.logger = logger
        self.db_cls = db_cls
        self.reaction_map = reaction_map
        self.q_name_prefix = q_name_prefix
        self._db_resync_done = gevent.event.Event()
        self._rabbitmq_cfg = rabbitmq_cfg
        self._trace_file = trace_file

    def establish(self):
        q_name = '.'.join([self.q_name_prefix, socket.gethostname()])
        self._vnc_kombu = VncKombuClient(
                self._rabbitmq_cfg['servers'], self._rabbitmq_cfg['port'],
                self._rabbitmq_cfg['user'], self._rabbitmq_cfg['password'],
                self._rabbitmq_cfg['vhost'], self._rabbitmq_cfg['ha_mode'],
                q_name, self._vnc_subscribe_callback,
                self.logger.log, rabbit_use_ssl=self._rabbitmq_cfg['use_ssl'],
                kombu_ssl_version=self._rabbitmq_cfg['ssl_version'],
                kombu_ssl_keyfile=self._rabbitmq_cfg['ssl_keyfile'],
                kombu_ssl_certfile=self._rabbitmq_cfg['ssl_certfile'],
                kombu_ssl_ca_certs=self._rabbitmq_cfg['ssl_ca_certs'])

    def msgbus_store_err_msg(self, msg):
        self.msg_tracer.error = msg

    def msgbus_trace_msg(self):
        self.msg_tracer.trace_msg(name='MessageBusNotifyTraceBuf',
                                  sandesh=self.sandesh)

    def log_exception(self):
        string_buf = cStringIO.StringIO()
        cgitb_hook(file=string_buf, format="text")
        self.logger.error(string_buf.getvalue())
        self.msgbus_store_err_msg(string_buf.getvalue())
        if not self._trace_file:
            return
        try:
            with open(self._trace_file, 'a') as err_file:
                err_file.write(string_buf.getvalue())
        except IOError:
            pass

    def _vnc_subscribe_callback(self, oper_info):
        self._db_resync_done.wait()
        try:
            self.oper_info = oper_info
            self.vnc_subscribe_actions()

        except ConnectionError:
            try:
                # retry write during api-server ConnectionError
                self.vnc_subscribe_actions()
            except ConnectionError:
                # log the exception, and exit during api-server
                # ConnectionError on retry to let standby to become active.
                self.log_exception()
                self.logger.error("Api-server connection lost. Exiting")
                self.close()
                raise SystemExit
            except Exception:
                self.log_exception()
        except Exception:
            self.log_exception()
        finally:
            try:
                self.msgbus_trace_msg()
            except Exception:
                pass
            del self.oper_info
            del self.obj_type
            del self.obj_class
            del self.obj
            del self.dependency_tracker

    def create_msgbus_trace(self, request_id, oper, uuid):
        self.msg_tracer = MessageBusNotifyTrace(request_id=request_id,
                                                operation=oper, uuid=uuid)

    def vnc_subscribe_actions(self):
        msg = "Notification Message: %s" % (pformat(self.oper_info))
        self.logger.debug(msg)

        self.obj = None
        self.dependency_tracker = None
        self.obj_type = self.oper_info['type'].replace('-', '_')
        self.obj_class = self.db_cls.get_obj_type_map().get(self.obj_type)
        if self.obj_class is None:
            return

        oper = self.oper_info['oper']
        obj_id = self.oper_info['uuid']
        self.create_msgbus_trace(self.oper_info.get('request_id'),
                                 oper, obj_id)
        if oper == 'CREATE':
            self.handle_create()
        elif oper == 'UPDATE':
            self.handle_update()
        elif oper == 'DELETE':
            self.handle_delete()
        elif oper == 'UPDATE-IMPLICIT':
            # Ignore this operation
            return
        else:
            self.handle_unknown()
            return
        if self.obj is None:
            self.logger.warning(
                    "Object %s uuid %s was not found for operation %s" %
                    (self. obj_type, obj_id, oper))
            return
        self.evaluate_dependency()

    def _get_key_from_oper_info(self):
        if self.db_cls._indexed_by_name:
            return ':'.join(self.oper_info['fq_name'])
        return self.oper_info['uuid']

    def handle_create(self):
        obj_key = self._get_key_from_oper_info()
        obj_id = self.oper_info['uuid']
        obj_fq_name = self.oper_info['fq_name']
        self.db_cls._object_db.cache_uuid_to_fq_name_add(
                obj_id, obj_fq_name, self.obj_type)
        self.obj = self.obj_class.locate(obj_key)
        if self.obj is None:
            self.logger.info('%s id %s fq_name %s not found' % (
                self.obj_type, obj_id, obj_fq_name))
            return
        self.dependency_tracker = DependencyTracker(
            self.db_cls.get_obj_type_map(), self.reaction_map)
        self.dependency_tracker.evaluate(self.obj_type, self.obj)

    def handle_update(self):
        obj_id = self.oper_info['uuid']
        self.obj = self.obj_class.get_by_uuid(obj_id)
        old_dt = None
        if self.obj is not None:
            old_dt = DependencyTracker(
                self.db_cls.get_obj_type_map(), self.reaction_map)
            old_dt.evaluate(self.obj_type, self.obj)
        else:
            self.logger.info('%s id %s not found' % (self.obj_type,
                                                     obj_id))
            return

        try:
            ret = self.obj.update()
            if ret is not None and not ret:
                # If update returns None, the function may not support a
                # return value, hence treat it as if something might have
                # changed. If a value is returned, use its truth value.
                # If it True, then some change was detected.
                # If no change, then terminate dependency tracker
                return
        except NoIdError:
            obj_id = self.oper_info['uuid']
            self.logger.warning('%s uuid %s update caused NoIdError' %
                                (self.obj_type, obj_id))
            return

        self.dependency_tracker = DependencyTracker(
                self.db_cls.get_obj_type_map(), self.reaction_map)
        self.dependency_tracker.evaluate(self.obj_type, self.obj)
        if old_dt:
            for resource, ids in old_dt.resources.items():
                if resource not in self.dependency_tracker.resources:
                    self.dependency_tracker.resources[resource] = ids
                else:
                    self.dependency_tracker.resources[resource] = list(
                        set(self.dependency_tracker.resources[resource]) |
                        set(ids))

    def handle_delete(self):
        obj_id = self.oper_info['uuid']
        self.obj = self.obj_class.get_by_uuid(obj_id)
        self.db_cls._object_db.cache_uuid_to_fq_name_del(obj_id)
        if self.obj is None:
            return
        self.dependency_tracker = DependencyTracker(
            self.db_cls.get_obj_type_map(), self.reaction_map)
        self.dependency_tracker.evaluate(self.obj_type, self.obj)
        obj_key = self._get_key_from_oper_info()
        self.obj_class.delete(obj_key)

    def handle_unknown(self):
        # unknown operation
        self.logger.error('Unknown operation %s' % self.oper_info['oper'])

    def init_msgbus_fq_name(self):
        self.msg_tracer.fq_name = self.obj.name

    def init_msgbus_dtr(self):
        self.msg_tracer.dependency_tracker_resources = []

    def add_msgbus_dtr(self, res_type, res_id_list):
        dtr = DependencyTrackerResource(obj_type=res_type,
                                        obj_keys=res_id_list)
        self.msg_tracer.dependency_tracker_resources.append(dtr)

    def evaluate_dependency(self):
        if not self.dependency_tracker:
            return

        self.init_msgbus_fq_name()
        self.init_msgbus_dtr()

        for res_type, res_id_list in self.dependency_tracker.resources.items():
            if not res_id_list:
                continue
            self.add_msgbus_dtr(res_type, res_id_list)
            cls = self.db_cls.get_obj_type_map().get(res_type)
            if cls is None:
                continue
            for res_id in res_id_list:
                res_obj = cls.get(res_id)
                if res_obj is not None:
                    res_obj.evaluate()

    def close(self):
        self._vnc_kombu.shutdown()
Exemplo n.º 10
0
    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])

        self._sandesh = Sandesh()
        # Reset the sandesh send rate limit value
        if args.sandesh_send_rate_limit is not None:
            SandeshSystem.set_sandesh_send_rate_limit(
                args.sandesh_send_rate_limit)
        sandesh.VnList.handle_request = self.sandesh_vn_handle_request
        sandesh.RoutintInstanceList.handle_request = \
            self.sandesh_ri_handle_request
        sandesh.ServiceChainList.handle_request = \
            self.sandesh_sc_handle_request
        sandesh.StObjectReq.handle_request = \
            self.sandesh_st_object_handle_request
        module = Module.SCHEMA_TRANSFORMER
        module_name = ModuleNames[module]
        node_type = Module2NodeType[module]
        node_type_name = NodeTypeNames[node_type]
        self.table = "ObjectConfigNode"
        instance_id = INSTANCE_ID_DEFAULT
        hostname = socket.gethostname()
        self._sandesh.init_generator(
            module_name,
            hostname,
            node_type_name,
            instance_id,
            self._args.collectors,
            'to_bgp_context',
            int(args.http_server_port),
            ['cfgm_common', 'schema_transformer.sandesh'],
            self._disc,
            logger_class=args.logger_class,
            logger_config_file=args.logging_conf)
        self._sandesh.set_logging_params(enable_local_log=args.log_local,
                                         category=args.log_category,
                                         level=args.log_level,
                                         file=args.log_file,
                                         enable_syslog=args.use_syslog,
                                         syslog_facility=args.syslog_facility)
        ConnectionState.init(
            self._sandesh, hostname, module_name, instance_id,
            staticmethod(ConnectionState.get_process_state_cb), NodeStatusUVE,
            NodeStatus, self.table)

        self._sandesh.trace_buffer_create(name="MessageBusNotifyTraceBuf",
                                          size=1000)

        rabbit_servers = self._args.rabbit_server
        rabbit_port = self._args.rabbit_port
        rabbit_user = self._args.rabbit_user
        rabbit_password = self._args.rabbit_password
        rabbit_vhost = self._args.rabbit_vhost
        rabbit_ha_mode = self._args.rabbit_ha_mode

        self._db_resync_done = gevent.event.Event()

        q_name = 'schema_transformer.%s' % (socket.gethostname())
        self._vnc_kombu = VncKombuClient(
            rabbit_servers,
            rabbit_port,
            rabbit_user,
            rabbit_password,
            rabbit_vhost,
            rabbit_ha_mode,
            q_name,
            self._vnc_subscribe_callback,
            self.config_log,
            rabbit_use_ssl=self._args.rabbit_use_ssl,
            kombu_ssl_version=self._args.kombu_ssl_version,
            kombu_ssl_keyfile=self._args.kombu_ssl_keyfile,
            kombu_ssl_certfile=self._args.kombu_ssl_certfile,
            kombu_ssl_ca_certs=self._args.kombu_ssl_ca_certs)
        try:
            self._cassandra = SchemaTransformerDB(self, _zookeeper_client)
            DBBaseST.init(self, self._sandesh.logger(), self._cassandra)
            DBBaseST._sandesh = self._sandesh
            DBBaseST._vnc_lib = _vnc_lib
            ServiceChain.init()
            self.reinit()
            # create cpu_info object to send periodic updates
            sysinfo_req = False
            self._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_kombu.shutdown()
            raise e
Exemplo n.º 11
0
class DeviceManager(object):
    _REACTION_MAP = {
        'physical_router': {
            'self': ['bgp_router',
                     'physical_interface',
                     'logical_interface'],
            'bgp_router': [],
            'physical_interface': [],
            'logical_interface': [],
            'virtual_network': [],
            'global_system_config': [],
        },
        'global_system_config': {
            'self': ['physical_router'],
            'physical_router': [],
        },
        'bgp_router': {
            'self': ['bgp_router', 'physical_router'],
            'bgp_router': ['physical_router'],
            'physical_router': [],
        },
        'physical_interface': {
            'self': ['physical_router',
                     'physical_interface',
                     'logical_interface'],
            'physical_router': ['logical_interface'],
            'logical_interface': ['physical_router'],
            'physical_interface': ['physical_router'],
            'virtual_machine_interface': ['physical_interface'],
        },
        'logical_interface': {
            'self': ['physical_router',
                     'physical_interface',
                     'virtual_machine_interface'],
            'physical_interface': ['virtual_machine_interface'],
            'virtual_machine_interface': ['physical_router',
                                          'physical_interface'],
            'physical_router': ['virtual_machine_interface']
        },
        'virtual_machine_interface': {
            'self': ['logical_interface',
                     'physical_interface',
                     'virtual_network',
                     'floating_ip',
                     'instance_ip',
                     'port_tuple'],
            'logical_interface': ['virtual_network'],
            'virtual_network': ['logical_interface'],
            'floating_ip': ['virtual_network'],
            'instance_ip': ['virtual_network'],
            'routing_instance': ['port_tuple','physical_interface'],
            'port_tuple': ['physical_interface']
        },
        'service_instance': {
            'self': ['port_tuple'],
            'port_tuple':[],
        },
        'port_tuple':{
            'self':['virtual_machine_interface','service_instance'],
            'service_instance':['virtual_machine_interface'],
            'virtual_machine_interface':['service_instance']
        },
        'virtual_network': {
            'self': ['physical_router',
                     'virtual_machine_interface'],
            'routing_instance': ['physical_router',
                                 'virtual_machine_interface'],
            'physical_router': [],
            'virtual_machine_interface': ['physical_router'],
        },
        'routing_instance': {
            'self': ['routing_instance',
                     'virtual_network',
                     'virtual_machine_interface'],
            'routing_instance': ['virtual_network',
                                 'virtual_machine_interface'],
            'virtual_network': []
        },
        'floating_ip': {
            'self': ['virtual_machine_interface'],
            'virtual_machine_interface': [],
        },
        'instance_ip': {
            'self': ['virtual_machine_interface'],
            'virtual_machine_interface': [],
        },
    }

    def __init__(self, args=None):
        self._args = args

        # 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.DEVICE_MANAGER])
        
        PushConfigState.set_repush_interval(int(self._args.repush_interval))
        PushConfigState.set_repush_max_interval(int(self._args.repush_max_interval))
        PushConfigState.set_push_delay_per_kb(float(self._args.push_delay_per_kb))
        PushConfigState.set_push_delay_max(int(self._args.push_delay_max))
        PushConfigState.set_push_delay_enable(bool(self._args.push_delay_enable))

        self._sandesh = Sandesh()
        # Reset the sandesh send rate limit value
        if self._args.sandesh_send_rate_limit is not None:
            SandeshSystem.set_sandesh_send_rate_limit(
                self._args.sandesh_send_rate_limit)
        module = Module.DEVICE_MANAGER
        module_name = ModuleNames[module]
        node_type = Module2NodeType[module]
        node_type_name = NodeTypeNames[node_type]
        self.table = "ObjectConfigNode"
        instance_id = INSTANCE_ID_DEFAULT
        hostname = socket.gethostname()
        self._sandesh.init_generator(
            module_name, hostname, node_type_name, instance_id,
            self._args.collectors, 'to_bgp_context',
            int(args.http_server_port),
            ['cfgm_common', 'device_manager.sandesh'], self._disc)
        self._sandesh.set_logging_params(enable_local_log=args.log_local,
                                         category=args.log_category,
                                         level=args.log_level,
                                         file=args.log_file,
                                         enable_syslog=args.use_syslog,
                                         syslog_facility=args.syslog_facility)
        PhysicalRouterDM._sandesh = self._sandesh
        ConnectionState.init(
            self._sandesh, hostname, module_name, instance_id,
            staticmethod(ConnectionState.get_process_state_cb),
            NodeStatusUVE, NodeStatus, self.table)

        # Retry till API server is up
        connected = False
        self.connection_state_update(ConnectionStatus.INIT)
        while not connected:
            try:
                self._vnc_lib = VncApi(
                    args.admin_user, args.admin_password,
                    args.admin_tenant_name, args.api_server_ip,
                    args.api_server_port,
                    api_server_use_ssl=args.api_server_use_ssl)
                connected = True
                self.connection_state_update(ConnectionStatus.UP)
            except requests.exceptions.ConnectionError as e:
                # Update connection info
                self.connection_state_update(ConnectionStatus.DOWN, str(e))
                time.sleep(3)
            except ResourceExhaustionError:  # haproxy throws 503
                time.sleep(3)

        rabbit_servers = self._args.rabbit_server
        rabbit_port = self._args.rabbit_port
        rabbit_user = self._args.rabbit_user
        rabbit_password = self._args.rabbit_password
        rabbit_vhost = self._args.rabbit_vhost
        rabbit_ha_mode = self._args.rabbit_ha_mode

        self._db_resync_done = gevent.event.Event()

        q_name = 'device_manager.%s' % (socket.gethostname())
        self._vnc_kombu = VncKombuClient(rabbit_servers, rabbit_port,
                                         rabbit_user, rabbit_password,
                                         rabbit_vhost, rabbit_ha_mode,
                                         q_name, self._vnc_subscribe_callback,
                                         self.config_log, rabbit_use_ssl =
                                         self._args.rabbit_use_ssl,
                                         kombu_ssl_version =
                                         self._args.kombu_ssl_version,
                                         kombu_ssl_keyfile =
                                         self._args.kombu_ssl_keyfile,
                                         kombu_ssl_certfile =
                                         self._args.kombu_ssl_certfile,
                                         kombu_ssl_ca_certs =
                                         self._args.kombu_ssl_ca_certs)

        self._cassandra = DMCassandraDB.getInstance(self, _zookeeper_client)

        DBBaseDM.init(self, self._sandesh.logger(), self._cassandra)
        for obj in GlobalSystemConfigDM.list_obj():
            GlobalSystemConfigDM.locate(obj['uuid'], obj)

        for obj in GlobalVRouterConfigDM.list_obj():
            GlobalVRouterConfigDM.locate(obj['uuid'], obj)

        for obj in VirtualNetworkDM.list_obj():
            vn = VirtualNetworkDM.locate(obj['uuid'], obj)
            if vn is not None and vn.routing_instances is not None:
                for ri_id in vn.routing_instances:
                    ri_obj = RoutingInstanceDM.locate(ri_id)

        for obj in BgpRouterDM.list_obj():
            BgpRouterDM.locate(obj['uuid'], obj)

        pr_obj_list = PhysicalRouterDM.list_obj()
        pr_uuid_set = set([pr_obj['uuid'] for pr_obj in pr_obj_list])
        self._cassandra.handle_pr_deletes(pr_uuid_set)

        for obj in PortTupleDM.list_obj():
            PortTupleDM.locate(obj['uuid'],obj)

        for obj in pr_obj_list:
            pr = PhysicalRouterDM.locate(obj['uuid'], obj)
            li_set = pr.logical_interfaces
            vmi_set = set()
            for pi_id in pr.physical_interfaces:
                pi = PhysicalInterfaceDM.locate(pi_id)
                if pi:
                    li_set |= pi.logical_interfaces
                    vmi_set |= pi.virtual_machine_interfaces
            for li_id in li_set:
                li = LogicalInterfaceDM.locate(li_id)
                if li and li.virtual_machine_interface:
                    vmi_set |= set([li.virtual_machine_interface])
            for vmi_id in vmi_set:
                vmi = VirtualMachineInterfaceDM.locate(vmi_id)

        si_obj_list = ServiceInstanceDM.list_obj()
        si_uuid_set = set([si_obj['uuid'] for si_obj in si_obj_list])
        self._cassandra.handle_pnf_resource_deletes(si_uuid_set)

        for obj in si_obj_list:
            ServiceInstanceDM.locate(obj['uuid'], obj)

        for obj in InstanceIpDM.list_obj():
            InstanceIpDM.locate(obj['uuid'], obj)

        for obj in FloatingIpDM.list_obj():
            FloatingIpDM.locate(obj['uuid'], obj)

        for vn in VirtualNetworkDM.values():
            vn.update_instance_ip_map()

        for pr in PhysicalRouterDM.values():
            pr.set_config_state()

        self._db_resync_done.set()
        gevent.joinall(self._vnc_kombu.greenlets())
    # end __init__

    def connection_state_update(self, status, message=None):
        ConnectionState.update(
            conn_type=ConnType.APISERVER, name='ApiServer',
            status=status, message=message or '',
            server_addrs=['%s:%s' % (self._args.api_server_ip,
                                     self._args.api_server_port)])
    # end connection_state_update

    def config_log(self, msg, level):
        self._sandesh.logger().log(SandeshLogger.get_py_logger_level(level),
                                   msg)

    def _vnc_subscribe_callback(self, oper_info):
        self._db_resync_done.wait()
        dependency_tracker = None
        try:
            msg = "Notification Message: %s" % (pformat(oper_info))
            self.config_log(msg, level=SandeshLevel.SYS_DEBUG)
            obj_type = oper_info['type'].replace('-', '_')
            obj_class = DBBaseDM.get_obj_type_map().get(obj_type)
            if obj_class is None:
                return

            if oper_info['oper'] == 'CREATE':
                obj_dict = oper_info['obj_dict']
                obj_id = obj_dict['uuid']
                obj = obj_class.locate(obj_id, obj_dict)
                dependency_tracker = DependencyTracker(
                    DBBaseDM.get_obj_type_map(), self._REACTION_MAP)
                dependency_tracker.evaluate(obj_type, obj)
            elif oper_info['oper'] == 'UPDATE':
                obj_id = oper_info['uuid']
                obj = obj_class.get(obj_id)
                old_dt = None
                if obj is not None:
                    old_dt = DependencyTracker(
                        DBBaseDM.get_obj_type_map(), self._REACTION_MAP)
                    old_dt.evaluate(obj_type, obj)
                else:
                    obj = obj_class.locate(obj_id)
                obj.update()
                dependency_tracker = DependencyTracker(
                    DBBaseDM.get_obj_type_map(), self._REACTION_MAP)
                dependency_tracker.evaluate(obj_type, obj)
                if old_dt:
                    for resource, ids in old_dt.resources.items():
                        if resource not in dependency_tracker.resources:
                            dependency_tracker.resources[resource] = ids
                        else:
                            dependency_tracker.resources[resource] = list(
                                set(dependency_tracker.resources[resource]) |
                                set(ids))
            elif oper_info['oper'] == 'DELETE':
                obj_id = oper_info['uuid']
                obj = obj_class.get(obj_id)
                if obj is None:
                    return
                dependency_tracker = DependencyTracker(
                    DBBaseDM.get_obj_type_map(), self._REACTION_MAP)
                dependency_tracker.evaluate(obj_type, obj)
                obj_class.delete(obj_id)
            else:
                # unknown operation
                self.config_log('Unknown operation %s' % oper_info['oper'],
                                level=SandeshLevel.SYS_ERR)
                return

            if obj is None:
                self.config_log('Error while accessing %s uuid %s' % (
                                obj_type, obj_id))
                return

        except Exception:
            string_buf = cStringIO.StringIO()
            cgitb_hook(file=string_buf, format="text")
            self.config_log(string_buf.getvalue(), level=SandeshLevel.SYS_ERR)

        if not dependency_tracker:
            return

        for vn_id in dependency_tracker.resources.get('virtual_network', []):
            vn = VirtualNetworkDM.get(vn_id)
            if vn is not None:
                vn.update_instance_ip_map()

        for pr_id in dependency_tracker.resources.get('physical_router', []):
            pr = PhysicalRouterDM.get(pr_id)
            if pr is not None:
                pr.set_config_state()
Exemplo n.º 12
0
class VncAmqpHandle(object):

    def __init__(self, logger, db_cls, reaction_map, q_name_prefix, args=None):
        self.logger = logger
        self.db_cls = db_cls
        self.reaction_map = reaction_map
        self.q_name_prefix = q_name_prefix
        self._db_resync_done = gevent.event.Event()
        self._args = args

    def establish(self):
        q_name = '.'.join([self.q_name_prefix, socket.gethostname()])
        self._vnc_kombu = VncKombuClient(
                self._args.rabbit_server, self._args.rabbit_port,
                self._args.rabbit_user, self._args.rabbit_password,
                self._args.rabbit_vhost, self._args.rabbit_ha_mode,
                q_name, self._vnc_subscribe_callback,
                self.logger.log, rabbit_use_ssl=self._args.rabbit_use_ssl,
                kombu_ssl_version=self._args.kombu_ssl_version,
                kombu_ssl_keyfile=self._args.kombu_ssl_keyfile,
                kombu_ssl_certfile=self._args.kombu_ssl_certfile,
                kombu_ssl_ca_certs=self._args.kombu_ssl_ca_certs)

    def msgbus_store_err_msg(self, msg):
        self.msg_tracer.error = msg

    def msgbus_trace_msg(self):
            self.msg_tracer.trace_msg(name='MessageBusNotifyTraceBuf',
                                      sandesh=self.logger._sandesh)

    def _vnc_subscribe_callback(self, oper_info):
        self._db_resync_done.wait()
        try:
            self.oper_info = oper_info
            self.vnc_subscribe_actions()

        except Exception:
            string_buf = cStringIO.StringIO()
            cgitb_hook(file=string_buf, format="text")
            self.logger.error(string_buf.getvalue())

            self.msgbus_store_err_msg(string_buf.getvalue())
            try:
                with open(self._args.trace_file, 'a') as err_file:
                    err_file.write(string_buf.getvalue())
            except IOError:
                pass
        finally:
            try:
                self.msgbus_trace_msg()
            except Exception:
                pass
            del self.oper_info
            del self.obj_type
            del self.obj_class
            del self.obj
            del self.dependency_tracker

    def create_msgbus_trace(self, request_id, oper, uuid):
        self.msg_tracer = MessageBusNotifyTrace(request_id=request_id,
                                                operation=oper, uuid=uuid)

    def vnc_subscribe_actions(self):
        msg = "Notification Message: %s" % (pformat(self.oper_info))
        self.logger.debug(msg)

        self.obj = None
        self.dependency_tracker = None
        self.obj_type = self.oper_info['type'].replace('-', '_')
        self.obj_class = self.db_cls.get_obj_type_map().get(self.obj_type)
        if self.obj_class is None:
            return

        oper = self.oper_info['oper']
        obj_id = self.oper_info['uuid']
        self.create_msgbus_trace(self.oper_info.get('request_id'),
                                 oper, obj_id)
        if oper == 'CREATE':
            self.handle_create()
        elif oper == 'UPDATE':
            self.handle_update()
        elif oper == 'DELETE':
            self.handle_delete()
        else:
            self.handle_unknown()
            return
        if self.obj is None:
            self.logger.error('Error while accessing %s uuid %s' % (
                self.obj_type, obj_id))
            return
        self.evaluate_dependency()

    def handle_create(self):
        obj_dict = self.oper_info['obj_dict']
        obj_key = self.db_cls.get_key_from_dict(obj_dict)
        obj_id = self.oper_info['uuid']
        obj_fq_name = obj_dict['fq_name']
        self.db_cls._object_db.cache_uuid_to_fq_name_add(
                obj_id, obj_fq_name, self.obj_type)
        self.obj = self.obj_class.locate(obj_key)
        if self.obj is None:
            self.logger.info('%s id %s fq_name %s not found' % (
                self.obj_type, obj_id, obj_fq_name))
            return
        self.dependency_tracker = DependencyTracker(
            self.db_cls.get_obj_type_map(), self.reaction_map)
        self.dependency_tracker.evaluate(self.obj_type, self.obj)

    def handle_update(self):
        obj_id = self.oper_info['uuid']
        self.obj = self.obj_class.get_by_uuid(obj_id)
        old_dt = None
        if self.obj is not None:
            old_dt = DependencyTracker(
                self.db_cls.get_obj_type_map(), self.reaction_map)
            old_dt.evaluate(self.obj_type, self.obj)
        else:
            self.logger.info('%s id %s not found' % (self.obj_type,
                                                     obj_id))
            return

        try:
            self.obj.update()
        except NoIdError:
            obj_id = self.oper_info['uuid']
            self.logger.warning('%s uuid %s update caused NoIdError' %
                                (self.obj_type, obj_id))
            return

        self.dependency_tracker = DependencyTracker(
                self.db_cls.get_obj_type_map(), self.reaction_map)
        self.dependency_tracker.evaluate(self.obj_type, self.obj)
        if old_dt:
            for resource, ids in old_dt.resources.items():
                if resource not in self.dependency_tracker.resources:
                    self.dependency_tracker.resources[resource] = ids
                else:
                    self.dependency_tracker.resources[resource] = list(
                        set(self.dependency_tracker.resources[resource]) |
                        set(ids))

    def handle_delete(self):
        obj_id = self.oper_info['uuid']
        self.obj = self.obj_class.get_by_uuid(obj_id)
        self.db_cls._object_db.cache_uuid_to_fq_name_del(obj_id)
        if self.obj is None:
            return
        self.dependency_tracker = DependencyTracker(
            self.db_cls.get_obj_type_map(), self.reaction_map)
        self.dependency_tracker.evaluate(self.obj_type, self.obj)
        obj_key = self.db_cls.get_key_from_dict(self.oper_info['obj_dict'])
        self.obj_class.delete(obj_key)

    def handle_unknown(self):
        # unknown operation
        self.logger.error('Unknown operation %s' % self.oper_info['oper'])

    def init_msgbus_fq_name(self):
        self.msg_tracer.fq_name = self.obj.name

    def init_msgbus_dtr(self):
        self.msg_tracer.dependency_tracker_resources = []

    def add_msgbus_dtr(self, res_type, res_id_list):
        dtr = DependencyTrackerResource(obj_type=res_type,
                                        obj_keys=res_id_list)
        self.msg_tracer.dependency_tracker_resources.append(dtr)

    def evaluate_dependency(self):
        if not self.dependency_tracker:
            return

        self.init_msgbus_fq_name()
        self.init_msgbus_dtr()

        for res_type, res_id_list in self.dependency_tracker.resources.items():
            if not res_id_list:
                continue
            self.add_msgbus_dtr(res_type, res_id_list)
            cls = self.db_cls.get_obj_type_map().get(res_type)
            if cls is None:
                continue
            for res_id in res_id_list:
                res_obj = cls.get(res_id)
                if res_obj is not None:
                    res_obj.evaluate()

    def close(self):
        self._vnc_kombu.shutdown()
#
#Connect to remote or local rabbitmq cluster to check the connectivity
#
#!/usr/bin/env python

from cfgm_common.vnc_kombu import VncKombuClient
import time

def lognprint(x, level):
    print x

def callb(x):
    print x
    
x = VncKombuClient('10.18.12.1:5672,10.18.12.2:5672,10.18.12.4:5672', '5672', 'guest', 'guest', '', False, 'vnc-config.issu-queue', callb, lognprint)

while (1):
    time.sleep(1)
    print x
Exemplo n.º 14
0
    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])

        self._sandesh = Sandesh()
        # Reset the sandesh send rate limit value
        if args.sandesh_send_rate_limit is not None:
            SandeshSystem.set_sandesh_send_rate_limit(
                args.sandesh_send_rate_limit)
        sandesh.VnList.handle_request = self.sandesh_vn_handle_request
        sandesh.RoutintInstanceList.handle_request = \
            self.sandesh_ri_handle_request
        sandesh.ServiceChainList.handle_request = \
            self.sandesh_sc_handle_request
        sandesh.StObjectReq.handle_request = \
            self.sandesh_st_object_handle_request
        module = Module.SCHEMA_TRANSFORMER
        module_name = ModuleNames[module]
        node_type = Module2NodeType[module]
        node_type_name = NodeTypeNames[node_type]
        instance_id = INSTANCE_ID_DEFAULT
        hostname = socket.gethostname()
        self._sandesh.init_generator(
            module_name, hostname, node_type_name, instance_id,
            self._args.collectors, 'to_bgp_context',
            int(args.http_server_port),
            ['cfgm_common', 'schema_transformer.sandesh'], self._disc,
            logger_class=args.logger_class,
            logger_config_file=args.logging_conf)
        self._sandesh.set_logging_params(enable_local_log=args.log_local,
                                    category=args.log_category,
                                    level=args.log_level,
                                    file=args.log_file,
                                    enable_syslog=args.use_syslog,
                                    syslog_facility=args.syslog_facility)
        ConnectionState.init(self._sandesh, hostname, module_name, instance_id,
                staticmethod(ConnectionState.get_process_state_cb),
                NodeStatusUVE, NodeStatus)

        self._sandesh.trace_buffer_create(name="MessageBusNotifyTraceBuf",
                                          size=1000)

        rabbit_servers = self._args.rabbit_server
        rabbit_port = self._args.rabbit_port
        rabbit_user = self._args.rabbit_user
        rabbit_password = self._args.rabbit_password
        rabbit_vhost = self._args.rabbit_vhost
        rabbit_ha_mode = self._args.rabbit_ha_mode

        self._db_resync_done = gevent.event.Event()

        q_name = 'schema_transformer.%s' % (socket.gethostname())
        self._vnc_kombu = VncKombuClient(rabbit_servers, rabbit_port,
                                         rabbit_user, rabbit_password,
                                         rabbit_vhost, rabbit_ha_mode,
                                         q_name, self._vnc_subscribe_callback,
                                         self.config_log)
        self._cassandra = SchemaTransformerDB(self, _zookeeper_client)
        DBBaseST.init(self, self._sandesh.logger(), self._cassandra)
        DBBaseST._sandesh = self._sandesh
        DBBaseST._vnc_lib = _vnc_lib
        ServiceChain.init()
        self.reinit()
        # create cpu_info object to send periodic updates
        sysinfo_req = False
        cpu_info = vnc_cpu_info.CpuInfo(
            module_name, instance_id, sysinfo_req, self._sandesh, 60)
        self._cpu_info = cpu_info
        self._db_resync_done.set()
Exemplo n.º 15
0
class VncAmqpHandle(object):
    def __init__(self,
                 sandesh,
                 logger,
                 db_cls,
                 reaction_map,
                 q_name_prefix,
                 rabbitmq_cfg,
                 host_ip,
                 trace_file=None,
                 timer_obj=None,
                 register_handler=True):
        self.sandesh = sandesh
        self.logger = logger
        self.db_cls = db_cls
        self.reaction_map = reaction_map
        self.q_name_prefix = q_name_prefix
        self._db_resync_done = gevent.event.Event()
        self._rabbitmq_cfg = rabbitmq_cfg
        self._trace_file = trace_file
        self.timer = timer_obj
        self.host_ip = host_ip
        self.register_handler = register_handler

    def establish(self):
        q_name = '.'.join([self.q_name_prefix, socket.getfqdn(self.host_ip)])
        self._vnc_kombu = VncKombuClient(
            self._rabbitmq_cfg['servers'],
            self._rabbitmq_cfg['port'],
            self._rabbitmq_cfg['user'],
            self._rabbitmq_cfg['password'],
            self._rabbitmq_cfg['vhost'],
            self._rabbitmq_cfg['ha_mode'],
            q_name,
            self._vnc_subscribe_callback,
            self.logger.log,
            rabbit_use_ssl=self._rabbitmq_cfg['use_ssl'],
            kombu_ssl_version=self._rabbitmq_cfg['ssl_version'],
            kombu_ssl_keyfile=self._rabbitmq_cfg['ssl_keyfile'],
            kombu_ssl_certfile=self._rabbitmq_cfg['ssl_certfile'],
            kombu_ssl_ca_certs=self._rabbitmq_cfg['ssl_ca_certs'],
            register_handler=self.register_handler)

    def msgbus_store_err_msg(self, msg):
        self.msg_tracer.error = msg

    def msgbus_trace_msg(self):
        self.msg_tracer.trace_msg(name='MessageBusNotifyTraceBuf',
                                  sandesh=self.sandesh)

    def log_exception(self):
        string_buf = StringIO()
        cgitb_hook(file=string_buf, format="text")
        self.logger.error(string_buf.getvalue())
        self.msgbus_store_err_msg(string_buf.getvalue())
        if not self._trace_file:
            return
        try:
            with open(self._trace_file, 'a') as err_file:
                err_file.write(string_buf.getvalue())
        except IOError:
            pass

    def _vnc_subscribe_callback(self, oper_info):
        self._db_resync_done.wait()
        try:
            self.oper_info = oper_info
            self.vnc_subscribe_actions()

        except ConnectionError:
            try:
                # retry write during api-server ConnectionError
                self.vnc_subscribe_actions()
            except ConnectionError:
                # log the exception, and exit during api-server
                # ConnectionError on retry to let standby to become active.
                self.log_exception()
                self.logger.error("Api-server connection lost. Exiting")
                self.close()
                raise SystemExit
            except Exception:
                self.log_exception()
        except Exception:
            self.log_exception()
        finally:
            try:
                self.msgbus_trace_msg()
            except Exception:
                pass
            del self.oper_info
            del self.obj_type
            del self.obj_class
            del self.obj
            del self.dependency_tracker

    def create_msgbus_trace(self, request_id, oper, uuid):
        self.msg_tracer = MessageBusNotifyTrace(request_id=request_id,
                                                operation=oper,
                                                uuid=uuid)

    def vnc_subscribe_actions(self):
        msg = "Notification Message: %s" % (pformat(self.oper_info))
        self.logger.debug(msg)

        self.obj = None
        self.dependency_tracker = None
        self.obj_type = self.oper_info['type'].replace('-', '_')
        self.obj_class = self.db_cls.get_obj_type_map().get(self.obj_type)
        if self.obj_class is None:
            return

        oper = self.oper_info['oper']
        obj_id = self.oper_info['uuid']
        self.create_msgbus_trace(self.oper_info.get('request_id'), oper,
                                 obj_id)
        if oper == 'CREATE':
            self.handle_create()
        elif oper == 'UPDATE':
            self.handle_update()
        elif oper == 'DELETE':
            self.handle_delete()
        elif oper == 'UPDATE-IMPLICIT':
            # Ignore this operation
            return
        else:
            self.handle_unknown()
            return
        if self.obj is None:
            self.logger.warning(
                "Object %s uuid %s was not found for operation %s" %
                (self.obj_type, obj_id, oper))
            return
        self.evaluate_dependency()

    def _get_key_from_oper_info(self):
        if self.db_cls._indexed_by_name:
            return ':'.join(self.oper_info['fq_name'])
        return self.oper_info['uuid']

    def handle_create(self):
        obj_key = self._get_key_from_oper_info()
        obj_id = self.oper_info['uuid']
        obj_fq_name = self.oper_info['fq_name']
        self.db_cls._object_db.cache_uuid_to_fq_name_add(
            obj_id, obj_fq_name, self.obj_type)
        self.obj = self.obj_class.locate(obj_key)
        if self.obj is None:
            self.logger.info('%s id %s fq_name %s not found' %
                             (self.obj_type, obj_id, obj_fq_name))
            return
        self.dependency_tracker = DependencyTracker(
            self.db_cls.get_obj_type_map(), self.reaction_map)
        self.dependency_tracker.evaluate(self.obj_type, self.obj)

    def handle_update(self):
        obj_id = self.oper_info['uuid']
        self.obj = self.obj_class.get_by_uuid(obj_id)
        old_dt = None
        if self.obj is not None:
            old_dt = DependencyTracker(self.db_cls.get_obj_type_map(),
                                       self.reaction_map)
            old_dt.evaluate(self.obj_type, self.obj)
        else:
            self.logger.info('%s id %s not found' % (self.obj_type, obj_id))
            return

        try:
            ret = self.obj.update()
            if ret is not None and not ret:
                # If update returns None, the function may not support a
                # return value, hence treat it as if something might have
                # changed. If a value is returned, use its truth value.
                # If it True, then some change was detected.
                # If no change, then terminate dependency tracker
                return
        except NoIdError:
            obj_id = self.oper_info['uuid']
            self.logger.warning('%s uuid %s update caused NoIdError' %
                                (self.obj_type, obj_id))
            return

        self.dependency_tracker = DependencyTracker(
            self.db_cls.get_obj_type_map(), self.reaction_map)
        self.dependency_tracker.evaluate(self.obj_type, self.obj)
        if old_dt:
            for resource, ids in list(old_dt.resources.items()):
                if resource not in self.dependency_tracker.resources:
                    self.dependency_tracker.resources[resource] = ids
                else:
                    self.dependency_tracker.resources[resource] = list(
                        set(self.dependency_tracker.resources[resource])
                        | set(ids))

    def handle_delete(self):
        obj_id = self.oper_info['uuid']
        self.obj = self.obj_class.get_by_uuid(obj_id)
        self.db_cls._object_db.cache_uuid_to_fq_name_del(obj_id)
        if self.obj is None:
            return
        self.dependency_tracker = DependencyTracker(
            self.db_cls.get_obj_type_map(), self.reaction_map)
        self.dependency_tracker.evaluate(self.obj_type, self.obj)
        obj_key = self._get_key_from_oper_info()
        self.obj_class.delete(obj_key)

    def handle_unknown(self):
        # unknown operation
        self.logger.error('Unknown operation %s' % self.oper_info['oper'])

    def init_msgbus_fq_name(self):
        self.msg_tracer.fq_name = self.obj.name

    def init_msgbus_dtr(self):
        self.msg_tracer.dependency_tracker_resources = []

    def add_msgbus_dtr(self, res_type, res_id_list):
        dtr = DependencyTrackerResource(obj_type=res_type,
                                        obj_keys=res_id_list)
        self.msg_tracer.dependency_tracker_resources.append(dtr)

    def evaluate_dependency(self):
        if not self.dependency_tracker:
            return

        self.init_msgbus_fq_name()
        self.init_msgbus_dtr()

        evaluate_kwargs = {}
        if self.timer and self.timer.yield_in_evaluate:
            evaluate_kwargs['timer'] = self.timer

        for res_type, res_id_list in list(
                self.dependency_tracker.resources.items()):
            if not res_id_list:
                continue
            self.add_msgbus_dtr(res_type, res_id_list)
            cls = self.db_cls.get_obj_type_map().get(res_type)
            if cls is None:
                continue
            for res_id in res_id_list:
                res_obj = cls.get(res_id)
                if res_obj is not None:
                    if evaluate_kwargs:
                        res_obj.evaluate(**evaluate_kwargs)
                    else:
                        res_obj.evaluate()
                    if self.timer:
                        self.timer.timed_yield()

    def close(self):
        self._vnc_kombu.shutdown()
Exemplo n.º 16
0
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'],
            'floating_ip': ['virtual_machine', 'port_tuple'],
            'virtual_machine': [],
            'port_tuple': [],
            'bgp_as_a_service': [],
        },
        'virtual_network': {
            'self': ['network_policy'],
            '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'],
            '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'],
        },
        'logical_router': {
            'self': [],
            'virtual_machine_interface': [],
        },
        'floating_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])

        self._sandesh = Sandesh()
        # Reset the sandesh send rate limit value
        if args.sandesh_send_rate_limit is not None:
            SandeshSystem.set_sandesh_send_rate_limit(
                args.sandesh_send_rate_limit)
        sandesh.VnList.handle_request = self.sandesh_vn_handle_request
        sandesh.RoutintInstanceList.handle_request = \
            self.sandesh_ri_handle_request
        sandesh.ServiceChainList.handle_request = \
            self.sandesh_sc_handle_request
        sandesh.StObjectReq.handle_request = \
            self.sandesh_st_object_handle_request
        module = Module.SCHEMA_TRANSFORMER
        module_name = ModuleNames[module]
        node_type = Module2NodeType[module]
        node_type_name = NodeTypeNames[node_type]
        instance_id = INSTANCE_ID_DEFAULT
        hostname = socket.gethostname()
        self._sandesh.init_generator(
            module_name, hostname, node_type_name, instance_id,
            self._args.collectors, 'to_bgp_context',
            int(args.http_server_port),
            ['cfgm_common', 'schema_transformer.sandesh'], self._disc,
            logger_class=args.logger_class,
            logger_config_file=args.logging_conf)
        self._sandesh.set_logging_params(enable_local_log=args.log_local,
                                    category=args.log_category,
                                    level=args.log_level,
                                    file=args.log_file,
                                    enable_syslog=args.use_syslog,
                                    syslog_facility=args.syslog_facility)
        ConnectionState.init(self._sandesh, hostname, module_name, instance_id,
                staticmethod(ConnectionState.get_process_state_cb),
                NodeStatusUVE, NodeStatus)

        self._sandesh.trace_buffer_create(name="MessageBusNotifyTraceBuf",
                                          size=1000)

        rabbit_servers = self._args.rabbit_server
        rabbit_port = self._args.rabbit_port
        rabbit_user = self._args.rabbit_user
        rabbit_password = self._args.rabbit_password
        rabbit_vhost = self._args.rabbit_vhost
        rabbit_ha_mode = self._args.rabbit_ha_mode

        self._db_resync_done = gevent.event.Event()

        q_name = 'schema_transformer.%s' % (socket.gethostname())
        self._vnc_kombu = VncKombuClient(rabbit_servers, rabbit_port,
                                         rabbit_user, rabbit_password,
                                         rabbit_vhost, rabbit_ha_mode,
                                         q_name, self._vnc_subscribe_callback,
                                         self.config_log)
        self._cassandra = SchemaTransformerDB(self, _zookeeper_client)
        DBBaseST.init(self, self._sandesh.logger(), self._cassandra)
        DBBaseST._sandesh = self._sandesh
        DBBaseST._vnc_lib = _vnc_lib
        ServiceChain.init()
        self.reinit()
        # create cpu_info object to send periodic updates
        sysinfo_req = False
        cpu_info = vnc_cpu_info.CpuInfo(
            module_name, instance_id, sysinfo_req, self._sandesh, 60)
        self._cpu_info = cpu_info
        self._db_resync_done.set()

    # end __init__

    def config_log(self, msg, level):
        self._sandesh.logger().log(SandeshLogger.get_py_logger_level(level),
                                   msg)

    def _vnc_subscribe_callback(self, oper_info):
        self._db_resync_done.wait()
        dependency_tracker = None
        try:
            msg = "Notification Message: %s" % (pformat(oper_info))
            self.config_log(msg, level=SandeshLevel.SYS_DEBUG)
            obj_type = oper_info['type'].replace('-', '_')
            obj_class = DBBaseST.get_obj_type_map().get(obj_type)
            if obj_class is None:
                return

            oper = oper_info['oper']
            obj_id = oper_info['uuid']
            notify_trace = MessageBusNotifyTrace(
                request_id=oper_info.get('request_id'),
                operation=oper, uuid=obj_id)
            if oper == 'CREATE':
                obj_dict = oper_info['obj_dict']
                obj_fq_name = ':'.join(obj_dict['fq_name'])
                obj = obj_class.locate(obj_fq_name)
                if obj is None:
                    self.config_log('%s id %s fq_name %s not found' % (
                                    obj_type, obj_id, obj_fq_name),
                                    level=SandeshLevel.SYS_INFO)
                    return
                dependency_tracker = DependencyTracker(
                    DBBaseST.get_obj_type_map(), self._REACTION_MAP)
                dependency_tracker.evaluate(obj_type, obj)
            elif oper == 'UPDATE':
                obj = obj_class.get_by_uuid(obj_id)
                old_dt = None
                if obj is not None:
                    old_dt = DependencyTracker(
                        DBBaseST.get_obj_type_map(), self._REACTION_MAP)
                    old_dt.evaluate(obj_type, obj)
                else:
                    self.config_log('%s id %s not found' % (obj_type, obj_id),
                                    level=SandeshLevel.SYS_INFO)
                    return
                try:
                    obj.update()
                except NoIdError:
                    self.config_log('%s id %s update caused NoIdError' % (obj_type, obj_id),
                                    level=SandeshLevel.SYS_INFO)
                    return
                dependency_tracker = DependencyTracker(
                    DBBaseST.get_obj_type_map(), self._REACTION_MAP)
                dependency_tracker.evaluate(obj_type, obj)
                if old_dt:
                    for resource, ids in old_dt.resources.items():
                        if resource not in dependency_tracker.resources:
                            dependency_tracker.resources[resource] = ids
                        else:
                            dependency_tracker.resources[resource] = list(
                                set(dependency_tracker.resources[resource]) |
                                set(ids))
            elif oper == 'DELETE':
                obj = obj_class.get_by_uuid(obj_id)
                if obj is None:
                    return
                dependency_tracker = DependencyTracker(
                    DBBaseST.get_obj_type_map(), self._REACTION_MAP)
                dependency_tracker.evaluate(obj_type, obj)
                obj_class.delete(obj.name)
            else:
                # unknown operation
                self.config_log('Unknown operation %s' % oper,
                                level=SandeshLevel.SYS_ERR)
                return

            if obj is None:
                self.config_log('Error while accessing %s uuid %s' % (
                                obj_type, obj_id))
                return

            notify_trace.fq_name = obj.name
            if not dependency_tracker:
                return

            notify_trace.dependency_tracker_resources = []
            for res_type, res_id_list in dependency_tracker.resources.items():
                if not res_id_list:
                    continue
                dtr = DependencyTrackerResource(obj_type=res_type, obj_keys=res_id_list)
                notify_trace.dependency_tracker_resources.append(dtr)
                cls = DBBaseST.get_obj_type_map().get(res_type)
                if cls is None:
                    continue
                for res_id in res_id_list:
                    res_obj = cls.get(res_id)
                    if res_obj is not None:
                        res_obj.evaluate()

            for vn_id in dependency_tracker.resources.get('virtual_network', []):
                vn = VirtualNetworkST.get(vn_id)
                if vn is not None:
                    vn.uve_send()
            # end for vn_id
        except Exception as e:
            string_buf = cStringIO.StringIO()
            cgitb_hook(file=string_buf, format="text")
            notify_trace.error = string_buf.getvalue()
            try:
                with open(self._args.trace_file, 'a') as err_file:
                    err_file.write(string_buf.getvalue())
            except IOError:
                self.config_log(string_buf.getvalue(), level=SandeshLevel.SYS_ERR)
        finally:
            try:
                notify_trace.trace_msg(name='MessageBusNotifyTraceBuf',
                                       sandesh=self._sandesh)
            except Exception:
                pass


    # end _vnc_subscribe_callback

    # Clean up stale objects
    def reinit(self):
        GlobalSystemConfigST.reinit()
        BgpRouterST.reinit()
        LogicalRouterST.reinit()
        vn_list = list(VirtualNetworkST.list_vnc_obj())
        vn_id_list = [vn.uuid for vn in vn_list]
        ri_dict = {}
        service_ri_dict = {}
        for ri in DBBaseST.list_vnc_obj('routing_instance'):
            delete = False
            if ri.parent_uuid not in vn_id_list:
                delete = True
            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._sandesh._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._sandesh._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:
            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()

        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()
    # end process_stale_objects

    def sandesh_ri_build(self, vn_name, ri_name):
        vn = VirtualNetworkST.get(vn_name)
        sandesh_ri_list = []
        for riname in vn.routing_instances:
            ri = RoutingInstanceST.get(riname)
            sandesh_ri = sandesh.RoutingInstance(name=ri.obj.get_fq_name_str())
            sandesh_ri.service_chain = ri.service_chain
            sandesh_ri.connections = list(ri.connections)
            sandesh_ri_list.append(sandesh_ri)
        return sandesh_ri_list
    # end sandesh_ri_build

    def sandesh_ri_handle_request(self, req):
        # Return the list of VNs
        ri_resp = sandesh.RoutingInstanceListResp(routing_instances=[])
        if req.vn_name is None:
            for vn in VirtualNetworkST:
                sandesh_ri = self.sandesh_ri_build(vn, req.ri_name)
                ri_resp.routing_instances.extend(sandesh_ri)
        elif req.vn_name in VirtualNetworkST:
            self.sandesh_ri_build(req.vn_name, req.ri_name)
            ri_resp.routing_instances.extend(sandesh_ri)
        ri_resp.response(req.context())
    # end sandesh_ri_handle_request

    def sandesh_vn_build(self, vn_name):
        vn = VirtualNetworkST.get(vn_name)
        sandesh_vn = sandesh.VirtualNetwork(name=vn_name)
        sandesh_vn.policies = vn.network_policys.keys()
        sandesh_vn.connections = list(vn.connections)
        sandesh_vn.routing_instances = vn.routing_instances
        if vn.acl:
            sandesh_vn.acl = vn.acl.get_fq_name_str()
        if vn.dynamic_acl:
            sandesh_vn.dynamic_acl = vn.dynamic_acl.get_fq_name_str()

        return sandesh_vn
    # end sandesh_vn_build

    def sandesh_vn_handle_request(self, req):
        # Return the list of VNs
        vn_resp = sandesh.VnListResp(vn_names=[])
        if req.vn_name is None:
            for vn in VirtualNetworkST:
                sandesh_vn = self.sandesh_vn_build(vn)
                vn_resp.vn_names.append(sandesh_vn)
        elif req.vn_name in VirtualNetworkST:
            sandesh_vn = self.sandesh_vn_build(req.vn_name)
            vn_resp.vn_names.append(sandesh_vn)
        vn_resp.response(req.context())
    # end sandesh_vn_handle_request

    def sandesh_sc_handle_request(self, req):
        sc_resp = sandesh.ServiceChainListResp(service_chains=[])
        if req.sc_name is None:
            for sc in ServiceChain.values():
                sandesh_sc = sc.build_introspect()
                sc_resp.service_chains.append(sandesh_sc)
        elif req.sc_name in ServiceChain:
            sandesh_sc = ServiceChain[req.sc_name].build_introspect()
            sc_resp.service_chains.append(sandesh_sc)
        sc_resp.response(req.context())
    # end sandesh_sc_handle_request

    def sandesh_st_object_handle_request(self, req):
        st_resp = sandesh.StObjectListResp(objects=[])
        obj_type_map = DBBaseST.get_obj_type_map()
        if req.object_type is not None:
            if req.object_type not in obj_type_map:
                return st_resp
            obj_cls_list = [obj_type_map[req.object_type]]
        else:
            obj_cls_list = obj_type_map.values()
        for obj_cls in obj_cls_list:
            id_or_name = req.object_id_or_fq_name
            if id_or_name:
                obj = obj_cls.get(id_or_name) or obj_cls.get_by_uuid(id_or_name)
                if obj is None:
                    continue
                st_resp.objects.append(obj.handle_st_object_req())
            else:
                for obj in obj_cls.values():
                    st_resp.objects.append(obj.handle_st_object_req())
        st_resp.response(req.context())
    # end sandesh_st_object_handle_request

    def reset(self):
        for cls in DBBaseST.get_obj_type_map().values():
            cls.reset()
        self._vnc_kombu.shutdown()
Exemplo n.º 17
0
    def __init__(self, args=None):
        self._args = args

        # 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.DEVICE_MANAGER])

        self._sandesh = Sandesh()
        module = Module.DEVICE_MANAGER
        module_name = ModuleNames[module]
        node_type = Module2NodeType[module]
        node_type_name = NodeTypeNames[node_type]
        instance_id = INSTANCE_ID_DEFAULT
        hostname = socket.gethostname()
        self._sandesh.init_generator(module_name, hostname, node_type_name,
                                     instance_id, self._args.collectors,
                                     'to_bgp_context',
                                     int(args.http_server_port),
                                     ['cfgm_common', 'device_manager.sandesh'],
                                     self._disc)
        self._sandesh.set_logging_params(enable_local_log=args.log_local,
                                         category=args.log_category,
                                         level=args.log_level,
                                         file=args.log_file,
                                         enable_syslog=args.use_syslog,
                                         syslog_facility=args.syslog_facility)
        ConnectionState.init(
            self._sandesh, hostname, module_name, instance_id,
            staticmethod(ConnectionState.get_process_state_cb), NodeStatusUVE,
            NodeStatus)

        # Retry till API server is up
        connected = False
        self.connection_state_update(ConnectionStatus.INIT)
        while not connected:
            try:
                self._vnc_lib = VncApi(args.admin_user, args.admin_password,
                                       args.admin_tenant_name,
                                       args.api_server_ip,
                                       args.api_server_port)
                connected = True
                self.connection_state_update(ConnectionStatus.UP)
            except requests.exceptions.ConnectionError as e:
                # Update connection info
                self.connection_state_update(ConnectionStatus.DOWN, str(e))
                time.sleep(3)
            except ResourceExhaustionError:  # haproxy throws 503
                time.sleep(3)

        rabbit_servers = self._args.rabbit_server
        rabbit_port = self._args.rabbit_port
        rabbit_user = self._args.rabbit_user
        rabbit_password = self._args.rabbit_password
        rabbit_vhost = self._args.rabbit_vhost
        rabbit_ha_mode = self._args.rabbit_ha_mode

        self._db_resync_done = gevent.event.Event()

        q_name = 'device_manager.%s' % (socket.gethostname())
        self._vnc_kombu = VncKombuClient(rabbit_servers, rabbit_port,
                                         rabbit_user, rabbit_password,
                                         rabbit_vhost, rabbit_ha_mode, q_name,
                                         self._vnc_subscribe_callback,
                                         self.config_log)

        cass_server_list = self._args.cassandra_server_list
        reset_config = self._args.reset_config
        self._cassandra = VncCassandraClient(cass_server_list, reset_config,
                                             self._args.cluster_id, None,
                                             self.config_log)

        DBBase.init(self, self._sandesh.logger(), self._cassandra)
        ok, pr_list = self._cassandra._cassandra_physical_router_list()
        if not ok:
            self.config_log('physical router list returned error: %s' %
                            pr_list)
        else:
            vn_set = set()
            for fq_name, uuid in pr_list:
                pr = PhysicalRouterDM.locate(uuid)
                if pr.bgp_router:
                    BgpRouterDM.locate(pr.bgp_router)
                vn_set |= pr.virtual_networks
                li_set = pr.logical_interfaces
                for pi_id in pr.physical_interfaces:
                    pi = PhysicalInterfaceDM.locate(pi_id)
                    if pi:
                        li_set |= pi.logical_interfaces
                vmi_set = set()
                for li_id in li_set:
                    li = LogicalInterfaceDM.locate(li_id)
                    if li and li.virtual_machine_interface:
                        vmi_set |= set([li.virtual_machine_interface])
                for vmi_id in vmi_set:
                    vmi = VirtualMachineInterfaceDM.locate(vmi_id)
                    if vmi:
                        vn_set |= set([vmi.virtual_network])

            for vn_id in vn_set:
                VirtualNetworkDM.locate(vn_id)

            for pr in PhysicalRouterDM.values():
                pr.push_config()
        self._db_resync_done.set()
        while 1:
            # Just wait indefinitely
            time.sleep(5)