]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Fix usage of NexusPortBindingNotFound exception
authorRoman Podolyaka <rpodolyaka@mirantis.com>
Tue, 7 May 2013 18:57:53 +0000 (21:57 +0300)
committerRoman Podolyaka <rpodolyaka@mirantis.com>
Wed, 8 May 2013 19:10:48 +0000 (22:10 +0300)
Currently the required keyword argument (port_id)
is not passed when the exception is raised. In fact
this exception has never been raised before due to
another bug (1173131) so this change also has to
ensure it doesn't break any existing code using
functions which can possibly raise this exception.

Fixes bug 1174323.

Change-Id: I81f0b0def7db163fb0fbb5e03be511113c8d0be5

quantum/plugins/cisco/common/cisco_exceptions.py
quantum/plugins/cisco/db/nexus_db_v2.py
quantum/plugins/cisco/nexus/cisco_nexus_plugin_v2.py
quantum/plugins/cisco/tests/unit/test_database.py

index 2b27cc23dc1e3aedf23e814a4ee1e69e22a1f166..f50e6050c59cc2d4baf147fac953c047e9335bac 100644 (file)
@@ -96,7 +96,11 @@ class NexusConfigFailed(exceptions.QuantumException):
 
 class NexusPortBindingNotFound(exceptions.QuantumException):
     """NexusPort Binding is not present."""
-    message = _("Nexus Port Binding %(port_id)s is not present.")
+    message = _("Nexus Port Binding (%(filters)s) is not present")
+
+    def __init__(self, **kwargs):
+        filters = ','.join('%s=%s' % i for i in kwargs.items())
+        super(NexusPortBindingNotFound, self).__init__(filters=filters)
 
 
 class PortVnicBindingAlreadyExists(exceptions.QuantumException):
index fb331873b1cdf93394c5e0fc572134b65d4fd133..a48a82795d62f6b04b737c36b5472544e50f81d4 100644 (file)
@@ -41,11 +41,14 @@ def get_nexusport_binding(port_id, vlan_id, switch_ip, instance_id):
     LOG.debug(_("get_nexusport_binding() called"))
     session = db.get_session()
 
-    # FIXME(rpodolyaka): https://bugs.launchpad.net/quantum/+bug/1174323
-    return (session.query(nexus_models_v2.NexusPortBinding).
-            filter_by(vlan_id=vlan_id).filter_by(switch_ip=switch_ip).
-            filter_by(port_id=port_id).
-            filter_by(instance_id=instance_id).all())
+    filters = dict(port_id=port_id, vlan_id=vlan_id, switch_ip=switch_ip,
+                   instance_id=instance_id)
+    bindings = (session.query(nexus_models_v2.NexusPortBinding).
+                filter_by(**filters).all())
+    if not bindings:
+        raise c_exc.NexusPortBindingNotFound(**filters)
+
+    return bindings
 
 
 def get_nexusvlan_binding(vlan_id, switch_ip):
@@ -53,10 +56,13 @@ def get_nexusvlan_binding(vlan_id, switch_ip):
     LOG.debug(_("get_nexusvlan_binding() called"))
     session = db.get_session()
 
-    # FIXME(rpodolyaka): https://bugs.launchpad.net/quantum/+bug/1174323
-    return (session.query(nexus_models_v2.NexusPortBinding).
-            filter_by(vlan_id=vlan_id).filter_by(switch_ip=switch_ip).
-            all())
+    filters = dict(vlan_id=vlan_id, switch_ip=switch_ip)
+    bindings = (session.query(nexus_models_v2.NexusPortBinding).
+                filter_by(**filters).all())
+    if not bindings:
+        raise c_exc.NexusPortBindingNotFound(**filters)
+
+    return bindings
 
 
 def add_nexusport_binding(port_id, vlan_id, switch_ip, instance_id):
@@ -98,20 +104,21 @@ def update_nexusport_binding(port_id, new_vlan_id):
         session.flush()
         return binding
     except exc.NoResultFound:
-        raise c_exc.NexusPortBindingNotFound()
+        raise c_exc.NexusPortBindingNotFound(port_id=port_id)
 
 
 def get_nexusvm_binding(vlan_id, instance_id):
     """Lists nexusvm bindings."""
     LOG.debug(_("get_nexusvm_binding() called"))
     session = db.get_session()
