def _notify_loop(resource, event, trigger, **kwargs): """The notification loop.""" errors = [] callbacks = kwargs.pop('callbacks', None) if not callbacks: callbacks = list( registry._get_callback_manager()._callbacks[resource].get( event, {}).items()) LOG.debug("Notify callbacks %s for %s, %s", callbacks, resource, event) for callback_id, callback in callbacks: try: callback(resource, event, trigger, **kwargs) except Exception as e: abortable_event = (event.startswith(events.BEFORE) or event.startswith(events.PRECOMMIT)) if not abortable_event: LOG.exception( "Error during notification for " "%(callback)s %(resource)s, %(event)s", { 'callback': callback_id, 'resource': resource, 'event': event }) else: LOG.error("Callback %(callback)s raised %(error)s", { 'callback': callback_id, 'error': e }) errors.append(exceptions.NotificationError(callback_id, e)) return errors
def _setUp(self): self._orig_manager = registry._get_callback_manager() self.patcher = mock.patch.object(registry, '_get_callback_manager', return_value=self.callback_manager) self.patcher.start() self.addCleanup(self._restore)
def _notify_loop(resource, event, trigger, **kwargs): """The notification loop.""" errors = [] callbacks = kwargs.pop('callbacks', None) if not callbacks: callbacks = list(registry._get_callback_manager()._callbacks[ resource].get(event, {}).items()) LOG.debug("Notify callbacks %s for %s, %s", callbacks, resource, event) for callback_id, callback in callbacks: try: callback(resource, event, trigger, **kwargs) except Exception as e: abortable_event = ( event.startswith(events.BEFORE) or event.startswith(events.PRECOMMIT) ) if not abortable_event: LOG.exception("Error during notification for " "%(callback)s %(resource)s, %(event)s", {'callback': callback_id, 'resource': resource, 'event': event}) else: LOG.error("Callback %(callback)s raised %(error)s", {'callback': callback_id, 'error': e}) errors.append(exceptions.NotificationError(callback_id, e)) return errors
def __init__(self): LOG.info("Ml2Plus initializing") registry._get_callback_manager()._notify_loop = ( patch_neutron._notify_loop) # First load drivers, then initialize DB, then initialize drivers self.type_manager = ml2_managers.TypeManager() self.extension_manager = managers.ExtensionManager() self.mechanism_manager = managers.MechanismManager() super(ml2_plugin.Ml2Plugin, self).__init__() self.type_manager.initialize() self.extension_manager.initialize() self.mechanism_manager.initialize() registry.subscribe(self._port_provisioned, resources.PORT, provisioning_blocks.PROVISIONING_COMPLETE) registry.subscribe(self._handle_segment_change, resources.SEGMENT, events.PRECOMMIT_CREATE) registry.subscribe(self._handle_segment_change, resources.SEGMENT, events.PRECOMMIT_DELETE) registry.subscribe(self._handle_segment_change, resources.SEGMENT, events.AFTER_CREATE) registry.subscribe(self._handle_segment_change, resources.SEGMENT, events.AFTER_DELETE) # REVISIT(kent): All the postcommit calls for SG and SG rules are not # currently implemented as they are not needed at this moment. registry.subscribe(self._handle_security_group_change, resources.SECURITY_GROUP, events.PRECOMMIT_CREATE) registry.subscribe(self._handle_security_group_change, resources.SECURITY_GROUP, events.PRECOMMIT_DELETE) registry.subscribe(self._handle_security_group_change, resources.SECURITY_GROUP, events.PRECOMMIT_UPDATE) # There is no update event to the security_group_rule registry.subscribe(self._handle_security_group_rule_change, resources.SECURITY_GROUP_RULE, events.PRECOMMIT_CREATE) registry.subscribe(self._handle_security_group_rule_change, resources.SECURITY_GROUP_RULE, events.PRECOMMIT_DELETE) try: registry.subscribe(self._subnet_delete_precommit_handler, resources.SUBNET, events.PRECOMMIT_DELETE) registry.subscribe(self._subnet_delete_after_delete_handler, resources.SUBNET, events.AFTER_DELETE) except AttributeError: LOG.info("Detected older version of Neutron, ML2Plus plugin " "is not subscribed to subnet_precommit_delete and " "subnet_after_delete events") self._setup_dhcp() self._start_rpc_notifiers() self.add_agent_status_check_worker(self.agent_health_check) self._verify_service_plugins_requirements() LOG.info("Modular L2 Plugin (extended) initialization complete")
def __init__(self): LOG.info("Ml2Plus initializing") registry._get_callback_manager()._notify_loop = ( patch_neutron._notify_loop) # First load drivers, then initialize DB, then initialize drivers self.type_manager = ml2_managers.TypeManager() self.extension_manager = managers.ExtensionManager() self.mechanism_manager = managers.MechanismManager() super(ml2_plugin.Ml2Plugin, self).__init__() self.type_manager.initialize() self.extension_manager.initialize() self.mechanism_manager.initialize() registry.subscribe(self._port_provisioned, resources.PORT, provisioning_blocks.PROVISIONING_COMPLETE) registry.subscribe(self._handle_segment_change, resources.SEGMENT, events.PRECOMMIT_CREATE) registry.subscribe(self._handle_segment_change, resources.SEGMENT, events.PRECOMMIT_DELETE) registry.subscribe(self._handle_segment_change, resources.SEGMENT, events.AFTER_CREATE) registry.subscribe(self._handle_segment_change, resources.SEGMENT, events.AFTER_DELETE) # REVISIT(kent): All the postcommit calls for SG and SG rules are not # currently implemented as they are not needed at this moment. registry.subscribe(self._handle_security_group_change, resources.SECURITY_GROUP, events.PRECOMMIT_CREATE) registry.subscribe(self._handle_security_group_change, resources.SECURITY_GROUP, events.PRECOMMIT_DELETE) registry.subscribe(self._handle_security_group_change, resources.SECURITY_GROUP, events.PRECOMMIT_UPDATE) # There is no update event to the security_group_rule registry.subscribe(self._handle_security_group_rule_change, resources.SECURITY_GROUP_RULE, events.PRECOMMIT_CREATE) registry.subscribe(self._handle_security_group_rule_change, resources.SECURITY_GROUP_RULE, events.PRECOMMIT_DELETE) try: registry.subscribe(self._subnet_delete_precommit_handler, resources.SUBNET, events.PRECOMMIT_DELETE) registry.subscribe(self._subnet_delete_after_delete_handler, resources.SUBNET, events.AFTER_DELETE) except AttributeError: LOG.info("Detected older version of Neutron, ML2Plus plugin " "is not subscribed to subnet_precommit_delete and " "subnet_after_delete events") self._setup_dhcp() self._start_rpc_notifiers() self.add_agent_status_check_worker(self.agent_health_check) self._verify_service_plugins_requirements() LOG.info("Modular L2 Plugin (extended) initialization complete")
def send_or_queue_notification(session, transaction_key, notifier_obj, notifier_method, args): rname = '' if notifier_method == NOVA_NOTIFIER_METHOD: # parse argument like "create_subnetpool" rname = args[0].split('_', 1)[1] event_name = 'after_' + args[0].split('_')[0] registry_method = getattr(notifier_obj, '_send_nova_notification') elif notifier_method == DHCP_NOTIFIER_METHOD: # parse argument like "subnetpool.create.end" rname = args[2].split('.')[0] event_name = 'after_' + args[2].split('.')[1] registry_method = getattr(notifier_obj, '_native_event_send_dhcp_notification') if rname: cbacks = registry._get_callback_manager()._callbacks.get(rname, None) if cbacks and event_name in cbacks.keys(): for entry in cbacks.values(): method = entry.values()[0] if registry_method == method: # This notification is already being sent by Neutron # soe we will avoid sending a duplicate notification return if not transaction_key or 'subnet.delete.end' in args or ( not QUEUE_OUT_OF_PROCESS_NOTIFICATIONS): # We make an exception for the dhcp agent notification # for port and subnet delete since the implementation # for sending that notification checks for the existence # of the associated network, which is not present in certain # cases if the delete notification is queued and sent after # the network delete. getattr(notifier_obj, notifier_method)(*args) return _queue_notification(session, transaction_key, notifier_obj, notifier_method, args)
def send_or_queue_notification(session, transaction_key, notifier_obj, notifier_method, args): rname = '' if notifier_method == NOVA_NOTIFIER_METHOD: # parse argument like "create_subnetpool" rname = args[0].split('_', 1)[1] event_name = 'after_' + args[0].split('_')[0] registry_method = getattr(notifier_obj, '_send_nova_notification') elif notifier_method == DHCP_NOTIFIER_METHOD: # parse argument like "subnetpool.create.end" rname = args[2].split('.')[0] event_name = 'after_' + args[2].split('.')[1] registry_method = getattr(notifier_obj, '_native_event_send_dhcp_notification') if rname: cbacks = registry._get_callback_manager()._callbacks.get(rname, None) if cbacks and event_name in cbacks.keys(): for entry in cbacks.values(): method = entry.values()[0] if registry_method == method: # This notification is already being sent by Neutron # soe we will avoid sending a duplicate notification return if not transaction_key or 'subnet.delete.end' in args or ( not QUEUE_OUT_OF_PROCESS_NOTIFICATIONS): # We make an exception for the dhcp agent notification # for port and subnet delete since the implementation # for sending that notification checks for the existence # of the associated network, which is not present in certain # cases if the delete notification is queued and sent after # the network delete. getattr(notifier_obj, notifier_method)(*args) return _queue_notification(session, transaction_key, notifier_obj, notifier_method, args)
def _registry_notify(resource, event, trigger, **kwargs): # This invokes neutron's original (unpatched) registry notification # method. registry._get_callback_manager().notify(resource, event, trigger, **kwargs)
def _get_callbacks_for_resource_event(resource, event): return list(registry._get_callback_manager()._callbacks[resource].get( event, {}).items())
def _test_resource_with_errors(self, res_name, op, **kwargs): # Must call the internal notify_loop in order to get the errors return registry._get_callback_manager()._notify_loop( res_name, op, 'nsxadmin', **kwargs)
"Error during notification for " "%(callback)s %(resource)s, %(event)s", { 'callback': callback_id, 'resource': resource, 'event': event }) else: LOG.error("Callback %(callback)s raised %(error)s", { 'callback': callback_id, 'error': e }) errors.append(exceptions.NotificationError(callback_id, e)) return errors original_notify_loop = registry._get_callback_manager()._notify_loop from inspect import isclass from inspect import isfunction from inspect import ismethod # The undecorated() and looks_like_a_decorator() functions have been # borrowed from the undecorated python library since RPM or Debian # packages are not readily available. def looks_like_a_decorator(a): return (isfunction(a) or ismethod(a) or isclass(a)) def undecorated(o): """Remove all decorators from a function, method or class"""
event.startswith(events.BEFORE) or event.startswith(events.PRECOMMIT) ) if not abortable_event: LOG.exception("Error during notification for " "%(callback)s %(resource)s, %(event)s", {'callback': callback_id, 'resource': resource, 'event': event}) else: LOG.error("Callback %(callback)s raised %(error)s", {'callback': callback_id, 'error': e}) errors.append(exceptions.NotificationError(callback_id, e)) return errors original_notify_loop = registry._get_callback_manager()._notify_loop from inspect import isclass from inspect import isfunction from inspect import ismethod # The undecorated() and looks_like_a_decorator() functions have been # borrowed from the undecorated python library since RPM or Debian # packages are not readily available. def looks_like_a_decorator(a): return ( isfunction(a) or ismethod(a) or isclass(a) )
def _delete_loaded_qos_drivers(self): registry._get_callback_manager().clear() for idx, _ in enumerate(self._loaded_qos_drivers): del self._loaded_qos_drivers[idx]
def _registry_notify(resource, event, trigger, **kwargs): # This invokes neutron's original (unpatched) registry notification # method. registry._get_callback_manager().notify( resource, event, trigger, **kwargs)
def _get_callbacks_for_resource_event(resource, event): return list(registry._get_callback_manager()._callbacks[ resource].get(event, {}).items())