Browse Source

Pass network_id to device's del_network method

This allows devices which reference VLANs by name and not ID
(such as Juniper Junos devices) to delete networks by name, which
is their neutron ID.

Change-Id: If1257fad47d05016dc59a8cfc60f5d2d22be420c
Related-Bug: #1740587
changes/34/530534/2
Mark Goddard 4 years ago
parent
commit
3ac398a481
13 changed files with 56 additions and 17 deletions
  1. +1
    -1
      networking_generic_switch/devices/__init__.py
  2. +6
    -2
      networking_generic_switch/devices/netmiko_devices/__init__.py
  3. +17
    -1
      networking_generic_switch/generic_switch_mech.py
  4. +1
    -1
      networking_generic_switch/tests/unit/netmiko/test_arista_eos.py
  5. +1
    -1
      networking_generic_switch/tests/unit/netmiko/test_brocade_fastiron.py
  6. +1
    -1
      networking_generic_switch/tests/unit/netmiko/test_cisco_300.py
  7. +1
    -1
      networking_generic_switch/tests/unit/netmiko/test_cisco_ios.py
  8. +2
    -2
      networking_generic_switch/tests/unit/netmiko/test_dell.py
  9. +1
    -1
      networking_generic_switch/tests/unit/netmiko/test_huawei.py
  10. +1
    -1
      networking_generic_switch/tests/unit/netmiko/test_huawei_vrpv8.py
  11. +2
    -2
      networking_generic_switch/tests/unit/netmiko/test_netmiko_base.py
  12. +1
    -1
      networking_generic_switch/tests/unit/netmiko/test_ovs_linux.py
  13. +21
    -2
      networking_generic_switch/tests/unit/test_generic_switch_mech.py

+ 1
- 1
networking_generic_switch/devices/__init__.py View File

@ -87,7 +87,7 @@ class GenericSwitchDevice(object):
pass
@abc.abstractmethod
def del_network(self, segmentation_id):
def del_network(self, segmentation_id, network_id):
pass
@abc.abstractmethod


+ 6
- 2
networking_generic_switch/devices/netmiko_devices/__init__.py View File

@ -163,14 +163,18 @@ class NetmikoSwitch(devices.GenericSwitchDevice):
segmentation_id=segmentation_id)
self.send_commands_to_device(cmds)
def del_network(self, segmentation_id):
def del_network(self, segmentation_id, network_id):
# NOTE(zhenguo): Remove dashes from uuid as on most devices 32 chars
# is the max length of vlan name.
network_id = uuid.UUID(network_id).hex
cmds = []
for port in self._get_trunk_ports():
cmds += self._format_commands(self.REMOVE_NETWORK_FROM_TRUNK,
port=port,
segmentation_id=segmentation_id)
cmds += self._format_commands(self.DELETE_NETWORK,
segmentation_id=segmentation_id)
segmentation_id=segmentation_id,
network_id=network_id)
self.send_commands_to_device(cmds)
def plug_port_to_network(self, port, segmentation_id):


+ 17
- 1
networking_generic_switch/generic_switch_mech.py View File