-    try:
-        binding = (session.query(nexus_models_v2.NexusPortBinding).
-                   filter_by(instance_id=instance_id).
-                   filter_by(vlan_id=vlan_id).first())
-        return binding
-    except exc.NoResultFound:
-        raise c_exc.NexusPortBindingNotFound(vlan_id=vlan_id)
+
+    filters = dict(instance_id=instance_id, vlan_id=vlan_id)
+    binding = (session.query(nexus_models_v2.NexusPortBinding).
+               filter_by(**filters).first())
+    if not binding:
+        raise c_exc.NexusPortBindingNotFound(**filters)
+
+    return binding
 
 
 def get_port_vlan_switch_binding(port_id, vlan_id, switch_ip):
@@ -119,7 +126,10 @@ def get_port_vlan_switch_binding(port_id, vlan_id, switch_ip):
     LOG.debug(_("get_port_vlan_switch_binding() called"))
     session = db.get_session()
 
-    # FIXME(rpodolyaka): https://bugs.launchpad.net/quantum/+bug/1174323
-    return (session.query(nexus_models_v2.NexusPortBinding).
-            filter_by(port_id=port_id).filter_by(switch_ip=switch_ip).
-            filter_by(vlan_id=vlan_id).all())
+    filters = dict(port_id=port_id, switch_ip=switch_ip, vlan_id=vlan_id)
+    bindings = (session.query(nexus_models_v2.NexusPortBinding).
+                filter_by(**filters).all())
+    if not bindings:
+        raise c_exc.NexusPortBindingNotFound(**filters)
+
+    return bindings
index a5873965aa2aba1e6b171f378c40ad49284e8294..b0c17366b9cccf72b9836a5b2a807bced94642a6 100644 (file)
@@ -87,11 +87,12 @@ class NexusPlugin(L2DevicePluginBase):
             raise cisco_exc.NexusComputeHostNotConfigured(host=host)
 
         # Check if this network is already in the DB
-        binding = nxos_db.get_port_vlan_switch_binding(
-            port_id, vlan_id, switch_ip)
         vlan_created = False
         vlan_enabled = False
-        if not binding:
+
+        try:
+            nxos_db.get_port_vlan_switch_binding(port_id, vlan_id, switch_ip)
+        except cisco_exc.NexusPortBindingNotFound:
             _nexus_ip = switch_ip
             _nexus_ports = (port_id,)
             _nexus_ssh_port = \
@@ -100,8 +101,9 @@ class NexusPlugin(L2DevicePluginBase):
             _nexus_username = _nexus_creds['username']
             _nexus_password = _nexus_creds['password']
             # Check for vlan/switch binding
