Fix usage of NexusPortBindingNotFound exception
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
This commit is contained in:
parent
f94126739a
commit
f8f2a7f39c
@ -96,7 +96,11 @@ class NexusConfigFailed(exceptions.QuantumException):
|
|||||||
|
|
||||||
class NexusPortBindingNotFound(exceptions.QuantumException):
|
class NexusPortBindingNotFound(exceptions.QuantumException):
|
||||||
"""NexusPort Binding is not present."""
|
"""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):
|
class PortVnicBindingAlreadyExists(exceptions.QuantumException):
|
||||||
|
@ -41,11 +41,14 @@ def get_nexusport_binding(port_id, vlan_id, switch_ip, instance_id):
|
|||||||
LOG.debug(_("get_nexusport_binding() called"))
|
LOG.debug(_("get_nexusport_binding() called"))
|
||||||
session = db.get_session()
|
session = db.get_session()
|
||||||
|
|
||||||
# FIXME(rpodolyaka): https://bugs.launchpad.net/quantum/+bug/1174323
|
filters = dict(port_id=port_id, vlan_id=vlan_id, switch_ip=switch_ip,
|
||||||
return (session.query(nexus_models_v2.NexusPortBinding).
|
instance_id=instance_id)
|
||||||
filter_by(vlan_id=vlan_id).filter_by(switch_ip=switch_ip).
|
bindings = (session.query(nexus_models_v2.NexusPortBinding).
|
||||||
filter_by(port_id=port_id).
|
filter_by(**filters).all())
|
||||||
filter_by(instance_id=instance_id).all())
|
if not bindings:
|
||||||
|
raise c_exc.NexusPortBindingNotFound(**filters)
|
||||||
|
|
||||||
|
return bindings
|
||||||
|
|
||||||
|
|
||||||
def get_nexusvlan_binding(vlan_id, switch_ip):
|
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"))
|
LOG.debug(_("get_nexusvlan_binding() called"))
|
||||||
session = db.get_session()
|
session = db.get_session()
|
||||||
|
|
||||||
# FIXME(rpodolyaka): https://bugs.launchpad.net/quantum/+bug/1174323
|
filters = dict(vlan_id=vlan_id, switch_ip=switch_ip)
|
||||||
return (session.query(nexus_models_v2.NexusPortBinding).
|
bindings = (session.query(nexus_models_v2.NexusPortBinding).
|
||||||
filter_by(vlan_id=vlan_id).filter_by(switch_ip=switch_ip).
|
filter_by(**filters).all())
|
||||||
all())
|
if not bindings:
|
||||||
|
raise c_exc.NexusPortBindingNotFound(**filters)
|
||||||
|
|
||||||
|
return bindings
|
||||||
|
|
||||||
|
|
||||||
def add_nexusport_binding(port_id, vlan_id, switch_ip, instance_id):
|
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()
|
session.flush()
|
||||||
return binding
|
return binding
|
||||||
except exc.NoResultFound:
|
except exc.NoResultFound:
|
||||||
raise c_exc.NexusPortBindingNotFound()
|
raise c_exc.NexusPortBindingNotFound(port_id=port_id)
|
||||||
|
|
||||||
|
|
||||||
def get_nexusvm_binding(vlan_id, instance_id):
|
def get_nexusvm_binding(vlan_id, instance_id):
|
||||||
"""Lists nexusvm bindings."""
|
"""Lists nexusvm bindings."""
|
||||||
LOG.debug(_("get_nexusvm_binding() called"))
|
LOG.debug(_("get_nexusvm_binding() called"))
|
||||||
session = db.get_session()
|
session = db.get_session()
|
||||||
try:
|
|
||||||
binding = (session.query(nexus_models_v2.NexusPortBinding).
|
filters = dict(instance_id=instance_id, vlan_id=vlan_id)
|
||||||
filter_by(instance_id=instance_id).
|
binding = (session.query(nexus_models_v2.NexusPortBinding).
|
||||||
filter_by(vlan_id=vlan_id).first())
|
filter_by(**filters).first())
|
||||||
return binding
|
if not binding:
|
||||||
except exc.NoResultFound:
|
raise c_exc.NexusPortBindingNotFound(**filters)
|
||||||
raise c_exc.NexusPortBindingNotFound(vlan_id=vlan_id)
|
|
||||||
|
return binding
|
||||||
|
|
||||||
|
|
||||||
def get_port_vlan_switch_binding(port_id, vlan_id, switch_ip):
|
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"))
|
LOG.debug(_("get_port_vlan_switch_binding() called"))
|
||||||
session = db.get_session()
|
session = db.get_session()
|
||||||
|
|
||||||
# FIXME(rpodolyaka): https://bugs.launchpad.net/quantum/+bug/1174323
|
filters = dict(port_id=port_id, switch_ip=switch_ip, vlan_id=vlan_id)
|
||||||
return (session.query(nexus_models_v2.NexusPortBinding).
|
bindings = (session.query(nexus_models_v2.NexusPortBinding).
|
||||||
filter_by(port_id=port_id).filter_by(switch_ip=switch_ip).
|
filter_by(**filters).all())
|
||||||
filter_by(vlan_id=vlan_id).all())
|
if not bindings:
|
||||||
|
raise c_exc.NexusPortBindingNotFound(**filters)
|
||||||
|
|
||||||
|
return bindings
|
||||||
|
@ -87,11 +87,12 @@ class NexusPlugin(L2DevicePluginBase):
|
|||||||
raise cisco_exc.NexusComputeHostNotConfigured(host=host)
|
raise cisco_exc.NexusComputeHostNotConfigured(host=host)
|
||||||
|
|
||||||
# Check if this network is already in the DB
|
# 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_created = False
|
||||||
vlan_enabled = 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_ip = switch_ip
|
||||||
_nexus_ports = (port_id,)
|
_nexus_ports = (port_id,)
|
||||||
_nexus_ssh_port = \
|
_nexus_ssh_port = \
|
||||||
@ -100,8 +101,9 @@ class NexusPlugin(L2DevicePluginBase):
|
|||||||
_nexus_username = _nexus_creds['username']
|
_nexus_username = _nexus_creds['username']
|
||||||
_nexus_password = _nexus_creds['password']
|
_nexus_password = _nexus_creds['password']
|
||||||
# Check for vlan/switch binding
|
# Check for vlan/switch binding
|
||||||
vbinding = nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
|
try:
|
||||||
if not vbinding:
|
nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
|
||||||
|
except cisco_exc.NexusPortBindingNotFound:
|
||||||
# Create vlan and trunk vlan on the port
|
# Create vlan and trunk vlan on the port
|
||||||
self._client.create_vlan(
|
self._client.create_vlan(
|
||||||
vlan_name, str(vlan_id), _nexus_ip,
|
vlan_name, str(vlan_id), _nexus_ip,
|
||||||
@ -188,44 +190,46 @@ class NexusPlugin(L2DevicePluginBase):
|
|||||||
"""
|
"""
|
||||||
LOG.debug(_("NexusPlugin:delete_port() called"))
|
LOG.debug(_("NexusPlugin:delete_port() called"))
|
||||||
# Delete DB row for this port
|
# Delete DB row for this port
|
||||||
row = nxos_db.get_nexusvm_binding(vlan_id, device_id)
|
try:
|
||||||
if row:
|
row = nxos_db.get_nexusvm_binding(vlan_id, device_id)
|
||||||
nxos_db.remove_nexusport_binding(row['port_id'], row['vlan_id'],
|
except cisco_exc.NexusPortBindingNotFound:
|
||||||
row['switch_ip'],
|
return
|
||||||
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:
|
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:
|
try:
|
||||||
# Delete this vlan from this switch
|
nxos_db.add_nexusport_binding(row['port_id'],
|
||||||
_nexus_ip = row['switch_ip']
|
row['vlan_id'],
|
||||||
_nexus_ports = (row['port_id'],)
|
row['switch_ip'],
|
||||||
_nexus_ssh_port = (self._nexus_switches[_nexus_ip,
|
row['instance_id'])
|
||||||
'ssh_port'])
|
finally:
|
||||||
_nexus_creds = self.get_credential(_nexus_ip)
|
# Raise the original exception
|
||||||
_nexus_username = _nexus_creds['username']
|
raise e
|
||||||
_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']
|
return row['instance_id']
|
||||||
|
|
||||||
def update_port(self, tenant_id, net_id, port_id, port_state, **kwargs):
|
def update_port(self, tenant_id, net_id, port_id, port_state, **kwargs):
|
||||||
"""Update port.
|
"""Update port.
|
||||||
|
@ -20,7 +20,11 @@ test_database.py is an independent test suite
|
|||||||
that tests the database api method calls
|
that tests the database api method calls
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import mock
|
||||||
|
import sqlalchemy
|
||||||
|
|
||||||
from quantum.openstack.common import log as logging
|
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.api as db
|
||||||
import quantum.plugins.cisco.db.l2network_db as l2network_db
|
import quantum.plugins.cisco.db.l2network_db as l2network_db
|
||||||
import quantum.plugins.cisco.db.nexus_db_v2 as nexus_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.assertTrue(count == 1)
|
||||||
self.tearDown_nexusportbinding()
|
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):
|
def tearDown_nexusportbinding(self):
|
||||||
"""Tear down nexus port binding table."""
|
"""Tear down nexus port binding table."""
|
||||||
LOG.debug("Tearing Down Nexus port Bindings")
|
LOG.debug("Tearing Down Nexus port Bindings")
|
||||||
|
Loading…
Reference in New Issue
Block a user