Skip to content

Commit 5098525

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Adds vlan aware VMs support for Cumulus NVUE and DellOS10"
2 parents 5354d91 + 1b53447 commit 5098525

5 files changed

Lines changed: 365 additions & 4 deletions

File tree

networking_generic_switch/devices/netmiko_devices/cumulus.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,67 @@ class CumulusNVUE(netmiko_devices.NetmikoSwitch):
117117
]
118118

119119
PLUG_PORT_TO_NETWORK = [
120+
'nv unset interface {port} bridge domain br_default untagged',
120121
'nv set interface {port} bridge domain br_default access '
121122
'{segmentation_id}',
122123
]
123124

125+
ADD_NETWORK_TO_TRUNK = [
126+
'nv unset interface {port} bridge domain br_default access',
127+
'nv set interface {port} bridge domain br_default vlan '
128+
'{segmentation_id}',
129+
]
130+
131+
ADD_NETWORK_TO_BOND_TRUNK = [
132+
'nv unset interface {bond} bridge domain br_default access',
133+
'nv set interface {bond} bridge domain br_default vlan '
134+
'{segmentation_id}',
135+
]
136+
137+
REMOVE_NETWORK_FROM_TRUNK = (
138+
'nv unset interface {port} bridge domain br_default vlan '
139+
'{segmentation_id}',
140+
)
141+
142+
DELETE_NETWORK_ON_BOND_TRUNK = (
143+
'nv unset interface {bond} bridge domain br_default vlan '
144+
'{segmentation_id}',
145+
)
146+
147+
SET_NATIVE_VLAN = [
148+
'nv unset interface {port} bridge domain br_default access',
149+
'nv set interface {port} bridge domain br_default untagged '
150+
'{segmentation_id}',
151+
'nv set interface {port} bridge domain br_default vlan '
152+
'{segmentation_id}',
153+
]
154+
155+
SET_NATIVE_VLAN_BOND = [
156+
'nv unset interface {bond} bridge domain br_default access',
157+
'nv set interface {bond} bridge domain br_default untagged '
158+
'{segmentation_id}',
159+
'nv set interface {bond} bridge domain br_default vlan '
160+
'{segmentation_id}',
161+
]
162+
163+
DELETE_NATIVE_VLAN = (
164+
'nv unset interface {port} bridge domain br_default untagged '
165+
'{segmentation_id}',
166+
'nv unset interface {port} bridge domain br_default vlan '
167+
'{segmentation_id}',
168+
)
169+
170+
DELETE_NATIVE_VLAN_BOND = (
171+
'nv unset interface {bond} bridge domain br_default untagged '
172+
'{segmentation_id}',
173+
'nv unset interface {bond} bridge domain br_default vlan '
174+
'{segmentation_id}',
175+
)
176+
124177
DELETE_PORT = [
125178
'nv unset interface {port} bridge domain br_default access',
179+
'nv unset interface {port} bridge domain br_default untagged',
180+
'nv unset interface {port} bridge domain br_default vlan',
126181
]
127182

128183
ENABLE_PORT = [

networking_generic_switch/devices/netmiko_devices/dell.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@ class DellOS10(netmiko_devices.NetmikoSwitch):
5858
"exit",
5959
)
6060

61+
SET_NATIVE_VLAN = (
62+
'interface {port}',
63+
'switchport mode trunk',
64+
'switchport access vlan {segmentation_id}',
65+
)
66+
67+
DELETE_NATIVE_VLAN = (
68+
'interface {port}',
69+
'no switchport access vlan',
70+
)
71+
6172
ENABLE_PORT = (
6273
"interface {port}",
6374
"no shutdown",

networking_generic_switch/tests/unit/netmiko/test_cumulus_nvue.py

Lines changed: 154 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
from unittest import mock
1616

17+
from oslo_utils import uuidutils
18+
1719
from networking_generic_switch.devices.netmiko_devices import cumulus
1820
from networking_generic_switch import exceptions as exc
1921
from networking_generic_switch.tests.unit.netmiko import test_netmiko_base
@@ -57,6 +59,9 @@ def test_plug_port_to_network(self, mock_exec):
5759
self.switch,
5860
['nv set interface 3333 link state up',
5961
'nv unset interface 3333 bridge domain br_default access',
62+
'nv unset interface 3333 bridge domain br_default untagged',
63+
'nv unset interface 3333 bridge domain br_default vlan',
64+
'nv unset interface 3333 bridge domain br_default untagged',
6065
'nv set interface 3333 bridge domain br_default access 33'])
6166

6267
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
@@ -89,7 +94,8 @@ def test_plug_port_simple(self, mock_exec):
8994
switch.plug_port_to_network(3333, 33)
9095
mock_exec.assert_called_with(
9196
switch,
92-
['nv set interface 3333 bridge domain br_default access 33'])
97+
['nv unset interface 3333 bridge domain br_default untagged',
98+
'nv set interface 3333 bridge domain br_default access 33'])
9399

