Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
 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)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
 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")
Ejemplo n.º 7
0
 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")
Ejemplo n.º 8
0
 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)
Ejemplo n.º 10
0
 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")
Ejemplo n.º 12
0
    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")
Ejemplo n.º 15
0
    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
            )
Ejemplo n.º 16
0
 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)
Ejemplo n.º 17
0
 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())
Ejemplo n.º 18
0
 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