@ -45,6 +45,7 @@ class GenericSwitchDriver(api.MechanismDriver):
LOG.info('Devices %s have been loaded', self.switches.keys())
if not self.switches:
LOG.error('No devices have been loaded')
self.warned_del_network = False
def create_network_precommit(self, context):
"""Allocate resources for a new network.
@ -161,7 +162,22 @@ class GenericSwitchDriver(api.MechanismDriver):
# Delete vlan on all switches from this driver
for switch_name, switch in self.switches.items():
try:
switch.del_network(segmentation_id)
# NOTE(mgoddard): The del_network method was modified to
# accept the network ID. The switch object may still be
# implementing the old interface, so retry on a TypeError.
try:
switch.del_network(segmentation_id, network['id'])
except TypeError:
if not self.warned_del_network:
msg = (
'The del_network device method should accept '
'the network ID. Falling back to just the '
'segmentation ID for %(device)s. This '
'transitional support will be removed in the '
'Rocky release')
LOG.warn(msg, {'device': switch_name})
self.warned_del_network = True
switch.del_network(segmentation_id)
except Exception as e:
LOG.error("Failed to delete network %(net_id)s "
"on device: %(switch)s, reason: %(exc)s",


+ 1
- 1
networking_generic_switch/tests/unit/netmiko/test_arista_eos.py View File

@ -37,7 +37,7 @@ class TestNetmikoAristaEos(test_netmiko_base.NetmikoSwitchTestBase):
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
'NetmikoSwitch.send_commands_to_device')
def test_del_network(self, mock_exec):
self.switch.del_network(33)
self.switch.del_network(33, '0ae071f5-5be9-43e4-80ea-e41fefe85b21')
mock_exec.assert_called_with(['no vlan 33'])
@mock.patch('networking_generic_switch.devices.netmiko_devices.'


+ 1
- 1
networking_generic_switch/tests/unit/netmiko/test_brocade_fastiron.py View File

@ -39,7 +39,7 @@ class TestNetmikoBrocadeFastIron(test_netmiko_base.NetmikoSwitchTestBase):
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
'NetmikoSwitch.send_commands_to_device')
def test_del_network(self, mock_exec):
self.switch.del_network(33)
self.switch.del_network(33, '0ae071f5-5be9-43e4-80ea-e41fefe85b21')
mock_exec.assert_called_with(['no vlan 33'])
@mock.patch('networking_generic_switch.devices.netmiko_devices.'


+ 1
- 1
networking_generic_switch/tests/unit/netmiko/test_cisco_300.py View File

@ -37,7 +37,7 @@ class TestNetmikoCisco300(test_netmiko_base.NetmikoSwitchTestBase):
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
'NetmikoSwitch.send_commands_to_device')
def test_del_network(self, mock_exec):
self.switch.del_network(33)
self.switch.del_network(33, '0ae071f5-5be9-43e4-80ea-e41fefe85b21')
mock_exec.assert_called_with(['no vlan 33'])
@mock.patch('networking_generic_switch.devices.netmiko_devices.'


+ 1
- 1
networking_generic_switch/tests/unit/netmiko/test_cisco_ios.py View File

@ -37,7 +37,7 @@ class TestNetmikoCiscoIos(test_netmiko_base.NetmikoSwitchTestBase):
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
'NetmikoSwitch.send_commands_to_device')
def test_del_network(self, mock_exec):
self.switch.del_network(33)
self.switch.del_network(33, '0ae071f5-5be9-43e4-80ea-e41fefe85b21')
mock_exec.assert_called_with(['no vlan 33'])
@mock.patch('networking_generic_switch.devices.netmiko_devices.'


+ 2
- 2
networking_generic_switch/tests/unit/netmiko/test_dell.py View File

@ -50,14 +50,14 @@ class TestNetmikoDellNos(test_netmiko_base.NetmikoSwitchTestBase):
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
'NetmikoSwitch.send_commands_to_device')
def test_del_network(self, mock_exec):
self.switch.del_network(33)
self.switch.del_network(33, '0ae071f5-5be9-43e4-80ea-e41fefe85b21')
mock_exec.assert_called_with(['no interface vlan 33', 'exit'])
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
'NetmikoSwitch.send_commands_to_device')
def test_del_network_with_trunk_ports(self, mock_exec):
switch = self._make_switch_device({'ngs_trunk_ports': 'port1,port2'})
switch.del_network(33)
switch.del_network(33, '0ae071f55be943e480eae41fefe85b21')
mock_exec.assert_called_with(
['interface vlan 33', 'no tagged port1', 'exit',
'interface vlan 33', 'no tagged port2', 'exit',


+ 1
- 1
networking_generic_switch/tests/unit/netmiko/test_huawei.py View File

@ -37,7 +37,7 @@ class TestNetmikoHuawei(test_netmiko_base.NetmikoSwitchTestBase):
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
'NetmikoSwitch.send_commands_to_device')
def test_del_network(self, mock_exec):
self.switch.del_network(33)
self.switch.del_network(33, '0ae071f5-5be9-43e4-80ea-e41fefe85b21')
mock_exec.assert_called_with(
['undo vlan 33'])


+ 1
- 1
networking_generic_switch/tests/unit/netmiko/test_huawei_vrpv8.py View File

@ -36,7 +36,7 @@ class TestNetmikoHuawei_vrpv8(test_netmiko_base.NetmikoSwitchTestBase):
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
'NetmikoSwitch.send_commands_to_device')
def test_del_network(self, mock_exec):
self.switch.del_network(33)
self.switch.del_network(33, '0ae071f5-5be9-43e4-80ea-e41fefe85b21')
mock_exec.assert_called_with(['undo vlan 33', 'commit'])
@mock.patch('networking_generic_switch.devices.netmiko_devices.'


+ 2
- 2
networking_generic_switch/tests/unit/netmiko/test_netmiko_base.py View File

@ -59,14 +59,14 @@ class TestNetmikoSwitch(NetmikoSwitchTestBase):
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
'NetmikoSwitch.send_commands_to_device')
def test_del_network(self, m_sctd):
self.switch.del_network(22)
self.switch.del_network(22, '0ae071f5-5be9-43e4-80ea-e41fefe85b21')
m_sctd.assert_called_with([])
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
'NetmikoSwitch.send_commands_to_device')
def test_del_network_with_trunk_ports(self, m_sctd):
switch = self._make_switch_device({'ngs_trunk_ports': 'port1,port2'})
switch.del_network(22)
switch.del_network(22, '0ae071f5-5be9-43e4-80ea-e41fefe85b21')
m_sctd.assert_called_with([])
@mock.patch('networking_generic_switch.devices.netmiko_devices.'


+ 1
- 1
networking_generic_switch/tests/unit/netmiko/test_ovs_linux.py View File

@ -37,7 +37,7 @@ class TestNetmikoOvsLinux(test_netmiko_base.NetmikoSwitchTestBase):
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
'NetmikoSwitch.send_commands_to_device')
def test_del_network(self, mock_exec):
self.switch.del_network(44)
self.switch.del_network(44, '0ae071f5-5be9-43e4-80ea-e41fefe85b21')
mock_exec.assert_called_with([])
@mock.patch('networking_generic_switch.devices.netmiko_devices.'


+ 21
- 2
networking_generic_switch/tests/unit/test_generic_switch_mech.py View File

@ -74,7 +74,7 @@ class TestGenericSwitchDriver(unittest.TestCase):
'provider:segmentation_id': 22}
driver.delete_network_postcommit(mock_context)
self.switch_mock.del_network.assert_called_once_with(22)
self.switch_mock.del_network.assert_called_once_with(22, 22)
@mock.patch('networking_generic_switch.generic_switch_mech.LOG')
def test_delete_network_postcommit_failure(self, m_log, m_list):
@ -87,10 +87,29 @@ class TestGenericSwitchDriver(unittest.TestCase):
'provider:segmentation_id': 22}
driver.delete_network_postcommit(mock_context)
self.switch_mock.del_network.assert_called_once_with(22)
self.switch_mock.del_network.assert_called_once_with(22, 22)
self.assertEqual(1, m_log.error.call_count)
self.assertIn('Failed to delete network', m_log.error.call_args[0][0])
@mock.patch('networking_generic_switch.generic_switch_mech.LOG')
def test_delete_network_postcommit_no_network_id(self, m_log, m_list):
driver = gsm.GenericSwitchDriver()
driver.initialize()
mock_context = mock.create_autospec(driver_context.NetworkContext)
mock_context.current = {'id': 22,
'provider:network_type': 'vlan',
'provider:segmentation_id': 22}
self.switch_mock.del_network.side_effect = TypeError
driver.delete_network_postcommit(mock_context)
self.assertEqual([mock.call(22, 22), mock.call(22)],
self.switch_mock.del_network.call_args_list)
self.assertEqual(m_log.warn.call_count, 1)
# Ensure the warning is only logged once.
driver.delete_network_postcommit(mock_context)
self.assertEqual(m_log.warn.call_count, 1)
def test_delete_port_postcommit(self, m_list):
driver = gsm.GenericSwitchDriver()
driver.initialize()


Loading…
Cancel
Save