94100
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
95101
'NetmikoSwitch.send_commands_to_device',
@@ -99,7 +105,10 @@ def test_delete_port(self, mock_exec):
99105
mock_exec.assert_called_with(
100106
self.switch,
101107
['nv unset interface 3333 bridge domain br_default access',
108+
'nv unset interface 3333 bridge domain br_default untagged',
109+
'nv unset interface 3333 bridge domain br_default vlan',
102110
'nv set bridge domain br_default vlan 123',
111+
'nv unset interface 3333 bridge domain br_default untagged',
103112
'nv set interface 3333 bridge domain br_default access 123',
104113
'nv set interface 3333 link state down'])
105114

@@ -114,7 +123,9 @@ def test_delete_port_simple(self, mock_exec):
114123
switch.delete_port(3333, 33)
115124
mock_exec.assert_called_with(
116125
switch,
117-
['nv unset interface 3333 bridge domain br_default access'])
126+
['nv unset interface 3333 bridge domain br_default access',
127+
'nv unset interface 3333 bridge domain br_default untagged',
128+
'nv unset interface 3333 bridge domain br_default vlan'])
118129

119130
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
120131
'NetmikoSwitch.send_commands_to_device',
@@ -125,6 +136,9 @@ def test_plug_bond_to_network(self, mock_exec):
125136
self.switch,
126137
['nv set interface 3333 link state up',
127138
'nv unset interface 3333 bridge domain br_default access',
139+
'nv unset interface 3333 bridge domain br_default untagged',
140+
'nv unset interface 3333 bridge domain br_default vlan',
141+
'nv unset interface 3333 bridge domain br_default untagged',
128142
'nv set interface 3333 bridge domain br_default access 33'])
129143

130144
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
@@ -138,7 +152,8 @@ def test_plug_bond_simple(self, mock_exec):
138152
switch.plug_bond_to_network(3333, 33)
139153
mock_exec.assert_called_with(
140154
switch,
141-
['nv set interface 3333 bridge domain br_default access 33'])
155+
['nv unset interface 3333 bridge domain br_default untagged',
156+
'nv set interface 3333 bridge domain br_default access 33'])
142157

143158
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
144159
'NetmikoSwitch.send_commands_to_device',
@@ -148,7 +163,10 @@ def test_unplug_bond_from_network(self, mock_exec):
148163
mock_exec.assert_called_with(
149164
self.switch,
150165
['nv unset interface 3333 bridge domain br_default access',
166+
'nv unset interface 3333 bridge domain br_default untagged',
167+
'nv unset interface 3333 bridge domain br_default vlan',
151168
'nv set bridge domain br_default vlan 123',
169+
'nv unset interface 3333 bridge domain br_default untagged',
152170
'nv set interface 3333 bridge domain br_default access 123',
153171
'nv set interface 3333 link state down'])
154172

@@ -163,10 +181,142 @@ def test_unplug_bond_from_network_simple(self, mock_exec):
163181
switch.unplug_bond_from_network(3333, 33)
164182
mock_exec.assert_called_with(
165183
switch,
166-
['nv unset interface 3333 bridge domain br_default access'])
184+
['nv unset interface 3333 bridge domain br_default access',
185+
'nv unset interface 3333 bridge domain br_default untagged',
186+
'nv unset interface 3333 bridge domain br_default vlan'])
167187

