blob: d4fcf6fda14572e51c1a20df2d92e78bc73259dc [file] [log] [blame]
Kevin Bentona305d592016-09-19 04:26:10 -07001# All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
Federico Ressi06ef8542018-10-25 15:23:52 +020015import collections
16
17from neutron_lib import constants
Slawek Kaplonskic12b50c2020-11-09 11:58:46 +010018from neutron_lib.utils import test
Kevin Benton07c90562017-02-27 01:53:16 -080019from oslo_log import log as logging
Chandan Kumarc125fd12017-11-15 19:41:01 +053020from tempest.common import utils as tutils
Itzik Brownbac51dc2016-10-31 12:25:04 +000021from tempest.lib.common.utils import data_utils
Sławek Kapłońskic0caa2e2017-02-25 10:11:32 +000022from tempest.lib import decorators
Genadi Chereshnyae91b69c2017-07-16 09:51:58 +030023import testtools
Kevin Bentona305d592016-09-19 04:26:10 -070024
Federico Ressi06ef8542018-10-25 15:23:52 +020025from neutron_tempest_plugin.common import ip
Chandan Kumar667d3d32017-09-22 12:24:06 +053026from neutron_tempest_plugin.common import ssh
27from neutron_tempest_plugin.common import utils
28from neutron_tempest_plugin import config
29from neutron_tempest_plugin.scenario import base
Federico Ressi06ef8542018-10-25 15:23:52 +020030
Kevin Bentona305d592016-09-19 04:26:10 -070031
Kevin Benton07c90562017-02-27 01:53:16 -080032LOG = logging.getLogger(__name__)
Kevin Bentona305d592016-09-19 04:26:10 -070033CONF = config.CONF
Kevin Bentona305d592016-09-19 04:26:10 -070034
Federico Ressi06ef8542018-10-25 15:23:52 +020035
36ServerWithTrunkPort = collections.namedtuple(
37 'ServerWithTrunkPort',
38 ['port', 'subport', 'trunk', 'floating_ip', 'server',
39 'ssh_client'])
Jakub Libosvar6d397d32016-12-30 10:57:52 -050040
41
Kevin Bentona305d592016-09-19 04:26:10 -070042class TrunkTest(base.BaseTempestTestCase):
Alex Katzbaf14a52020-03-05 11:31:19 +020043 credentials = ['primary', 'admin']
Kevin Bentona305d592016-09-19 04:26:10 -070044 force_tenant_isolation = False
45
46 @classmethod
Chandan Kumarc125fd12017-11-15 19:41:01 +053047 @tutils.requires_ext(extension="trunk", service="network")
Kevin Bentona305d592016-09-19 04:26:10 -070048 def resource_setup(cls):
49 super(TrunkTest, cls).resource_setup()
50 # setup basic topology for servers we can log into
Federico Ressi06ef8542018-10-25 15:23:52 +020051 cls.rand_name = data_utils.rand_name(
52 cls.__name__.rsplit('.', 1)[-1])
53 cls.network = cls.create_network(name=cls.rand_name)
54 cls.subnet = cls.create_subnet(network=cls.network,
55 name=cls.rand_name)
Huifeng Le1c9f40b2018-11-07 01:14:21 +080056 cls.router = cls.create_router_by_client()
57 cls.create_router_interface(cls.router['id'], cls.subnet['id'])
Federico Ressi06ef8542018-10-25 15:23:52 +020058 cls.keypair = cls.create_keypair(name=cls.rand_name)
Kevin Bentona305d592016-09-19 04:26:10 -070059
Federico Ressi06ef8542018-10-25 15:23:52 +020060 def setUp(self):
61 super(TrunkTest, self).setUp()
62 self.security_group = self.create_security_group(name=self.rand_name)
63 self.create_loginable_secgroup_rule(self.security_group['id'])
Kevin Bentona305d592016-09-19 04:26:10 -070064
Federico Ressi06ef8542018-10-25 15:23:52 +020065 def _create_server_with_network(self, network, use_advanced_image=False):
66 port = self._create_server_port(network=network)
67 floating_ip = self.create_floatingip(port=port)
68 ssh_client = self._create_ssh_client(
69 floating_ip=floating_ip, use_advanced_image=use_advanced_image)
70 server = self._create_server(port=port,
71 use_advanced_image=use_advanced_image)
72 return ServerWithTrunkPort(port=port, subport=None, trunk=None,
73 floating_ip=floating_ip, server=server,
74 ssh_client=ssh_client)
75
76 def _create_server_with_trunk_port(self, subport_network=None,
77 segmentation_id=None,
78 use_advanced_image=False):
79 port = self._create_server_port()
80 floating_ip = self.create_floatingip(port=port)
81 ssh_client = self._create_ssh_client(
82 floating_ip=floating_ip, use_advanced_image=use_advanced_image)
83
84 subport = None
85 subports = None
86 if subport_network:
87 subport = self._create_server_port(
88 network=subport_network, mac_address=port['mac_address'])
89 subports = [{'port_id': subport['id'],
90 'segmentation_type': 'vlan',
91 'segmentation_id': segmentation_id}]
92 trunk = self.create_trunk(port=port, subports=subports)
93
94 server = self._create_server(port=port,
95 use_advanced_image=use_advanced_image)
96 return ServerWithTrunkPort(port=port, subport=subport, trunk=trunk,
97 floating_ip=floating_ip, server=server,
98 ssh_client=ssh_client)
99
Yarboa11b68922021-01-07 13:03:35 +0200100 def _create_advanced_servers_with_trunk_port(self, num_servers=1,
101 subport_network=None,
102 segmentation_id=None,
103 vlan_subnet=None,
104 use_advanced_image=False):
105 server_list = []
106 for _ in range(0, num_servers):
107 vm = self._create_server_with_trunk_port(
108 subport_network,
109 segmentation_id,
110 use_advanced_image)
111 server_list.append(vm)
112 self._configure_vlan_subport(
113 vm=vm,
114 vlan_tag=segmentation_id,
115 vlan_subnet=vlan_subnet)
116
Yarboa11b68922021-01-07 13:03:35 +0200117 return server_list
118
119 def _check_servers_remote_connectivity(self, vms=None,
120 should_succeed=True):
121 self.check_remote_connectivity(
122 vms[0].ssh_client,
123 vms[1].subport['fixed_ips'][0]['ip_address'],
124 should_succeed=should_succeed)
125
Federico Ressi06ef8542018-10-25 15:23:52 +0200126 def _create_server_port(self, network=None, **params):
127 network = network or self.network
128 return self.create_port(network=network, name=self.rand_name,
129 security_groups=[self.security_group['id']],
130 **params)
131
132 def _create_server(self, port, use_advanced_image=False, **params):
Slawek Kaplonskida17f002018-10-11 18:35:23 +0200133 if use_advanced_image:
134 flavor_ref = CONF.neutron_plugin_options.advanced_image_flavor_ref
135 image_ref = CONF.neutron_plugin_options.advanced_image_ref
Federico Ressi06ef8542018-10-25 15:23:52 +0200136 else:
137 flavor_ref = CONF.compute.flavor_ref
138 image_ref = CONF.compute.image_ref
139 return self.create_server(flavor_ref=flavor_ref,
140 image_ref=image_ref,
141 key_name=self.keypair['name'],
142 networks=[{'port': port['id']}],
143 **params)['server']
Jakub Libosvar6d397d32016-12-30 10:57:52 -0500144
Federico Ressi06ef8542018-10-25 15:23:52 +0200145 def _show_port(self, port, update=False):
146 observed = self.client.show_port(port['id'])['port']
147 if update:
148 port.update(observed)
149 return observed
Kevin Bentona305d592016-09-19 04:26:10 -0700150
Federico Ressi06ef8542018-10-25 15:23:52 +0200151 def _show_trunk(self, trunk, update=False):
152 observed = self.client.show_trunk(trunk['id'])['trunk']
153 if update:
154 trunk.update(observed)
155 return observed
Kevin Bentona305d592016-09-19 04:26:10 -0700156
Federico Ressi06ef8542018-10-25 15:23:52 +0200157 def _is_trunk_status(self, trunk, status, update=False):
158 return self._show_trunk(trunk, update)['status'] == status
Kevin Bentona305d592016-09-19 04:26:10 -0700159
Federico Ressi06ef8542018-10-25 15:23:52 +0200160 def _is_port_status(self, port, status, update=False):
161 return self._show_port(port, update)['status'] == status
162
163 def _wait_for_port(self, port, status=constants.ACTIVE):
164 utils.wait_until_true(
165 lambda: self._is_port_status(port, status),
166 exception=RuntimeError(
Brian Haley07144862024-10-16 14:34:53 -0400167 "Timed out waiting for port {!r} to transition to "
Federico Ressi06ef8542018-10-25 15:23:52 +0200168 "status {!r}.".format(port['id'], status)))
169
170 def _wait_for_trunk(self, trunk, status=constants.ACTIVE):
171 utils.wait_until_true(
172 lambda: self._is_trunk_status(trunk, status),
173 exception=RuntimeError(
Brian Haley07144862024-10-16 14:34:53 -0400174 "Timed out waiting for trunk {!r} to transition to "
Federico Ressi06ef8542018-10-25 15:23:52 +0200175 "status {!r}.".format(trunk['id'], status)))
176
177 def _create_ssh_client(self, floating_ip, use_advanced_image=False):
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800178 if use_advanced_image:
Federico Ressi06ef8542018-10-25 15:23:52 +0200179 username = CONF.neutron_plugin_options.advanced_image_ssh_user
180 else:
181 username = CONF.validation.image_ssh_user
182 return ssh.Client(host=floating_ip['floating_ip_address'],
183 username=username,
184 pkey=self.keypair['private_key'])
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800185
Federico Ressi06ef8542018-10-25 15:23:52 +0200186 def _assert_has_ssh_connectivity(self, ssh_client):
187 ssh_client.exec_command("true")
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800188
Federico Ressi06ef8542018-10-25 15:23:52 +0200189 def _configure_vlan_subport(self, vm, vlan_tag, vlan_subnet):
190 self.wait_for_server_active(server=vm.server)
Slawek Kaplonski2211eab2020-10-20 16:43:53 +0200191 self.wait_for_guest_os_ready(vm.server)
Federico Ressi06ef8542018-10-25 15:23:52 +0200192 self._wait_for_trunk(trunk=vm.trunk)
193 self._wait_for_port(port=vm.port)
194 self._wait_for_port(port=vm.subport)
yatinkarelc4597e62021-11-26 14:09:18 +0530195 self.check_connectivity(
yatinkarelc4597e62021-11-26 14:09:18 +0530196 ssh_client=vm.ssh_client,
197 servers=[vm.server])
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800198
Federico Ressi06ef8542018-10-25 15:23:52 +0200199 ip_command = ip.IPCommand(ssh_client=vm.ssh_client)
200 for address in ip_command.list_addresses(port=vm.port):
201 port_iface = address.device.name
202 break
203 else:
204 self.fail("Parent port fixed IP not found on server.")
Jakub Libosvar6d397d32016-12-30 10:57:52 -0500205
Federico Ressi06ef8542018-10-25 15:23:52 +0200206 subport_iface = ip_command.configure_vlan_subport(
207 port=vm.port, subport=vm.subport, vlan_tag=vlan_tag,
208 subnets=[vlan_subnet])
209 for address in ip_command.list_addresses(port=vm.subport):
210 self.assertEqual(subport_iface, address.device.name)
211 self.assertEqual(port_iface, address.device.parent)
212 break
213 else:
214 self.fail("Sub-port fixed IP not found on server.")
Jakub Libosvar6d397d32016-12-30 10:57:52 -0500215
Sławek Kapłońskic0caa2e2017-02-25 10:11:32 +0000216 @decorators.idempotent_id('bb13fe28-f152-4000-8131-37890a40c79e')
Kevin Bentona305d592016-09-19 04:26:10 -0700217 def test_trunk_subport_lifecycle(self):
218 """Test trunk creation and subport transition to ACTIVE status.
219
220 This is a basic test for the trunk extension to ensure that we
221 can create a trunk, attach it to a server, add/remove subports,
222 while ensuring the status transitions as appropriate.
223
224 This test does not assert any dataplane behavior for the subports.
225 It's just a high-level check to ensure the agents claim to have
226 wired the port correctly and that the trunk port itself maintains
227 connectivity.
228 """
Federico Ressi06ef8542018-10-25 15:23:52 +0200229 vm1 = self._create_server_with_trunk_port()
230 vm2 = self._create_server_with_trunk_port()
231 for vm in (vm1, vm2):
232 self.wait_for_server_active(server=vm.server)
Slawek Kaplonski2211eab2020-10-20 16:43:53 +0200233 self.wait_for_guest_os_ready(vm.server)
Federico Ressi06ef8542018-10-25 15:23:52 +0200234 self._wait_for_trunk(vm.trunk)
235 self._assert_has_ssh_connectivity(vm.ssh_client)
236
Kevin Bentona305d592016-09-19 04:26:10 -0700237 # create a few more networks and ports for subports
Yariv Rachmanifed6f862017-12-19 11:55:25 +0200238 # check limit of networks per project
Federico Ressi06ef8542018-10-25 15:23:52 +0200239 segment_ids = range(
240 3, 3 + CONF.neutron_plugin_options.max_networks_per_project)
241 tagged_networks = [self.create_network() for _ in segment_ids]
242 tagged_ports = [self.create_port(network=network)
243 for network in tagged_networks]
244 subports = [{'port_id': tagged_ports[i]['id'],
245 'segmentation_type': 'vlan',
246 'segmentation_id': segment_id}
247 for i, segment_id in enumerate(segment_ids)]
Jakub Libosvar6d397d32016-12-30 10:57:52 -0500248
Federico Ressi06ef8542018-10-25 15:23:52 +0200249 # add all subports to server1
250 self.client.add_subports(vm1.trunk['id'], subports)
251 self._wait_for_trunk(vm1.trunk)
252 for port in tagged_ports:
253 self._wait_for_port(port)
254
255 # ensure main data-plane wasn't interrupted
256 self._assert_has_ssh_connectivity(vm1.ssh_client)
257
258 # move subports over to other server
259 self.client.remove_subports(vm1.trunk['id'], subports)
260 # ensure all subports go down
261 for port in tagged_ports:
262 self._wait_for_port(port, status=constants.DOWN)
263
264 self.client.add_subports(vm2.trunk['id'], subports)
265
266 # wait for both trunks to go back to ACTIVE
267 for vm in [vm1, vm2]:
268 self._wait_for_trunk(vm.trunk)
269
270 # ensure subports come up on other trunk
271 for port in tagged_ports:
272 self._wait_for_port(port)
273
274 # final connectivity check
275 for vm in [vm1, vm2]:
276 self._wait_for_trunk(vm.trunk)
277 self._assert_has_ssh_connectivity(vm1.ssh_client)
278
Rodolfo Alonso Hernandez370f71e2023-09-09 21:33:55 +0000279 @test.unstable_test("bug 2033887 / bug 2024160")
Yarboa11b68922021-01-07 13:03:35 +0200280 @testtools.skipUnless(
281 (CONF.neutron_plugin_options.advanced_image_ref or
282 CONF.neutron_plugin_options.default_image_is_advanced),
283 "Advanced image is required to run this test.")
284 @testtools.skipUnless(
285 (CONF.neutron_plugin_options.reboots_in_test > 0),
286 "Number of reboots > 0 is reqired for this test")
287 @decorators.idempotent_id('a8a02c9b-b453-49b5-89a2-cce7da6680fb')
288 def test_subport_connectivity_soft_reboot(self):
289 vlan_tag = 10
290 vlan_network = self.create_network()
291 vlan_subnet = self.create_subnet(network=vlan_network, gateway=None)
292 use_advanced_image = (
293 not CONF.neutron_plugin_options.default_image_is_advanced)
294
295 # allow intra-security-group traffic
296 sg_rule = self.create_pingable_secgroup_rule(self.security_group['id'])
297 self.addCleanup(
298 self.os_primary.network_client.delete_security_group_rule,
299 sg_rule['id'])
300
301 vms = self._create_advanced_servers_with_trunk_port(
302 num_servers=2,
303 subport_network=vlan_network,
304 segmentation_id=vlan_tag,
305 vlan_subnet=vlan_subnet,
306 use_advanced_image=use_advanced_image)
307 # check remote connectivity true before reboots
308 self._check_servers_remote_connectivity(vms=vms)
309 client = self.os_tempest.compute.ServersClient()
310 for _ in range(CONF.neutron_plugin_options.reboots_in_test):
311 client.reboot_server(vms[1].server['id'],
312 **{'type': 'SOFT'})
313 self.wait_for_server_active(vms[1].server)
314 self._configure_vlan_subport(vm=vms[1],
315 vlan_tag=vlan_tag,
316 vlan_subnet=vlan_subnet)
317 self._check_servers_remote_connectivity(vms=vms)
318
Slawek Kaplonskic12b50c2020-11-09 11:58:46 +0100319 @test.unstable_test("bug 1897796")
Yariv Rachmanifa1081a2018-11-21 12:46:57 +0200320 @testtools.skipUnless(
321 (CONF.neutron_plugin_options.advanced_image_ref or
322 CONF.neutron_plugin_options.default_image_is_advanced),
323 "Advanced image is required to run this test.")
Yarboa11b68922021-01-07 13:03:35 +0200324 @decorators.idempotent_id('a8a02c9b-b453-49b5-89a2-cce7da66bbcb')
Jakub Libosvar6d397d32016-12-30 10:57:52 -0500325 def test_subport_connectivity(self):
326 vlan_tag = 10
Jakub Libosvar6d397d32016-12-30 10:57:52 -0500327 vlan_network = self.create_network()
Federico Ressi06ef8542018-10-25 15:23:52 +0200328 vlan_subnet = self.create_subnet(network=vlan_network, gateway=None)
Yariv Rachmanifa1081a2018-11-21 12:46:57 +0200329 use_advanced_image = (
330 not CONF.neutron_plugin_options.default_image_is_advanced)
Yarboa11b68922021-01-07 13:03:35 +0200331 vms = self._create_advanced_servers_with_trunk_port(
332 num_servers=2,
Yariv Rachmanifa1081a2018-11-21 12:46:57 +0200333 subport_network=vlan_network,
334 segmentation_id=vlan_tag,
Yarboa11b68922021-01-07 13:03:35 +0200335 vlan_subnet=vlan_subnet,
Yariv Rachmanifa1081a2018-11-21 12:46:57 +0200336 use_advanced_image=use_advanced_image)
Kevin Benton6f1f9d52017-03-01 09:14:45 -0800337 # Ping from server1 to server2 via VLAN interface should fail because
338 # we haven't allowed ICMP
Yarboa11b68922021-01-07 13:03:35 +0200339 self._check_servers_remote_connectivity(vms=vms,
340 should_succeed=False)
Federico Ressi06ef8542018-10-25 15:23:52 +0200341 # allow intra-security-group traffic
Alex Katzbaf14a52020-03-05 11:31:19 +0200342 sg_rule = self.create_pingable_secgroup_rule(self.security_group['id'])
343 self.addCleanup(
344 self.os_primary.network_client.delete_security_group_rule,
345 sg_rule['id'])
Yarboa11b68922021-01-07 13:03:35 +0200346 self._check_servers_remote_connectivity(vms=vms)
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800347
Alex Katzbaf14a52020-03-05 11:31:19 +0200348 @testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
349 'Cold migration is not available.')
350 @testtools.skipUnless(CONF.compute.min_compute_nodes > 1,
351 'Less than 2 compute nodes, skipping multinode '
352 'tests.')
353 @testtools.skipUnless(
354 (CONF.neutron_plugin_options.advanced_image_ref or
355 CONF.neutron_plugin_options.default_image_is_advanced),
356 "Advanced image is required to run this test.")
357 @decorators.attr(type='slow')
358 @decorators.idempotent_id('ecd7de30-1c90-4280-b97c-1bed776d5d07')
359 def test_trunk_vm_migration(self):
360 '''Test connectivity after migration of the server with trunk
361
362 A successfully migrated server shows a VERIFY_RESIZE status that
363 requires confirmation. Need to reconfigure VLAN interface on server
364 side after migration is finished as the configuration doesn't survive
365 the reboot.
366 '''
367 vlan_tag = 10
368 vlan_network = self.create_network()
369 vlan_subnet = self.create_subnet(vlan_network)
370 sg_rule = self.create_pingable_secgroup_rule(self.security_group['id'])
371 self.addCleanup(
372 self.os_primary.network_client.delete_security_group_rule,
373 sg_rule['id'])
374
375 use_advanced_image = (
376 not CONF.neutron_plugin_options.default_image_is_advanced)
377 servers = {}
378 for role in ['migrate', 'connection_test']:
379 servers[role] = self._create_server_with_trunk_port(
380 subport_network=vlan_network,
381 segmentation_id=vlan_tag,
382 use_advanced_image=use_advanced_image)
383 for role in ['migrate', 'connection_test']:
384 self.wait_for_server_active(servers[role].server)
Slawek Kaplonski2211eab2020-10-20 16:43:53 +0200385 self.wait_for_guest_os_ready(servers[role].server)
Alex Katzbaf14a52020-03-05 11:31:19 +0200386 self._configure_vlan_subport(vm=servers[role],
387 vlan_tag=vlan_tag,
388 vlan_subnet=vlan_subnet)
389
390 self.check_remote_connectivity(
391 servers['connection_test'].ssh_client,
392 servers['migrate'].subport['fixed_ips'][0]['ip_address'])
393
394 client = self.os_admin.compute.ServersClient()
395 client.migrate_server(servers['migrate'].server['id'])
396 self.wait_for_server_status(servers['migrate'].server,
397 'VERIFY_RESIZE')
398 client.confirm_resize_server(servers['migrate'].server['id'])
399 self._configure_vlan_subport(vm=servers['migrate'],
400 vlan_tag=vlan_tag,
401 vlan_subnet=vlan_subnet)
402
403 self.check_remote_connectivity(
404 servers['connection_test'].ssh_client,
405 servers['migrate'].subport['fixed_ips'][0]['ip_address'])
406
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800407 @testtools.skipUnless(
Yariv Rachmanifa1081a2018-11-21 12:46:57 +0200408 (CONF.neutron_plugin_options.advanced_image_ref or
409 CONF.neutron_plugin_options.default_image_is_advanced),
Federico Ressi06ef8542018-10-25 15:23:52 +0200410 "Advanced image is required to run this test.")
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800411 @testtools.skipUnless(
Federico Ressi06ef8542018-10-25 15:23:52 +0200412 CONF.neutron_plugin_options.q_agent == "linuxbridge",
413 "Linux bridge agent is required to run this test.")
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800414 @decorators.idempotent_id('d61cbdf6-1896-491c-b4b4-871caf7fbffe')
415 def test_parent_port_connectivity_after_trunk_deleted_lb(self):
416 vlan_tag = 10
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800417 vlan_network = self.create_network()
418 vlan_subnet = self.create_subnet(vlan_network)
419 self.create_router_interface(self.router['id'], vlan_subnet['id'])
420
Yariv Rachmanifa1081a2018-11-21 12:46:57 +0200421 use_advanced_image = (
422 not CONF.neutron_plugin_options.default_image_is_advanced)
423
Federico Ressi06ef8542018-10-25 15:23:52 +0200424 # Create servers
425 trunk_network_server = self._create_server_with_trunk_port(
426 subport_network=vlan_network,
427 segmentation_id=vlan_tag,
Yariv Rachmanifa1081a2018-11-21 12:46:57 +0200428 use_advanced_image=use_advanced_image)
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800429 normal_network_server = self._create_server_with_network(self.network)
430 vlan_network_server = self._create_server_with_network(vlan_network)
Slawek Kaplonskie58219b2019-12-09 12:10:55 +0100431 vms = [normal_network_server, vlan_network_server]
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800432
Federico Ressi06ef8542018-10-25 15:23:52 +0200433 self._configure_vlan_subport(vm=trunk_network_server,
434 vlan_tag=vlan_tag,
435 vlan_subnet=vlan_subnet)
Slawek Kaplonskie58219b2019-12-09 12:10:55 +0100436 for vm in vms:
Federico Ressi06ef8542018-10-25 15:23:52 +0200437 self.wait_for_server_active(vm.server)
Slawek Kaplonski2211eab2020-10-20 16:43:53 +0200438 self.wait_for_guest_os_ready(vm.server)
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800439
Federico Ressi06ef8542018-10-25 15:23:52 +0200440 # allow ICMP traffic
Alex Katzbaf14a52020-03-05 11:31:19 +0200441 sg_rule = self.create_pingable_secgroup_rule(self.security_group['id'])
442 self.addCleanup(
443 self.os_primary.network_client.delete_security_group_rule,
444 sg_rule['id'])
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800445
446 # Ping from trunk_network_server to normal_network_server
447 # via parent port
448 self.check_remote_connectivity(
Federico Ressi06ef8542018-10-25 15:23:52 +0200449 trunk_network_server.ssh_client,
450 normal_network_server.port['fixed_ips'][0]['ip_address'],
Slawek Kaplonskie58219b2019-12-09 12:10:55 +0100451 should_succeed=True,
452 servers=vms)
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800453
454 # Ping from trunk_network_server to vlan_network_server via VLAN
455 # interface should success
456 self.check_remote_connectivity(
Federico Ressi06ef8542018-10-25 15:23:52 +0200457 trunk_network_server.ssh_client,
458 vlan_network_server.port['fixed_ips'][0]['ip_address'],
Slawek Kaplonskie58219b2019-12-09 12:10:55 +0100459 should_succeed=True,
460 servers=vms)
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800461
462 # Delete the trunk
Federico Ressi06ef8542018-10-25 15:23:52 +0200463 self.delete_trunk(
464 trunk_network_server.trunk,
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800465 detach_parent_port=False)
Federico Ressi06ef8542018-10-25 15:23:52 +0200466 LOG.debug("Trunk %s is deleted.",
467 trunk_network_server.trunk['id'])
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800468
469 # Ping from trunk_network_server to normal_network_server
470 # via parent port success after trunk deleted
471 self.check_remote_connectivity(
Federico Ressi06ef8542018-10-25 15:23:52 +0200472 trunk_network_server.ssh_client,
473 normal_network_server.port['fixed_ips'][0]['ip_address'],
Slawek Kaplonskie58219b2019-12-09 12:10:55 +0100474 should_succeed=True,
475 servers=vms)
Huifeng Le1c9f40b2018-11-07 01:14:21 +0800476
477 # Ping from trunk_network_server to vlan_network_server via VLAN
478 # interface should fail after trunk deleted
479 self.check_remote_connectivity(
Federico Ressi06ef8542018-10-25 15:23:52 +0200480 trunk_network_server.ssh_client,
481 vlan_network_server.port['fixed_ips'][0]['ip_address'],
482 should_succeed=False)