Propagate relevant driver exceptions to client

We have so far taken the approach of morhping the driver specific
exceptions into generic GBP exceptions before we propagate them
back to the client. The intention here was to shield the end user
from the technology specific driver details.

Over time, we have seen that the generic GBP exceptions make the
system difficult to debug, often requiring painful correlation
between client request-id and the server side logs.

This patches proposes to err on the side of exposing more details
in the form of the driver exception but hopefully making it easier
to debug an error situation.

Closes-bug: #1636624

Change-Id: Ia067b4bfa9d155ab3d780e1e69c8e5ceedd75cd6
This commit is contained in:
Sumit Naiksatam
2016-10-25 14:02:49 -07:00
parent f516fe8612
commit fdbec60438
4 changed files with 25 additions and 19 deletions

View File

@@ -16,6 +16,7 @@ from neutron._i18n import _LI
from neutron.common import exceptions as n_exc
from oslo_config import cfg
from oslo_log import log
from oslo_utils import excutils
import stevedore
from gbpservice.neutron.services.grouppolicy.common import exceptions as gp_exc
@@ -74,13 +75,18 @@ class ExtensionManager(stevedore.named.NamedExtensionManager):
try:
getattr(driver.obj, method_name)(session, data, result)
except (gp_exc.GroupPolicyException, n_exc.NeutronException):
# This is an exception for the user.
raise
with excutils.save_and_reraise_exception():
LOG.exception(
_LE("Extension driver '%(name)s' "
"failed in %(method)s"),
{'name': driver.name, 'method': method_name}
)
except Exception:
LOG.exception(
_LE("Extension driver '%(name)s' failed in %(method)s"),
{'name': driver.name, 'method': method_name}
)
LOG.exception(_LE("Extension driver '%(name)s' "
"failed in %(method)s"),
{'name': driver.name, 'method': method_name})
# We are replacing a non-GBP/non-Neutron exception here
raise gp_exc.GroupPolicyDriverError(method=method_name)
def process_create_policy_target(self, session, data, result):
"""Call all extension drivers during PT creation."""

View File

@@ -12,8 +12,10 @@
from neutron._i18n import _LE
from neutron._i18n import _LI
from neutron.common import exceptions as n_exc
from oslo_config import cfg
from oslo_log import log
from oslo_utils import excutils
import stevedore
from gbpservice.neutron.services.grouppolicy.common import exceptions as gp_exc
@@ -119,22 +121,22 @@ class PolicyDriverManager(stevedore.named.NamedExtensionManager):
for driver in drivers:
try:
getattr(driver.obj, method_name)(context)
except gp_exc.GroupPolicyException:
# This is an exception for the user.
raise
except (gp_exc.GroupPolicyException, n_exc.NeutronException):
with excutils.save_and_reraise_exception():
LOG.exception(
_LE("Policy driver '%(name)s' failed in %(method)s"),
{'name': driver.name, 'method': method_name}
)
except Exception:
# This is an internal failure.
# 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}
)
{'name': driver.name, 'method': method_name})
error = True
if not continue_on_failure:
break
if error:
raise gp_exc.GroupPolicyDriverError(
method=method_name
)
raise gp_exc.GroupPolicyDriverError(method=method_name)
def ensure_tenant(self, plugin_context, tenant_id):
for driver in self.ordered_policy_drivers:

View File

@@ -830,10 +830,8 @@ class TestPolicyTarget(ResourceMappingTestCase, TestClusterIdMixin):
self.api)['port']
ports.append(port)
self.assertEqual(1, len(port['fixed_ips']))
# sadly, we expect a 500 being a postcommit Neutron raised
# exception
self.create_policy_target(
policy_target_group_id=ptg['id'], expected_res_status=500)
policy_target_group_id=ptg['id'], expected_res_status=409)
def test_port_extra_attributes(self, extra=None):
extra = extra or {}

View File

@@ -301,7 +301,7 @@ class TestPolicyTarget(ResourceMappingProxyGroupGBPTestCase,
ptg = self.create_policy_target_group()['policy_target_group']
self.create_policy_target(policy_target_group_id=ptg['id'],
group_default_gateway=True,
expected_res_status=500)
expected_res_status=409)
def test_proxy_gateway_deleted(self):
ptg = self.create_policy_target_group()['policy_target_group']