168188
def test_save(self):
169189
mock_connect = mock.MagicMock()
170190
mock_connect.save_config.side_effect = NotImplementedError
171191
self.switch.save_configuration(mock_connect)
172192
mock_connect.send_command.assert_called_with('nv config save')
193+
194+
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
195+
'NetmikoSwitch.send_commands_to_device', autospec=True)
196+
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
197+
'NetmikoSwitch.check_output', autospec=True)
198+
def test_plug_port_to_network_subports(self, _, mock_exec):
199+
trunk_details = {"sub_ports": [{"segmentation_id": "tag1"},
200+
{"segmentation_id": "tag2"}]}
201+
self.switch.plug_port_to_network(4444, 44, trunk_details=trunk_details)
202+
mock_exec.assert_called_with(
203+
self.switch,
204+
['nv set interface 4444 link state up',
205+
'nv unset interface 4444 bridge domain br_default access',
206+
'nv unset interface 4444 bridge domain br_default untagged',
207+
'nv unset interface 4444 bridge domain br_default vlan',
208+
'nv unset interface 4444 bridge domain br_default access',
209+
'nv set interface 4444 bridge domain br_default untagged 44',
210+
'nv set interface 4444 bridge domain br_default vlan 44',
211+
'nv unset interface 4444 bridge domain br_default access',
212+
'nv set interface 4444 bridge domain br_default vlan tag1',
213+
'nv unset interface 4444 bridge domain br_default access',
214+
'nv set interface 4444 bridge domain br_default vlan tag2'])
215+
216+
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
217+
'NetmikoSwitch.send_commands_to_device', autospec=True)
218+
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
219+
'NetmikoSwitch.check_output', autospec=True)
220+
def test_delete_port_subports(self, _, mock_exec):
221+
trunk_details = {"sub_ports": [{"segmentation_id": "tag1"},
222+
{"segmentation_id": "tag2"}]}
223+
self.switch.delete_port(4444, 44, trunk_details=trunk_details)
224+
mock_exec.assert_called_with(
225+
self.switch,
226+
['nv unset interface 4444 bridge domain br_default access',
227+
'nv unset interface 4444 bridge domain br_default untagged',
228+
'nv unset interface 4444 bridge domain br_default vlan',
229+
'nv unset interface 4444 bridge domain br_default untagged 44',
230+
'nv unset interface 4444 bridge domain br_default vlan 44',
231+
'nv unset interface 4444 bridge domain br_default vlan tag1',
232+
'nv unset interface 4444 bridge domain br_default vlan tag2',
233+
'nv set bridge domain br_default vlan 123',
234+
'nv unset interface 4444 bridge domain br_default untagged',
235+
'nv set interface 4444 bridge domain br_default access 123',
236+
'nv set interface 4444 link state down'])
237+
238+
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
239+
'NetmikoSwitch.send_commands_to_device', autospec=True)
240+
def test_add_subports_on_trunk_no_subports(self, mock_exec):
241+
port_id = uuidutils.generate_uuid()
242+
parent_port = {
243+
'binding:profile': {
244+
'local_link_information': [
245+
{
246+
'switch_info': 'bar',
247+
'port_id': 2222
248+
}
249+
]},
250+
'binding:vnic_type': 'baremetal',
251+
'id': port_id
252+
}
253+
subports = []
254+
self.switch.add_subports_on_trunk(parent_port, 44, subports=subports)
255+
mock_exec.assert_called_with(self.switch, [])
256+
257+
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
258+
'NetmikoSwitch.send_commands_to_device', autospec=True)
259+
def test_add_subports_on_trunk_subports(self, mock_exec):
260+
port_id = uuidutils.generate_uuid()
261+
parent_port = {
262+
'binding:profile': {
263+
'local_link_information': [
264+
{
265+
'switch_info': 'bar',
266+
'port_id': 2222
267+
}
268+
]},
269+
'binding:vnic_type': 'baremetal',
270+
'id': port_id
271+
}
272+
subports = [{"segmentation_id": "tag1"},
273+
{"segmentation_id": "tag2"}]
274+
self.switch.add_subports_on_trunk(parent_port, 44, subports=subports)
275+
mock_exec.assert_called_with(
276+
self.switch,
277+
['nv unset interface 44 bridge domain br_default access',
278+
'nv set interface 44 bridge domain br_default vlan tag1',
279+
'nv unset interface 44 bridge domain br_default access',
280+
'nv set interface 44 bridge domain br_default vlan tag2'])
281+
282+
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
283+
'NetmikoSwitch.send_commands_to_device', autospec=True)
284+
def test_del_subports_on_trunk_no_subports(self, mock_exec):
285+
port_id = uuidutils.generate_uuid()
286+
parent_port = {
287+
'binding:profile': {
288+
'local_link_information': [
289+
{
290+
'switch_info': 'bar',
291+
'port_id': 2222
292+
}
293+
]},
294+
'binding:vnic_type': 'baremetal',
295+
'id': port_id
296+
}
297+
subports = []
298+
self.switch.del_subports_on_trunk(parent_port, 44, subports=subports)
299+
mock_exec.assert_called_with(self.switch, [])
300+
301+
@mock.patch('networking_generic_switch.devices.netmiko_devices.'
302+
'NetmikoSwitch.send_commands_to_device', autospec=True)
303+
def test_del_subports_on_trunk_subports(self, mock_exec):
304+
port_id = uuidutils.generate_uuid()
305+
parent_port = {
306+
'binding:profile': {
307+
'local_link_information': [
308+
{
309+
'switch_info': 'bar',
310+
'port_id': 2222
311+
}
312+
]},
313+
'binding:vnic_type': 'baremetal',
314+
'id': port_id
315+
}
316+
subports = [{"segmentation_id": "tag1"},
317+
{"segmentation_id": "tag2"}]
318+
self.switch.del_subports_on_trunk(parent_port, 44, subports=subports)
319+
mock_exec.assert_called_with(
320+
self.switch,
321+
['nv unset interface 44 bridge domain br_default vlan tag1',
322+
'nv unset interface 44 bridge domain br_default vlan tag2'])

0 commit comments

Comments
 (0)