def _sg_callback(self, callback, resource, event, trigger, **kwargs): if 'payload' in kwargs: # TODO(boden): remove shim once all callbacks use payloads context = kwargs['payload'].context res = kwargs['payload'].desired_state res_id = kwargs['payload'].resource_id copy_kwargs = kwargs else: context = kwargs['context'] res = kwargs.get(resource) res_id = kwargs.get("%s_id" % resource) copy_kwargs = kwargs.copy() copy_kwargs.pop('context') if res_id is None: res_id = res.get('id') odl_res_type = _RESOURCE_MAPPING[resource] odl_ops = _OPERATION_MAPPING[event] odl_res_dict = None if res is None else {odl_res_type.singular: res} _log_on_callback(logging.DEBUG, "Calling callback", odl_ops, odl_res_type, res_id, odl_res_dict, copy_kwargs) try: callback(context, odl_ops, odl_res_type, res_id, odl_res_dict, **copy_kwargs) except Exception as e: # In case of precommit, neutron registry notification caller # doesn't log its exception. In networking-odl case, we don't # normally throw exception. So log it here for debug with excutils.save_and_reraise_exception(): if not db_api.is_retriable(e): _log_on_callback(logging.ERROR, "Exception from callback", odl_ops, odl_res_type, res_id, odl_res_dict, copy_kwargs)
def _call_drivers(self, method_name, context, raise_orig_exc=False): for driver in self.ordered_drivers: try: getattr(driver.obj, method_name)(context) except Exception as e: # This is an internal failure. if db_api.is_retriable(e): with excutils.save_and_reraise_exception(): LOG.debug( "DB exception raised by extension driver " "'%(name)s' in %(method)s", { 'name': driver.name, 'method': method_name }, exc_info=e) LOG.exception(e) LOG.error( "%(plugin)s driver '%(name)s' " "failed in %(method)s", { 'name': driver.name, 'method': method_name, 'plugin': name }) if raise_orig_exc: raise else: raise exception(method=method_name)
def _call_on_dict_driver(self, method_name, session, base_model, result, extended_only=False, has_base_model=True): # Bulk operations might not be implemented by all drivers def noop(*args, **kwargs): pass for driver in self.ordered_ext_drivers: if not extended_only or isinstance( driver.obj, driver_api.ExtensionDriver): try: if not has_base_model: getattr(driver.obj, method_name, noop)(session, result) else: getattr(driver.obj, method_name, noop)(session, base_model, result) except Exception as e: if db_api.is_retriable(e): with excutils.save_and_reraise_exception(): LOG.debug( "DB exception raised by extension driver " "'%(name)s' in %(method)s", {'name': driver.name, 'method': method_name}, exc_info=e) LOG.exception( "Extension driver '%(name)s' failed in %(method)s", {'name': driver.name, 'method': method_name}) raise ml2_exc.ExtensionDriverError(driver=driver.name)
def _build_topology(self, context, tenant_id, default_external_network): """Build the network topology and returns its network UUID.""" network_id = None router_id = None subnets = None try: subnets = self._provision_tenant_private_network( context, tenant_id) network_id = subnets[0]['network_id'] router = self._provision_external_connectivity( context, default_external_network, subnets, tenant_id) network_id = self._save(context, tenant_id, network_id, router['id'], subnets) return network_id except Exception as e: with excutils.save_and_reraise_exception(): # FIXME(armax): defensively catch all errors and let # the caller retry the operation, if it can be retried. # This catch-all should no longer be necessary once # bug #1612798 is solved; any other error should just # surface up to the user and be dealt with as a bug. if db_api.is_retriable(e): self._cleanup(context, network_id=network_id, router_id=router_id, subnets=subnets)
def _call_on_dict_driver(self, method_name, session, base_model, result, extended_only=False): for driver in self.ordered_ext_drivers: if not extended_only or isinstance(driver.obj, driver_api.ExtensionDriver): try: getattr(driver.obj, method_name)(session, base_model, result) except Exception as e: if db_api.is_retriable(e): with excutils.save_and_reraise_exception(): LOG.debug( "DB exception raised by extension driver " "'%(name)s' in %(method)s", { 'name': driver.name, 'method': method_name }, exc_info=e) LOG.exception( "Extension driver '%(name)s' failed in %(method)s", { 'name': driver.name, 'method': method_name }) raise ml2_exc.ExtensionDriverError(driver=driver.name)
def extend_address_scope_dict(self, session, base_model, result): try: self._md.extend_address_scope_dict(session, base_model, result) except Exception as e: with excutils.save_and_reraise_exception(): if db_api.is_retriable(e): LOG.debug("APIC AIM extend_address_scope_dict got " "retriable exception: %s", type(e)) else: LOG.exception("APIC AIM extend_address_scope_dict failed")
def extend_network_dict_bulk(self, session, results): try: self._md.extend_network_dict_bulk(session, results) except Exception as e: with excutils.save_and_reraise_exception(): if db_api.is_retriable(e): LOG.debug("APIC AIM extend_network_dict got retriable " "exception: %s", type(e)) else: LOG.exception("APIC AIM extend_network_dict failed")
def extend_subnet_dict(self, session, base_model, result): try: self._md.extend_subnet_dict(session, base_model, result) res_dict = self.get_subnet_extn_db(session, result['id']) result[cisco_apic.SNAT_HOST_POOL] = ( res_dict.get(cisco_apic.SNAT_HOST_POOL, False)) except Exception as e: with excutils.save_and_reraise_exception(): if db_api.is_retriable(e): LOG.debug("APIC AIM extend_subnet_dict got retriable " "exception: %s", type(e)) else: LOG.exception("APIC AIM extend_subnet_dict failed")
def _call_on_drivers(self, method_name, context, continue_on_failure=False): """Helper method for calling a method across all policy drivers. :param method_name: name of the method to call :param context: context parameter to pass to each method call :param continue_on_failure: whether or not to continue to call all policy drivers once one has raised an exception :raises: neutron.services.group_policy.common.GroupPolicyDriverError if any policy driver call fails. """ error = False drivers = (self.ordered_policy_drivers if not method_name.startswith('delete') else self.reverse_ordered_policy_drivers) for driver in drivers: try: getattr(driver.obj, method_name)(context) except Exception as e: if db_api.is_retriable(e): with excutils.save_and_reraise_exception(): LOG.debug( "Policy driver '%(name)s' failed in" " %(method)s, operation will be retried", { 'name': driver.name, 'method': method_name }) elif isinstance(e, gp_exc.GroupPolicyException) or isinstance( e, n_exc.NeutronException) or isinstance( e, oslo_policy.PolicyNotAuthorized): with excutils.save_and_reraise_exception(): LOG.exception( _LE("Policy driver '%(name)s' failed in" " %(method)s"), { 'name': driver.name, 'method': method_name }) else: error = True # We are eating a non-GBP/non-Neutron exception here LOG.exception( _LE("Policy driver '%(name)s' failed in %(method)s"), { 'name': driver.name, 'method': method_name }) if not continue_on_failure: break if error: raise gp_exc.GroupPolicyDriverError(method=method_name)
def ensure_tenant(self, plugin_context, tenant_id): for driver in self.ordered_mech_drivers: if isinstance(driver.obj, driver_api.MechanismDriver): try: driver.obj.ensure_tenant(plugin_context, tenant_id) except Exception as e: if db_api.is_retriable(e): with excutils.save_and_reraise_exception(): LOG.debug("DB exception raised by Mechanism " "driver '%(name)s' in ensure_tenant", {'name': driver.name}, exc_info=e) LOG.exception("Mechanism driver '%s' failed in " "ensure_tenant", driver.name) raise ml2_exc.MechanismDriverError(method="ensure_tenant")
def ensure_tenant(self, plugin_context, tenant_id): for driver in self.ordered_policy_drivers: if isinstance(driver.obj, api.PolicyDriver): try: driver.obj.ensure_tenant(plugin_context, tenant_id) except Exception as e: if db_api.is_retriable(e): with excutils.save_and_reraise_exception(): LOG.debug("Policy driver '%(driver)s' failed in " "ensure_tenant, operation will " "be retried", {'driver': driver.name}) else: LOG.exception("Policy driver '%s' failed in " "ensure_tenant", driver.name) raise gp_exc.GroupPolicyDriverError( method="ensure_tenant")
def _call_on_extended_drivers(self, method_name, context, continue_on_failure=False, raise_db_retriable=False): """Call a method on all extended mechanism drivers. :param method_name: name of the method to call :param context: context parameter to pass to each method call :param continue_on_failure: whether or not to continue to call all mechanism drivers once one has raised an exception :param raise_db_retriable: whether or not to treat retriable db exception by mechanism drivers to propagate up to upper layer so that upper layer can handle it or error in ML2 player :raises: neutron.plugins.ml2.common.MechanismDriverError if any mechanism driver call fails. or DB retriable error when raise_db_retriable=False. See neutron.db.api.is_retriable for what db exception is retriable """ errors = [] for driver in self.ordered_mech_drivers: if isinstance(driver.obj, driver_api.MechanismDriver): try: getattr(driver.obj, method_name)(context) except Exception as e: if raise_db_retriable and db_api.is_retriable(e): with excutils.save_and_reraise_exception(): LOG.debug( "DB exception raised by Mechanism " "driver '%(name)s' in %(method)s", { 'name': driver.name, 'method': method_name }, exc_info=e) LOG.exception( "Mechanism driver '%(name)s' failed in " "%(method)s", { 'name': driver.name, 'method': method_name }) errors.append(e) if not continue_on_failure: break if errors: raise ml2_exc.MechanismDriverError(method=method_name, errors=errors)
def ensure_tenant(self, plugin_context, tenant_id): for driver in self.ordered_policy_drivers: if isinstance(driver.obj, group_policy_driver_api.PolicyDriver): try: driver.obj.ensure_tenant(plugin_context, tenant_id) except Exception as e: if db_api.is_retriable(e): with excutils.save_and_reraise_exception(): LOG.debug( "Policy driver '%(driver)s' failed in " "ensure_tenant, operation will " "be retried", {'driver': driver.name}) else: LOG.exception( "Policy driver '%s' failed in " "ensure_tenant", driver.name) raise gp_exc.GroupPolicyDriverError( method="ensure_tenant")
def extend_network_dict(self, session, base_model, result): try: self._md.extend_network_dict(session, base_model, result) res_dict = self.get_network_extn_db(session, result['id']) if cisco_apic.EXTERNAL_NETWORK in res_dict: result.setdefault( cisco_apic.DIST_NAMES, {})[cisco_apic.EXTERNAL_NETWORK] = res_dict.pop( cisco_apic.EXTERNAL_NETWORK) result.update(res_dict) except Exception as e: with excutils.save_and_reraise_exception(): if db_api.is_retriable(e): LOG.debug( "APIC AIM extend_network_dict got retriable " "exception: %s", type(e)) else: LOG.exception("APIC AIM extend_network_dict failed")
def _call_on_extended_drivers(self, method_name, context, continue_on_failure=False, raise_db_retriable=False): """Call a method on all extended mechanism drivers. :param method_name: name of the method to call :param context: context parameter to pass to each method call :param continue_on_failure: whether or not to continue to call all mechanism drivers once one has raised an exception :param raise_db_retriable: whether or not to treat retriable db exception by mechanism drivers to propagate up to upper layer so that upper layer can handle it or error in ML2 player :raises: neutron.plugins.ml2.common.MechanismDriverError if any mechanism driver call fails. or DB retriable error when raise_db_retriable=False. See neutron.db.api.is_retriable for what db exception is retriable """ errors = [] for driver in self.ordered_mech_drivers: if isinstance(driver.obj, driver_api.MechanismDriver): try: getattr(driver.obj, method_name)(context) except Exception as e: if raise_db_retriable and db_api.is_retriable(e): with excutils.save_and_reraise_exception(): LOG.debug("DB exception raised by Mechanism " "driver '%(name)s' in %(method)s", {'name': driver.name, 'method': method_name}, exc_info=e) LOG.exception( "Mechanism driver '%(name)s' failed in " "%(method)s", {'name': driver.name, 'method': method_name} ) errors.append(e) if not continue_on_failure: break if errors: raise ml2_exc.MechanismDriverError( method=method_name, errors=errors )
def _call_drivers(self, method_name, context, raise_orig_exc=False): for driver in self.ordered_drivers: try: getattr(driver.obj, method_name)(context) except Exception as e: # This is an internal failure. if db_api.is_retriable(e): with excutils.save_and_reraise_exception(): LOG.debug( "DB exception raised by extension driver " "'%(name)s' in %(method)s", {'name': driver.name, 'method': method_name}, exc_info=e) LOG.exception(e) LOG.error("%(plugin)s driver '%(name)s' " "failed in %(method)s", {'name': driver.name, 'method': method_name, 'plugin': name}) if raise_orig_exc: raise else: raise exception(method=method_name)
def _destroy_servicechain_nodes(self, context, destroyers): # Actual node disruption try: for destroy in destroyers.values(): driver = destroy['driver'] try: driver.delete(destroy['context']) except exc.NodeDriverError: LOG.error("Node destroy failed, for node %s ", driver['context'].current_node['id']) except Exception as e: if db_api.is_retriable(e): with excutils.save_and_reraise_exception(): LOG.debug( "Node driver '%(name)s' failed in" " %(method)s, operation will be retried", {'name': driver._name, 'method': 'delete'} ) LOG.exception(e) finally: self.driver_manager.clear_node_owner(destroy['context']) finally: self.plumber.unplug_services(context, destroyers.values())
def _destroy_servicechain_nodes(self, context, destroyers): # Actual node disruption try: for destroy in destroyers.values(): driver = destroy['driver'] try: driver.delete(destroy['context']) except exc.NodeDriverError: LOG.error("Node destroy failed, for node %s ", driver['context'].current_node['id']) except Exception as e: if db_api.is_retriable(e): with excutils.save_and_reraise_exception(): LOG.debug( "Node driver '%(name)s' failed in" " %(method)s, operation will be retried", { 'name': driver._name, 'method': 'delete' }) LOG.exception(e) finally: self.driver_manager.clear_node_owner(destroy['context']) finally: self.plumber.unplug_services(context, destroyers.values())
def _call_on_drivers(self, method_name, context=None, continue_on_failure=False): """Helper method for calling a method across all policy drivers. :param method_name: name of the method to call :param context: context parameter to pass to each method call :param continue_on_failure: whether or not to continue to call all policy drivers once one has raised an exception :raises: neutron.services.group_policy.common.GroupPolicyDriverError if any policy driver call fails. """ error = False drivers = (self.ordered_policy_drivers if not method_name.startswith('delete') else self.reverse_ordered_policy_drivers) if method_name == 'start_rpc_listeners': servers = [] for driver in drivers: try: if method_name == 'start_rpc_listeners': server = getattr(driver.obj, method_name)() if server: servers.extend(server) else: getattr(driver.obj, method_name)(context) except Exception as e: if db_api.is_retriable(e): with excutils.save_and_reraise_exception(): LOG.debug( "Policy driver '%(name)s' failed in" " %(method)s, operation will be retried", {'name': driver.name, 'method': method_name} ) elif isinstance(e, gp_exc.GroupPolicyException) or isinstance( e, n_exc.NeutronException) or isinstance( e, oslo_policy.PolicyNotAuthorized): with excutils.save_and_reraise_exception(): LOG.exception( "Policy driver '%(name)s' failed in" " %(method)s", {'name': driver.name, 'method': method_name} ) elif isinstance(e, sqlalchemy_exc.InvalidRequestError): LOG.exception( "Policy driver '%(name)s' failed in %(method)s ", "with sqlalchemy.exc.InvalidRequestError", {'name': driver.name, 'method': method_name}) raise oslo_db_excp.RetryRequest(e) else: error = True # We are eating a non-GBP/non-Neutron exception here LOG.exception( "Policy driver '%(name)s' failed in %(method)s", {'name': driver.name, 'method': method_name}) if not continue_on_failure: break if error: raise gp_exc.GroupPolicyDriverError(method=method_name) if method_name == 'start_rpc_listeners': return servers