diff --git a/networking_generic_switch/devices/__init__.py b/networking_generic_switch/devices/__init__.py index 31c52f63..9e986273 100644 --- a/networking_generic_switch/devices/__init__.py +++ b/networking_generic_switch/devices/__init__.py @@ -33,6 +33,8 @@ {'name': 'ngs_ssh_connect_timeout', 'default': 60}, {'name': 'ngs_ssh_connect_interval', 'default': 10}, {'name': 'ngs_max_connections', 'default': 1}, + # If True, disable switch ports that are not in use. + {'name': 'ngs_disable_inactive_ports', 'default': False}, ] @@ -91,6 +93,15 @@ def _get_physical_networks(self): return [] return physnets.split(',') + @staticmethod + def _str_to_bool(value): + truthy = ('true', 'yes', '1') + return str(value).lower() in truthy + + def _disable_inactive_ports(self): + """Return whether inactive ports should be disabled.""" + return self._str_to_bool(self.ngs_config['ngs_disable_inactive_ports']) + @abc.abstractmethod def add_network(self, segmentation_id, network_id): pass diff --git a/networking_generic_switch/devices/netmiko_devices/__init__.py b/networking_generic_switch/devices/netmiko_devices/__init__.py index c1e246b7..2ae915a3 100644 --- a/networking_generic_switch/devices/netmiko_devices/__init__.py +++ b/networking_generic_switch/devices/netmiko_devices/__init__.py @@ -42,6 +42,10 @@ class NetmikoSwitch(devices.GenericSwitchDevice): DELETE_PORT = None + ENABLE_PORT = None + + DISABLE_PORT = None + PLUG_TRUNK_PORT_TO_NETWORK = None UNPLUG_TRUNK_PORT_FROM_NETWORK = None @@ -179,16 +183,21 @@ def del_network(self, segmentation_id, network_id): self.send_commands_to_device(cmds) def plug_port_to_network(self, port, segmentation_id): - self.send_commands_to_device( - self._format_commands(self.PLUG_PORT_TO_NETWORK, - port=port, - segmentation_id=segmentation_id)) + cmds = [] + if self._disable_inactive_ports() and self.ENABLE_PORT: + cmds += self._format_commands(self.ENABLE_PORT, port=port) + cmds += self._format_commands(self.PLUG_PORT_TO_NETWORK, + port=port, + segmentation_id=segmentation_id) + self.send_commands_to_device(cmds) def delete_port(self, port, segmentation_id): - self.send_commands_to_device( - self._format_commands(self.DELETE_PORT, - port=port, - segmentation_id=segmentation_id)) + cmds = self._format_commands(self.DELETE_PORT, + port=port, + segmentation_id=segmentation_id) + if self._disable_inactive_ports() and self.DISABLE_PORT: + cmds += self._format_commands(self.DISABLE_PORT, port=port) + self.send_commands_to_device(cmds) def send_config_set(self, net_connect, cmd_set): """Send a set of configuration lines to the device. diff --git a/networking_generic_switch/tests/unit/netmiko/test_netmiko_base.py b/networking_generic_switch/tests/unit/netmiko/test_netmiko_base.py index d8356f6c..31b08d0b 100644 --- a/networking_generic_switch/tests/unit/netmiko/test_netmiko_base.py +++ b/networking_generic_switch/tests/unit/netmiko/test_netmiko_base.py @@ -76,11 +76,27 @@ def test_plug_port_to_network(self, m_sctd): self.switch.plug_port_to_network(2222, 22) m_sctd.assert_called_with([]) + @mock.patch('networking_generic_switch.devices.netmiko_devices.' + 'NetmikoSwitch.send_commands_to_device') + def test_plug_port_to_network_disable_inactive(self, m_sctd): + switch = self._make_switch_device( + {'ngs_disable_inactive_ports': 'true'}) + switch.plug_port_to_network(2222, 22) + m_sctd.assert_called_with([]) + @mock.patch('networking_generic_switch.devices.netmiko_devices.' 'NetmikoSwitch.send_commands_to_device') def test_delete_port(self, m_sctd): self.switch.delete_port(2222, 22) - m_sctd.assert_called_with(None) + m_sctd.assert_called_with([]) + + @mock.patch('networking_generic_switch.devices.netmiko_devices.' + 'NetmikoSwitch.send_commands_to_device') + def test_delete_port_disable_inactive(self, m_sctd): + switch = self._make_switch_device( + {'ngs_disable_inactive_ports': 'true'}) + switch.delete_port(2222, 22) + m_sctd.assert_called_with([]) def test__format_commands(self): self.switch._format_commands(