Merge "Change nexus_dict to accept port lists"
This commit is contained in:
commit
2ffcb79117
@ -66,12 +66,13 @@ class CiscoNexusMechanismDriver(api.MechanismDriver):
|
||||
host_connections = []
|
||||
for switch_ip, attr in self._nexus_switches:
|
||||
if str(attr) == str(host_id):
|
||||
port_id = self._nexus_switches[switch_ip, attr]
|
||||
if ':' in port_id:
|
||||
intf_type, port = port_id.split(':')
|
||||
else:
|
||||
intf_type, port = 'ethernet', port_id
|
||||
host_connections.append((switch_ip, intf_type, port))
|
||||
for port_id in (
|
||||
self._nexus_switches[switch_ip, attr].split(',')):
|
||||
if ':' in port_id:
|
||||
intf_type, port = port_id.split(':')
|
||||
else:
|
||||
intf_type, port = 'ethernet', port_id
|
||||
host_connections.append((switch_ip, intf_type, port))
|
||||
|
||||
if host_connections:
|
||||
return host_connections
|
||||
@ -100,18 +101,30 @@ class CiscoNexusMechanismDriver(api.MechanismDriver):
|
||||
vlan_name = cfg.CONF.ml2_cisco.vlan_name_prefix + str(vlan_id)
|
||||
host_connections = self._get_switch_info(host_id)
|
||||
|
||||
# (nexus_port,switch_ip) will be unique in each iteration.
|
||||
# But switch_ip will repeat if host has >1 connection to same switch.
|
||||
# So track which switch_ips already have vlan created in this loop.
|
||||
vlan_already_created = []
|
||||
for switch_ip, intf_type, nexus_port in host_connections:
|
||||
# Check to see if this is the first binding to use this vlan on the
|
||||
# switch/port. Configure switch accordingly.
|
||||
bindings = nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
|
||||
if len(bindings) == 1:
|
||||
LOG.debug(_("Nexus: create & trunk vlan %s"), vlan_name)
|
||||
self.driver.create_and_trunk_vlan(
|
||||
switch_ip, vlan_id, vlan_name, intf_type, nexus_port)
|
||||
else:
|
||||
LOG.debug(_("Nexus: trunk vlan %s"), vlan_name)
|
||||
|
||||
# The VLAN needs to be created on the switch if no other
|
||||
# instance has been placed in this VLAN on a different host
|
||||
# attached to this switch. Search the existing bindings in the
|
||||
# database. If all the instance_id in the database match the
|
||||
# current device_id, then create the VLAN, but only once per
|
||||
# switch_ip. Otherwise, just trunk.
|
||||
all_bindings = nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
|
||||
previous_bindings = [row for row in all_bindings
|
||||
if row.instance_id != device_id]
|
||||
if previous_bindings or (switch_ip in vlan_already_created):
|
||||
LOG.debug("Nexus: trunk vlan %s"), vlan_name
|
||||
self.driver.enable_vlan_on_trunk_int(switch_ip, vlan_id,
|
||||
intf_type, nexus_port)
|
||||
else:
|
||||
vlan_already_created.append(switch_ip)
|
||||
LOG.debug("Nexus: create & trunk vlan %s"), vlan_name
|
||||
self.driver.create_and_trunk_vlan(
|
||||
switch_ip, vlan_id, vlan_name, intf_type, nexus_port)
|
||||
|
||||
def _delete_nxos_db(self, vlan_id, device_id, host_id):
|
||||
"""Delete the nexus database entry.
|
||||
@ -135,7 +148,13 @@ class CiscoNexusMechanismDriver(api.MechanismDriver):
|
||||
Called during update postcommit port event.
|
||||
"""
|
||||
host_connections = self._get_switch_info(host_id)
|
||||
|
||||
# (nexus_port,switch_ip) will be unique in each iteration.
|
||||
# But switch_ip will repeat if host has >1 connection to same switch.
|
||||
# So track which switch_ips already have vlan removed in this loop.
|
||||
vlan_already_removed = []
|
||||
for switch_ip, intf_type, nexus_port in host_connections:
|
||||
|
||||
# if there are no remaining db entries using this vlan on this
|
||||
# nexus switch port then remove vlan from the switchport trunk.
|
||||
port_id = '%s:%s' % (intf_type, nexus_port)
|
||||
@ -151,7 +170,11 @@ class CiscoNexusMechanismDriver(api.MechanismDriver):
|
||||
try:
|
||||
nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
|
||||
except excep.NexusPortBindingNotFound:
|
||||
self.driver.delete_vlan(switch_ip, vlan_id)
|
||||
|
||||
# Do not perform a second time on same switch
|
||||
if switch_ip not in vlan_already_removed:
|
||||
self.driver.delete_vlan(switch_ip, vlan_id)
|
||||
vlan_already_removed.append(switch_ip)
|
||||
|
||||
def _is_vm_migration(self, context):
|
||||
if not context.bound_segment and context.original_bound_segment:
|
||||
|
@ -42,6 +42,7 @@ class TestCiscoNexusPluginConfig(base.BaseTestCase):
|
||||
'ssh_port': [22],
|
||||
'compute1': ['1/1'],
|
||||
'compute2': ['1/2'],
|
||||
'compute5': ['1/3,1/4']
|
||||
},
|
||||
'ml2_mech_cisco_nexus:2.2.2.2': {
|
||||
'username': ['admin'],
|
||||
@ -49,6 +50,7 @@ class TestCiscoNexusPluginConfig(base.BaseTestCase):
|
||||
'ssh_port': [22],
|
||||
'compute3': ['1/1'],
|
||||
'compute4': ['1/2'],
|
||||
'compute5': ['portchannel:20,portchannel:30']
|
||||
},
|
||||
}
|
||||
expected_dev_dict = {
|
||||
@ -57,11 +59,13 @@ class TestCiscoNexusPluginConfig(base.BaseTestCase):
|
||||
('1.1.1.1', 'ssh_port'): 22,
|
||||
('1.1.1.1', 'compute1'): '1/1',
|
||||
('1.1.1.1', 'compute2'): '1/2',
|
||||
('1.1.1.1', 'compute5'): '1/3,1/4',
|
||||
('2.2.2.2', 'username'): 'admin',
|
||||
('2.2.2.2', 'password'): 'mySecretPassword',
|
||||
('2.2.2.2', 'ssh_port'): 22,
|
||||
('2.2.2.2', 'compute3'): '1/1',
|
||||
('2.2.2.2', 'compute4'): '1/2',
|
||||
('2.2.2.2', 'compute5'): 'portchannel:20,portchannel:30',
|
||||
}
|
||||
with mock.patch.object(cfg, 'MultiConfigParser') as parser:
|
||||
parser.return_value.read.return_value = cfg.CONF.config_file
|
||||
|
@ -31,18 +31,23 @@ from neutron.tests.unit import testlib_api
|
||||
|
||||
NEXUS_IP_ADDRESS = '1.1.1.1'
|
||||
NEXUS_IP_ADDRESS_PC = '2.2.2.2'
|
||||
NEXUS_IP_ADDRESS_DUAL = '3.3.3.3'
|
||||
HOST_NAME_1 = 'testhost1'
|
||||
HOST_NAME_2 = 'testhost2'
|
||||
HOST_NAME_PC = 'testpchost'
|
||||
HOST_NAME_DUAL = 'testdualhost'
|
||||
INSTANCE_1 = 'testvm1'
|
||||
INSTANCE_2 = 'testvm2'
|
||||
INSTANCE_PC = 'testpcvm'
|
||||
INSTANCE_DUAL = 'testdualvm'
|
||||
NEXUS_PORT_1 = 'ethernet:1/10'
|
||||
NEXUS_PORT_2 = 'ethernet:1/20'
|
||||
NEXUS_PORTCHANNELS = 'portchannel:2'
|
||||
NEXUS_DUAL = 'ethernet:1/3,portchannel:2'
|
||||
VLAN_ID_1 = 267
|
||||
VLAN_ID_2 = 265
|
||||
VLAN_ID_PC = 268
|
||||
VLAN_ID_DUAL = 269
|
||||
DEVICE_OWNER = 'compute:test'
|
||||
NEXUS_SSH_PORT = '22'
|
||||
PORT_STATE = n_const.PORT_STATUS_ACTIVE
|
||||
@ -119,6 +124,12 @@ class TestCiscoNexusDevice(testlib_api.SqlTestCase):
|
||||
NEXUS_PORTCHANNELS,
|
||||
INSTANCE_PC,
|
||||
VLAN_ID_PC),
|
||||
'test_config_dual': TestConfigObj(
|
||||
NEXUS_IP_ADDRESS_DUAL,
|
||||
HOST_NAME_DUAL,
|
||||
NEXUS_DUAL,
|
||||
INSTANCE_DUAL,
|
||||
VLAN_ID_DUAL),
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
@ -169,19 +180,22 @@ class TestCiscoNexusDevice(testlib_api.SqlTestCase):
|
||||
|
||||
self._cisco_mech_driver.update_port_precommit(port_context)
|
||||
self._cisco_mech_driver.update_port_postcommit(port_context)
|
||||
bindings = nexus_db_v2.get_nexusport_binding(nexus_port,
|
||||
vlan_id,
|
||||
nexus_ip_addr,
|
||||
instance_id)
|
||||
self.assertEqual(len(bindings), 1)
|
||||
for port_id in nexus_port.split(','):
|
||||
bindings = nexus_db_v2.get_nexusport_binding(port_id,
|
||||
vlan_id,
|
||||
nexus_ip_addr,
|
||||
instance_id)
|
||||
self.assertEqual(len(bindings), 1)
|
||||
|
||||
self._cisco_mech_driver.delete_port_precommit(port_context)
|
||||
self._cisco_mech_driver.delete_port_postcommit(port_context)
|
||||
with testtools.ExpectedException(exceptions.NexusPortBindingNotFound):
|
||||
nexus_db_v2.get_nexusport_binding(nexus_port,
|
||||
vlan_id,
|
||||
nexus_ip_addr,
|
||||
instance_id)
|
||||
for port_id in nexus_port.split(','):
|
||||
with testtools.ExpectedException(
|
||||
exceptions.NexusPortBindingNotFound):
|
||||
nexus_db_v2.get_nexusport_binding(port_id,
|
||||
vlan_id,
|
||||
nexus_ip_addr,
|
||||
instance_id)
|
||||
|
||||
def test_create_delete_ports(self):
|
||||
"""Tests creation and deletion of two new virtual Ports."""
|
||||
@ -195,3 +209,8 @@ class TestCiscoNexusDevice(testlib_api.SqlTestCase):
|
||||
"""Tests creation of a port over a portchannel."""
|
||||
self._create_delete_port(
|
||||
TestCiscoNexusDevice.test_configs['test_config_portchannel'])
|
||||
|
||||
def test_create_delete_dual(self):
|
||||
"""Tests creation and deletion of dual ports for single server"""
|
||||
self._create_delete_port(
|
||||
TestCiscoNexusDevice.test_configs['test_config_dual'])
|
||||
|
Loading…
x
Reference in New Issue
Block a user