summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Goddard <mark@stackhpc.com>2018-08-15 11:45:09 +0100
committerMark Goddard <mark@stackhpc.com>2018-08-31 16:00:50 +0100
commit55a9efeffd2265bd355c23d7be2e1e77a919e03c (patch)
tree9fff8730d706098b127a873a279f24919cfc58cf
parent9fa0acce4a8816fe87611da1075d2da3ddbd637f (diff)
Support disabling inactive links
Currently, when a port is unbound by NGS, this is typically implemented by removing the VLAN association from the corresponding switch interface. This puts the interface on the default VLAN of the switch, and leaves it administratively up (active). This may be an issue in some scenarios, such as: * If there is more than one interface on the server, subsequent instances may choose not to attach a network to one or more interfaces. If these interfaces are active on a default VLAN this would be a security hole. * If configuration of an interface fails but is silently ignored by NGS, the interface will remain on the default VLAN. To avoid these issues this change adds support for administratively disabling ports when they are not in use. This behaviour is optional, since it might not be appropriate on all devices or in all scenarios. Configuration of the behaviour is controlled by a per-device config flag, 'ngs_disable_inactive_ports'. Change-Id: Ibdbb871d7f3e9ad0d3ade1049cc09a2da5e36fab Story: 2003391 Task: 24511
Notes
Notes (review): Code-Review+2: Julia Kreger <juliaashleykreger@gmail.com> Code-Review+2: Dmitry Tantsur <divius.inside@gmail.com> Workflow+1: Dmitry Tantsur <divius.inside@gmail.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Mon, 01 Oct 2018 13:15:06 +0000 Reviewed-on: https://review.openstack.org/598996 Project: openstack/networking-generic-switch Branch: refs/heads/master
-rw-r--r--networking_generic_switch/devices/__init__.py13
-rw-r--r--networking_generic_switch/devices/netmiko_devices/__init__.py8
-rw-r--r--networking_generic_switch/tests/unit/netmiko/test_netmiko_base.py24
-rw-r--r--releasenotes/notes/disable-inactive-ports-bd6c42ceb232aab2.yaml7
4 files changed, 51 insertions, 1 deletions
diff --git a/networking_generic_switch/devices/__init__.py b/networking_generic_switch/devices/__init__.py
index 6ca744e..12c6831 100644
--- a/networking_generic_switch/devices/__init__.py
+++ b/networking_generic_switch/devices/__init__.py
@@ -34,7 +34,9 @@ NGS_INTERNAL_OPTS = [
34 {'name': 'ngs_ssh_connect_timeout', 'default': 60}, 34 {'name': 'ngs_ssh_connect_timeout', 'default': 60},
35 {'name': 'ngs_ssh_connect_interval', 'default': 10}, 35 {'name': 'ngs_ssh_connect_interval', 'default': 10},
36 {'name': 'ngs_max_connections', 'default': 1}, 36 {'name': 'ngs_max_connections', 'default': 1},
37 {'name': 'ngs_switchport_mode', 'default': 'access'} 37 {'name': 'ngs_switchport_mode', 'default': 'access'},
38 # If True, disable switch ports that are not in use.
39 {'name': 'ngs_disable_inactive_ports', 'default': False},
38] 40]
39 41
40 42
@@ -97,6 +99,15 @@ class GenericSwitchDevice(object):
97 return [] 99 return []
98 return physnets.split(',') 100 return physnets.split(',')
99 101
102 @staticmethod
103 def _str_to_bool(value):
104 truthy = ('true', 'yes', '1')
105 return str(value).lower() in truthy
106
107 def _disable_inactive_ports(self):
108 """Return whether inactive ports should be disabled."""
109 return self._str_to_bool(self.ngs_config['ngs_disable_inactive_ports'])
110
100 @abc.abstractmethod 111 @abc.abstractmethod
101 def add_network(self, segmentation_id, network_id): 112 def add_network(self, segmentation_id, network_id):
102 pass 113 pass
diff --git a/networking_generic_switch/devices/netmiko_devices/__init__.py b/networking_generic_switch/devices/netmiko_devices/__init__.py
index 5e4900d..57d8e2a 100644
--- a/networking_generic_switch/devices/netmiko_devices/__init__.py
+++ b/networking_generic_switch/devices/netmiko_devices/__init__.py
@@ -73,6 +73,10 @@ class NetmikoSwitch(devices.GenericSwitchDevice):
73 73
74 REMOVE_NETWORK_FROM_TRUNK = None 74 REMOVE_NETWORK_FROM_TRUNK = None
75 75
76 ENABLE_PORT = None
77
78 DISABLE_PORT = None
79
76 SAVE_CONFIGURATION = None 80 SAVE_CONFIGURATION = None
77 81
78 ERROR_MSG_PATTERNS = () 82 ERROR_MSG_PATTERNS = ()
@@ -217,6 +221,8 @@ class NetmikoSwitch(devices.GenericSwitchDevice):
217 @check_output('plug port') 221 @check_output('plug port')
218 def plug_port_to_network(self, port, segmentation_id): 222 def plug_port_to_network(self, port, segmentation_id):
219 cmds = [] 223 cmds = []
224 if self._disable_inactive_ports() and self.ENABLE_PORT:
225 cmds += self._format_commands(self.ENABLE_PORT, port=port)
220 ngs_port_default_vlan = self._get_port_default_vlan() 226 ngs_port_default_vlan = self._get_port_default_vlan()
221 if ngs_port_default_vlan: 227 if ngs_port_default_vlan:
222 cmds += self._format_commands( 228 cmds += self._format_commands(
@@ -244,6 +250,8 @@ class NetmikoSwitch(devices.GenericSwitchDevice):
244 self.PLUG_PORT_TO_NETWORK, 250 self.PLUG_PORT_TO_NETWORK,
245 port=port, 251 port=port,
246 segmentation_id=ngs_port_default_vlan) 252 segmentation_id=ngs_port_default_vlan)
253 if self._disable_inactive_ports() and self.DISABLE_PORT:
254 cmds += self._format_commands(self.DISABLE_PORT, port=port)
247 return self.send_commands_to_device(cmds) 255 return self.send_commands_to_device(cmds)
248 256
249 def send_config_set(self, net_connect, cmd_set): 257 def send_config_set(self, net_connect, cmd_set):
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 b1fb934..95aba66 100644
--- a/networking_generic_switch/tests/unit/netmiko/test_netmiko_base.py
+++ b/networking_generic_switch/tests/unit/netmiko/test_netmiko_base.py
@@ -114,6 +114,18 @@ class TestNetmikoSwitch(NetmikoSwitchTestBase):
114 return_value='fake output') 114 return_value='fake output')
115 @mock.patch('networking_generic_switch.devices.netmiko_devices.' 115 @mock.patch('networking_generic_switch.devices.netmiko_devices.'
116 'NetmikoSwitch.check_output') 116 'NetmikoSwitch.check_output')
117 def test_plug_port_to_network_disable_inactive(self, m_check, m_sctd):
118 switch = self._make_switch_device(
119 {'ngs_disable_inactive_ports': 'true'})
120 switch.plug_port_to_network(2222, 22)
121 m_sctd.assert_called_with([])
122 m_check.assert_called_once_with('fake output', 'plug port')
123
124 @mock.patch('networking_generic_switch.devices.netmiko_devices.'
125 'NetmikoSwitch.send_commands_to_device',
126 return_value='fake output')
127 @mock.patch('networking_generic_switch.devices.netmiko_devices.'
128 'NetmikoSwitch.check_output')
117 def test_delete_port(self, m_check, m_sctd): 129 def test_delete_port(self, m_check, m_sctd):
118 self.switch.delete_port(2222, 22) 130 self.switch.delete_port(2222, 22)
119 m_sctd.assert_called_with([]) 131 m_sctd.assert_called_with([])
@@ -130,6 +142,18 @@ class TestNetmikoSwitch(NetmikoSwitchTestBase):
130 m_sctd.assert_called_with([]) 142 m_sctd.assert_called_with([])
131 m_check.assert_called_once_with('fake output', 'unplug port') 143 m_check.assert_called_once_with('fake output', 'unplug port')
132 144
145 @mock.patch('networking_generic_switch.devices.netmiko_devices.'
146 'NetmikoSwitch.send_commands_to_device',
147 return_value='fake output')
148 @mock.patch('networking_generic_switch.devices.netmiko_devices.'
149 'NetmikoSwitch.check_output')
150 def test_delete_port_disable_inactive(self, m_check, m_sctd):
151 switch = self._make_switch_device(
152 {'ngs_disable_inactive_ports': 'true'})
153 switch.delete_port(2222, 22)
154 m_sctd.assert_called_with([])
155 m_check.assert_called_once_with('fake output', 'unplug port')
156
133 def test__format_commands(self): 157 def test__format_commands(self):
134 self.switch._format_commands( 158 self.switch._format_commands(
135 netmiko_devices.NetmikoSwitch.ADD_NETWORK, 159 netmiko_devices.NetmikoSwitch.ADD_NETWORK,
diff --git a/releasenotes/notes/disable-inactive-ports-bd6c42ceb232aab2.yaml b/releasenotes/notes/disable-inactive-ports-bd6c42ceb232aab2.yaml
new file mode 100644
index 0000000..3e6e67c
--- /dev/null
+++ b/releasenotes/notes/disable-inactive-ports-bd6c42ceb232aab2.yaml
@@ -0,0 +1,7 @@
1---
2features:
3 - |
4 Adds support for disabling inactive switch interfaces. This is configured
5 on a per-device basis using the ``ngs_disable_inactive_ports`` flag. See
6 `Story 2003391 <https://storyboard.openstack.org/#!/story/2003391>`__ for
7 details.