-            vbinding = nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
-            if not vbinding:
+            try:
+                nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
+            except cisco_exc.NexusPortBindingNotFound:
                 # Create vlan and trunk vlan on the port
                 self._client.create_vlan(
                     vlan_name, str(vlan_id), _nexus_ip,
@@ -188,44 +190,46 @@ class NexusPlugin(L2DevicePluginBase):
         """
         LOG.debug(_("NexusPlugin:delete_port() called"))
         # Delete DB row for this port
-        row = nxos_db.get_nexusvm_binding(vlan_id, device_id)
-        if row:
-            nxos_db.remove_nexusport_binding(row['port_id'], row['vlan_id'],
-                                             row['switch_ip'],
-                                             row['instance_id'])
-            # Check for any other bindings with the same vlan_id and switch_ip
-            bindings = nxos_db.get_nexusvlan_binding(
-                row['vlan_id'], row['switch_ip'])
-
-            if not bindings:
+        try:
+            row = nxos_db.get_nexusvm_binding(vlan_id, device_id)
+        except cisco_exc.NexusPortBindingNotFound:
+            return
+
+        nxos_db.remove_nexusport_binding(row['port_id'], row['vlan_id'],
+                                         row['switch_ip'],
+                                         row['instance_id'])
+        # Check for any other bindings with the same vlan_id and switch_ip
+        try:
+            nxos_db.get_nexusvlan_binding(row['vlan_id'], row['switch_ip'])
+        except cisco_exc.NexusPortBindingNotFound:
+            try:
+                # Delete this vlan from this switch
+                _nexus_ip = row['switch_ip']
+                _nexus_ports = (row['port_id'],)
+                _nexus_ssh_port = (self._nexus_switches[_nexus_ip,
+                                                        'ssh_port'])
+                _nexus_creds = self.get_credential(_nexus_ip)
+                _nexus_username = _nexus_creds['username']
+                _nexus_password = _nexus_creds['password']
+                self._client.delete_vlan(
+                    str(row['vlan_id']), _nexus_ip,
+                    _nexus_username, _nexus_password,
+                    _nexus_ports, _nexus_ssh_port)
+            except Exception as e:
+                # The delete vlan operation on the Nexus failed,
+                # so this delete_port request has failed. For
+                # consistency, roll back the Nexus database to what
+                # it was before this request.
                 try:
-                    # Delete this vlan from this switch
-                    _nexus_ip = row['switch_ip']
-                    _nexus_ports = (row['port_id'],)
-                    _nexus_ssh_port = (self._nexus_switches[_nexus_ip,
-                                                            'ssh_port'])
-                    _nexus_creds = self.get_credential(_nexus_ip)
-                    _nexus_username = _nexus_creds['username']
-                    _nexus_password = _nexus_creds['password']
-                    self._client.delete_vlan(
-                        str(row['vlan_id']), _nexus_ip,
-                        _nexus_username, _nexus_password,
-                        _nexus_ports, _nexus_ssh_port)
-                except Exception as e:
-                    # The delete vlan operation on the Nexus failed,
-                    # so this delete_port request has failed. For
-                    # consistency, roll back the Nexus database to what
-                    # it was before this request.
-                    try:
-                        nxos_db.add_nexusport_binding(row['port_id'],
-                                                      row['vlan_id'],
-                                                      row['switch_ip'],
-                                                      row['instance_id'])
-                    finally:
-                        # Raise the original exception
-                        raise e
-
-            return row['instance_id']
+                    nxos_db.add_nexusport_binding(row['port_id'],
+                                                  row['vlan_id'],
+                                                  row['switch_ip'],
+                                                  row['instance_id'])
+                finally:
+                    # Raise the original exception
+                    raise e
+
+        return row['instance_id']
 
     def update_port(self, tenant_id, net_id, port_id, port_state, **kwargs):
         """Update port.
index 4ff9e8a9ac5f6c61cf5cae523d922f9bc51f4a44..bf18c23af4716edb42ecada4261a1d1c9a3c12af 100644 (file)
@@ -20,7 +20,11 @@ test_database.py is an independent test suite
 that tests the database api method calls
 """
 
+import mock
+import sqlalchemy
+
 from quantum.openstack.common import log as logging
+import quantum.plugins.cisco.common.cisco_exceptions as c_exc
 import quantum.plugins.cisco.db.api as db
 import quantum.plugins.cisco.db.l2network_db as l2network_db
 import quantum.plugins.cisco.db.nexus_db_v2 as nexus_db
@@ -397,6 +401,49 @@ class NexusDBTest(base.BaseTestCase):
         self.assertTrue(count == 1)
         self.tearDown_nexusportbinding()
 
+    def test_get_nexusport_binding_no_result_found_handling(self):
+        with mock.patch('sqlalchemy.orm.Query.all') as mock_all:
+            mock_all.return_value = []
+
+            with self.assertRaises(c_exc.NexusPortBindingNotFound):
+                nexus_db.get_nexusport_binding(port_id=10,
+                                               vlan_id=20,
+                                               switch_ip='10.0.0.1',
+                                               instance_id=1)
+
+    def test_get_nexusvlan_binding_no_result_found_handling(self):
+        with mock.patch('sqlalchemy.orm.Query.all') as mock_all:
+            mock_all.return_value = []
+
+            with self.assertRaises(c_exc.NexusPortBindingNotFound):
+                nexus_db.get_nexusvlan_binding(vlan_id=10,
+                                               switch_ip='10.0.0.1')
+
+    def test_update_nexusport_binding_no_result_found_handling(self):
+        with mock.patch('sqlalchemy.orm.Query.one') as mock_one:
+            mock_one.side_effect = sqlalchemy.orm.exc.NoResultFound
+
+            with self.assertRaises(c_exc.NexusPortBindingNotFound):
+                nexus_db.update_nexusport_binding(port_id=10,
+                                                  vlan_id=20,
+                                                  switch_ip='10.0.0.1',
+                                                  instance_id=1)
+
+    def test_get_nexusvm_binding_no_result_found_handling(self):
+        with mock.patch('sqlalchemy.orm.Query.first') as mock_first:
+            mock_first.return_value = None
+
+            with self.assertRaises(c_exc.NexusPortBindingNotFound):
+                nexus_db.get_nexusvm_binding(port_id=10,
+                                             vlan_id=20,
+                                             switch_ip='10.0.0.1')
+
+    def test_nexusport_binding_not_found_exception_message_formatting(self):
+        try:
+            raise c_exc.NexusPortBindingNotFound(a=1, b='test')
+        except c_exc.NexusPortBindingNotFound as e:
+            self.assertIn('(a=1,b=test)', str(e))
+
     def tearDown_nexusportbinding(self):
         """Tear down nexus port binding table."""
         LOG.debug("Tearing Down Nexus port Bindings")