blob: 85d7e377664b7308e690d7b8443d59c69af62f67 [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2012 OpenStack Foundation
Gavin Brebner0f465a32013-03-14 13:26:09 +00002# Copyright 2013 Hewlett-Packard Development Company, L.P.
Maru Newby81f07a02012-09-05 20:21:19 -07003# All Rights Reserved.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
Yair Fried2d2f3fe2014-02-24 16:19:20 +020016import collections
Yair Fried3097dc12014-01-26 08:46:43 +020017import re
Matthew Treinish96e9e882014-06-09 18:37:19 -040018
Doug Hellmann583ce2c2015-03-11 14:55:46 +000019from oslo_log import log as logging
Adam Gandelman7186f7a2014-07-23 09:28:56 -040020import testtools
Yair Fried3097dc12014-01-26 08:46:43 +020021
Ken'ichi Ohmichie91a0c62015-08-13 02:09:16 +000022from tempest.common import waiters
Matthew Treinishcb569942013-08-09 16:33:44 -040023from tempest import config
Jordan Pittier9e227c52016-02-09 14:35:18 +010024from tempest.lib.common.utils import test_utils
Sean Dague17487fb2016-08-08 10:44:20 -040025from tempest.lib import decorators
guo yunxianebb15f22016-11-01 21:03:35 +080026from tempest.lib import exceptions
Sean Dague6dbc6da2013-05-08 17:49:46 -040027from tempest.scenario import manager
Yoshihiro Kaneko05670262014-01-18 19:22:44 +090028from tempest import test
Maru Newby81f07a02012-09-05 20:21:19 -070029
Sean Dague86bd8422013-12-20 09:56:44 -050030CONF = config.CONF
Matthew Treinish2b59f842013-09-09 20:32:51 +000031LOG = logging.getLogger(__name__)
32
Yair Fried2d2f3fe2014-02-24 16:19:20 +020033Floating_IP_tuple = collections.namedtuple('Floating_IP_tuple',
34 ['floating_ip', 'server'])
35
Maru Newby81f07a02012-09-05 20:21:19 -070036
Andrea Frittoli4971fc82014-09-25 10:22:20 +010037class TestNetworkBasicOps(manager.NetworkScenarioTest):
Maru Newby81f07a02012-09-05 20:21:19 -070038
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +000039 """The test suite of network basic operations
40
Maru Newby81f07a02012-09-05 20:21:19 -070041 This smoke test suite assumes that Nova has been configured to
Mark McClainf2982e82013-07-06 17:48:03 -040042 boot VM's with Neutron-managed networking, and attempts to
Maru Newby81f07a02012-09-05 20:21:19 -070043 verify network connectivity as follows:
44
Maru Newby81f07a02012-09-05 20:21:19 -070045 There are presumed to be two types of networks: tenant and
46 public. A tenant network may or may not be reachable from the
47 Tempest host. A public network is assumed to be reachable from
48 the Tempest host, and it should be possible to associate a public
49 ('floating') IP address with a tenant ('fixed') IP address to
Chang Bo Guocc1623c2013-09-13 20:11:27 -070050 facilitate external connectivity to a potentially unroutable
Maru Newby81f07a02012-09-05 20:21:19 -070051 tenant IP address.
52
53 This test suite can be configured to test network connectivity to
54 a VM via a tenant network, a public network, or both. If both
55 networking types are to be evaluated, tests that need to be
56 executed remotely on the VM (via ssh) will only be run against
57 one of the networks (to minimize test execution time).
58
59 Determine which types of networks to test as follows:
60
61 * Configure tenant network checks (via the
Sean Dagueed6e5862016-04-04 10:49:13 -040062 'project_networks_reachable' key) if the Tempest host should
Maru Newby81f07a02012-09-05 20:21:19 -070063 have direct connectivity to tenant networks. This is likely to
64 be the case if Tempest is running on the same host as a
65 single-node devstack installation with IP namespaces disabled.
66
67 * Configure checks for a public network if a public network has
68 been configured prior to the test suite being run and if the
69 Tempest host should have connectivity to that public network.
70 Checking connectivity for a public network requires that a
71 value be provided for 'public_network_id'. A value can
72 optionally be provided for 'public_router_id' if tenants will
73 use a shared router to access a public network (as is likely to
74 be the case when IP namespaces are not enabled). If a value is
75 not provided for 'public_router_id', a router will be created
76 for each tenant and use the network identified by
77 'public_network_id' as its gateway.
78
79 """
80
81 @classmethod
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +000082 def skip_checks(cls):
83 super(TestNetworkBasicOps, cls).skip_checks()
Sean Dagueed6e5862016-04-04 10:49:13 -040084 if not (CONF.network.project_networks_reachable
Matthew Treinish6c072292014-01-29 19:15:52 +000085 or CONF.network.public_network_id):
Sean Dagueed6e5862016-04-04 10:49:13 -040086 msg = ('Either project_networks_reachable must be "true", or '
Maru Newby81f07a02012-09-05 20:21:19 -070087 'public_network_id must be defined.')
ivan-zhu1feeb382013-01-24 10:14:39 +080088 raise cls.skipException(msg)
Yoshihiro Kaneko05670262014-01-18 19:22:44 +090089 for ext in ['router', 'security-group']:
90 if not test.is_extension_enabled(ext, 'network'):
91 msg = "%s extension not enabled." % ext
92 raise cls.skipException(msg)
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +000093
94 @classmethod
95 def setup_credentials(cls):
Masayuki Igawa60ea6c52014-10-15 17:32:14 +090096 # Create no network resources for these tests.
97 cls.set_network_resources()
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +000098 super(TestNetworkBasicOps, cls).setup_credentials()
Maru Newby81f07a02012-09-05 20:21:19 -070099
Yair Frieded8392f2014-01-15 17:21:35 +0200100 def setUp(self):
101 super(TestNetworkBasicOps, self).setUp()
Yair Fried1fc32a12014-08-04 09:11:30 +0300102 self.keypairs = {}
103 self.servers = []
David Shrewsbury9bac3662014-08-07 15:07:01 -0400104
Yair Fried413bf2d2014-11-19 17:07:11 +0200105 def _setup_network_and_servers(self, **kwargs):
Matt Riedemann17940732015-03-13 14:18:19 +0000106 boot_with_port = kwargs.pop('boot_with_port', False)
Marc Koderer410c7822016-11-08 11:47:00 +0100107 self.security_group = self._create_security_group()
Yair Fried413bf2d2014-11-19 17:07:11 +0200108 self.network, self.subnet, self.router = self.create_networks(**kwargs)
David Shrewsbury9bac3662014-08-07 15:07:01 -0400109 self.check_networks()
110
Shuquan Huangb5c8beb2015-08-05 14:14:01 +0000111 self.ports = []
zhufl7a8f29d2017-02-17 10:16:45 +0800112 port_id = None
Jordan Pittierf72a1dc2015-08-04 12:50:33 +0000113 if boot_with_port:
Matt Riedemann17940732015-03-13 14:18:19 +0000114 # create a port on the network and boot with that
zhufl7a8f29d2017-02-17 10:16:45 +0800115 port_id = self._create_port(self.network['id'])['id']
116 self.ports.append({'port': port_id})
Matt Riedemann17940732015-03-13 14:18:19 +0000117
zhufl7a8f29d2017-02-17 10:16:45 +0800118 server = self._create_server(self.network, port_id)
Yair Frieded8392f2014-01-15 17:21:35 +0200119 self._check_tenant_network_connectivity()
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200120
Yair Friedae0e73d2014-11-24 11:56:26 +0200121 floating_ip = self.create_floating_ip(server)
122 self.floating_ip_tuple = Floating_IP_tuple(floating_ip, server)
Maru Newby81f07a02012-09-05 20:21:19 -0700123
Yair Frieded8392f2014-01-15 17:21:35 +0200124 def check_networks(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000125 """Checks that we see the newly created network/subnet/router
126
127 via checking the result of list_[networks,routers,subnets]
Yair Frieded8392f2014-01-15 17:21:35 +0200128 """
129
Jordan Pittier64e6b442017-02-20 19:29:02 +0100130 seen_nets = self.admin_manager.networks_client.list_networks()
131 seen_names = [n['name'] for n in seen_nets['networks']]
132 seen_ids = [n['id'] for n in seen_nets['networks']]
Steve Heyman33735f22016-05-24 09:28:08 -0500133 self.assertIn(self.network['name'], seen_names)
134 self.assertIn(self.network['id'], seen_ids)
Yair Frieded8392f2014-01-15 17:21:35 +0200135
David Shrewsbury9bac3662014-08-07 15:07:01 -0400136 if self.subnet:
Jordan Pittier64e6b442017-02-20 19:29:02 +0100137 seen_subnets = self.admin_manager.subnets_client.list_subnets()
138 seen_net_ids = [n['network_id'] for n in seen_subnets['subnets']]
139 seen_subnet_ids = [n['id'] for n in seen_subnets['subnets']]
Steve Heyman33735f22016-05-24 09:28:08 -0500140 self.assertIn(self.network['id'], seen_net_ids)
141 self.assertIn(self.subnet['id'], seen_subnet_ids)
Yair Frieded8392f2014-01-15 17:21:35 +0200142
David Shrewsbury9bac3662014-08-07 15:07:01 -0400143 if self.router:
Jordan Pittier64e6b442017-02-20 19:29:02 +0100144 seen_routers = self.admin_manager.routers_client.list_routers()
145 seen_router_ids = [n['id'] for n in seen_routers['routers']]
146 seen_router_names = [n['name'] for n in seen_routers['routers']]
Steve Heyman33735f22016-05-24 09:28:08 -0500147 self.assertIn(self.router['name'],
David Shrewsbury9bac3662014-08-07 15:07:01 -0400148 seen_router_names)
Steve Heyman33735f22016-05-24 09:28:08 -0500149 self.assertIn(self.router['id'],
David Shrewsbury9bac3662014-08-07 15:07:01 -0400150 seen_router_ids)
Gavin Brebner851c3502013-01-18 13:14:10 +0000151
zhufl24208c22016-10-25 15:23:48 +0800152 def _create_server(self, network, port_id=None):
Yair Fried1fc32a12014-08-04 09:11:30 +0300153 keypair = self.create_keypair()
154 self.keypairs[keypair['name']] = keypair
Ken'ichi Ohmichi1b3461e2014-12-02 03:41:07 +0000155 security_groups = [{'name': self.security_group['name']}]
Steve Heyman33735f22016-05-24 09:28:08 -0500156 network = {'uuid': network['id']}
Matt Riedemann17940732015-03-13 14:18:19 +0000157 if port_id is not None:
lanoux5fc14522015-09-21 08:17:35 +0000158 network['port'] = port_id
159
160 server = self.create_server(
lanoux5fc14522015-09-21 08:17:35 +0000161 networks=[network],
162 key_name=keypair['name'],
zhufl13c9c892017-02-10 12:04:07 +0800163 security_groups=security_groups)
Yair Fried1fc32a12014-08-04 09:11:30 +0300164 self.servers.append(server)
165 return server
166
167 def _get_server_key(self, server):
168 return self.keypairs[server['key_name']]['private_key']
Salvatore Orlando5ed3b6e2013-09-17 01:27:26 -0700169
Matthew Treinish2b59f842013-09-09 20:32:51 +0000170 def _check_tenant_network_connectivity(self):
lanoux283273b2015-12-04 03:01:54 -0800171 ssh_login = CONF.validation.image_ssh_user
Yair Fried1fc32a12014-08-04 09:11:30 +0300172 for server in self.servers:
Matt Riedemann2d005be2014-05-27 10:52:35 -0700173 # call the common method in the parent class
174 super(TestNetworkBasicOps, self).\
175 _check_tenant_network_connectivity(
Yair Fried1fc32a12014-08-04 09:11:30 +0300176 server, ssh_login, self._get_server_key(server),
177 servers_for_debug=self.servers)
Brent Eaglesc26d4522013-12-02 13:28:49 -0500178
Alok Maurya6384bbb2014-07-13 06:44:29 -0700179 def check_public_network_connectivity(
180 self, should_connect=True, msg=None,
Ihar Hrachyshkaf9227c02016-09-15 11:16:47 +0000181 should_check_floating_ip_status=True, mtu=None):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000182 """Verifies connectivty to a VM via public network and floating IP
183
Yair Fried45f92952014-06-26 05:19:19 +0300184 and verifies floating IP has resource status is correct.
185
Yair Fried45f92952014-06-26 05:19:19 +0300186 :param should_connect: bool. determines if connectivity check is
187 negative or positive.
188 :param msg: Failure message to add to Error message. Should describe
189 the place in the test scenario where the method was called,
190 to indicate the context of the failure
Alok Maurya6384bbb2014-07-13 06:44:29 -0700191 :param should_check_floating_ip_status: bool. should status of
192 floating_ip be checked or not
Ihar Hrachyshkaf9227c02016-09-15 11:16:47 +0000193 :param mtu: int. MTU network to use for connectivity validation
Yair Fried45f92952014-06-26 05:19:19 +0300194 """
lanoux283273b2015-12-04 03:01:54 -0800195 ssh_login = CONF.validation.image_ssh_user
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200196 floating_ip, server = self.floating_ip_tuple
Steve Heyman33735f22016-05-24 09:28:08 -0500197 ip_address = floating_ip['floating_ip_address']
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200198 private_key = None
Yair Fried45f92952014-06-26 05:19:19 +0300199 floatingip_status = 'DOWN'
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200200 if should_connect:
Yair Fried1fc32a12014-08-04 09:11:30 +0300201 private_key = self._get_server_key(server)
Yair Fried45f92952014-06-26 05:19:19 +0300202 floatingip_status = 'ACTIVE'
Swaminathan Vasudevandc8bcdb2015-02-28 12:47:21 -0800203 # Check FloatingIP Status before initiating a connection
204 if should_check_floating_ip_status:
205 self.check_floating_ip_status(floating_ip, floatingip_status)
Matt Riedemann343305f2014-05-27 09:55:03 -0700206 # call the common method in the parent class
Yair Friedae0e73d2014-11-24 11:56:26 +0200207 super(TestNetworkBasicOps, self).check_public_network_connectivity(
Matt Riedemann343305f2014-05-27 09:55:03 -0700208 ip_address, ssh_login, private_key, should_connect, msg,
Ihar Hrachyshkaf9227c02016-09-15 11:16:47 +0000209 self.servers, mtu=mtu)
Matthew Treinish2b59f842013-09-09 20:32:51 +0000210
Yair Fried9a551c42013-12-15 14:59:34 +0200211 def _disassociate_floating_ips(self):
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200212 floating_ip, server = self.floating_ip_tuple
213 self._disassociate_floating_ip(floating_ip)
214 self.floating_ip_tuple = Floating_IP_tuple(
215 floating_ip, None)
Yair Fried9a551c42013-12-15 14:59:34 +0200216
Yair Fried05db2522013-11-18 11:02:10 +0200217 def _reassociate_floating_ips(self):
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200218 floating_ip, server = self.floating_ip_tuple
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200219 # create a new server for the floating ip
zhufl24208c22016-10-25 15:23:48 +0800220 server = self._create_server(self.network)
Yair Fried1fc32a12014-08-04 09:11:30 +0300221 self._associate_floating_ip(floating_ip, server)
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200222 self.floating_ip_tuple = Floating_IP_tuple(
Yair Fried1fc32a12014-08-04 09:11:30 +0300223 floating_ip, server)
Yair Fried05db2522013-11-18 11:02:10 +0200224
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300225 def _create_new_network(self, create_gateway=False):
Marc Koderer410c7822016-11-08 11:47:00 +0100226 self.new_net = self._create_network()
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300227 if create_gateway:
228 self.new_subnet = self._create_subnet(
229 network=self.new_net)
230 else:
231 self.new_subnet = self._create_subnet(
232 network=self.new_net,
233 gateway_ip=None)
Yair Fried3097dc12014-01-26 08:46:43 +0200234
235 def _hotplug_server(self):
236 old_floating_ip, server = self.floating_ip_tuple
Steve Heyman33735f22016-05-24 09:28:08 -0500237 ip_address = old_floating_ip['floating_ip_address']
Yair Fried1fc32a12014-08-04 09:11:30 +0300238 private_key = self._get_server_key(server)
Jordan Pittierbbb17122016-01-26 17:10:55 +0100239 ssh_client = self.get_remote_client(
240 ip_address, private_key=private_key)
Yair Fried3097dc12014-01-26 08:46:43 +0200241 old_nic_list = self._get_server_nics(ssh_client)
242 # get a port from a list of one item
Jordan Pittier64e6b442017-02-20 19:29:02 +0100243 port_list = self.admin_manager.ports_client.list_ports(
244 device_id=server['id'])['ports']
Yair Fried3097dc12014-01-26 08:46:43 +0200245 self.assertEqual(1, len(port_list))
246 old_port = port_list[0]
David Kranzb2b0c182015-02-18 13:28:19 -0500247 interface = self.interface_client.create_interface(
Ken'ichi Ohmichi9509b962015-07-07 05:30:15 +0000248 server_id=server['id'],
Steve Heyman33735f22016-05-24 09:28:08 -0500249 net_id=self.new_net['id'])['interfaceAttachment']
Ken'ichi Ohmichi43e7fcf2016-04-04 11:59:13 -0700250 self.addCleanup(self.ports_client.wait_for_resource_deletion,
251 interface['port_id'])
Jordan Pittier9e227c52016-02-09 14:35:18 +0100252 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
Yair Fried1fc32a12014-08-04 09:11:30 +0300253 self.interface_client.delete_interface,
254 server['id'], interface['port_id'])
Yair Fried3097dc12014-01-26 08:46:43 +0200255
256 def check_ports():
Jordan Pittier64e6b442017-02-20 19:29:02 +0100257 self.new_port_list = [
258 port for port in
259 self.admin_manager.ports_client.list_ports(
260 device_id=server['id'])['ports']
261 if port['id'] != old_port['id']
262 ]
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200263 return len(self.new_port_list) == 1
Yair Fried3097dc12014-01-26 08:46:43 +0200264
Jordan Pittier35a63752016-08-30 13:09:12 +0200265 if not test_utils.call_until_true(
266 check_ports, CONF.network.build_timeout,
267 CONF.network.build_interval):
Matt Riedemann892094e2015-02-05 07:24:02 -0800268 raise exceptions.TimeoutException(
269 "No new port attached to the server in time (%s sec)! "
270 "Old port: %s. Number of new ports: %d" % (
271 CONF.network.build_timeout, old_port,
272 len(self.new_port_list)))
Steve Heyman33735f22016-05-24 09:28:08 -0500273 new_port = self.new_port_list[0]
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200274
275 def check_new_nic():
276 new_nic_list = self._get_server_nics(ssh_client)
277 self.diff_list = [n for n in new_nic_list if n not in old_nic_list]
278 return len(self.diff_list) == 1
279
Jordan Pittier35a63752016-08-30 13:09:12 +0200280 if not test_utils.call_until_true(
281 check_new_nic, CONF.network.build_timeout,
282 CONF.network.build_interval):
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200283 raise exceptions.TimeoutException("Interface not visible on the "
284 "guest after %s sec"
285 % CONF.network.build_timeout)
286
287 num, new_nic = self.diff_list[0]
Ken'ichi Ohmichicc1264c2017-03-01 12:27:28 -0800288 ssh_client.assign_static_ip(
289 nic=new_nic, addr=new_port['fixed_ips'][0]['ip_address'],
290 network_mask_bits=CONF.network.project_network_mask_bits)
Yair Friedbc46f592015-11-18 16:29:34 +0200291 ssh_client.set_nic_state(nic=new_nic)
Yair Fried3097dc12014-01-26 08:46:43 +0200292
293 def _get_server_nics(self, ssh_client):
294 reg = re.compile(r'(?P<num>\d+): (?P<nic_name>\w+):')
295 ipatxt = ssh_client.get_ip_list()
296 return reg.findall(ipatxt)
297
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300298 def _check_network_internal_connectivity(self, network,
299 should_connect=True):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000300 """via ssh check VM internal connectivity:
301
Yair Fried06552292013-11-11 12:10:09 +0200302 - ping internal gateway and DHCP port, implying in-tenant connectivity
303 pinging both, because L3 and DHCP agents might be on different nodes
Yair Fried3097dc12014-01-26 08:46:43 +0200304 """
305 floating_ip, server = self.floating_ip_tuple
306 # get internal ports' ips:
307 # get all network ports in the new network
Jordan Pittier64e6b442017-02-20 19:29:02 +0100308 internal_ips = (
309 p['fixed_ips'][0]['ip_address'] for p in
310 self.admin_manager.ports_client.list_ports(
311 tenant_id=server['tenant_id'],
312 network_id=network['id'])['ports']
313 if p['device_owner'].startswith('network')
314 )
Yair Fried3097dc12014-01-26 08:46:43 +0200315
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300316 self._check_server_connectivity(floating_ip,
317 internal_ips,
318 should_connect)
Yair Fried06552292013-11-11 12:10:09 +0200319
320 def _check_network_external_connectivity(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000321 """ping default gateway to imply external connectivity"""
Yair Fried06552292013-11-11 12:10:09 +0200322 if not CONF.network.public_network_id:
323 msg = 'public network not defined.'
324 LOG.info(msg)
325 return
326
Andrew Boik4a3daf12015-03-27 01:59:31 -0400327 # We ping the external IP from the instance using its floating IP
328 # which is always IPv4, so we must only test connectivity to
329 # external IPv4 IPs if the external network is dualstack.
Jordan Pittier64e6b442017-02-20 19:29:02 +0100330 v4_subnets = [
331 s for s in self.admin_manager.subnets_client.list_subnets(
332 network_id=CONF.network.public_network_id)['subnets']
333 if s['ip_version'] == 4
334 ]
Andrew Boik4a3daf12015-03-27 01:59:31 -0400335 self.assertEqual(1, len(v4_subnets),
336 "Found %d IPv4 subnets" % len(v4_subnets))
Yair Fried06552292013-11-11 12:10:09 +0200337
Andrew Boik4a3daf12015-03-27 01:59:31 -0400338 external_ips = [v4_subnets[0]['gateway_ip']]
Yair Fried06552292013-11-11 12:10:09 +0200339 self._check_server_connectivity(self.floating_ip_tuple.floating_ip,
340 external_ips)
341
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300342 def _check_server_connectivity(self, floating_ip, address_list,
343 should_connect=True):
Steve Heyman33735f22016-05-24 09:28:08 -0500344 ip_address = floating_ip['floating_ip_address']
Yair Fried1fc32a12014-08-04 09:11:30 +0300345 private_key = self._get_server_key(self.floating_ip_tuple.server)
Jordan Pittierbbb17122016-01-26 17:10:55 +0100346 ssh_source = self.get_remote_client(
347 ip_address, private_key=private_key)
Yair Fried3097dc12014-01-26 08:46:43 +0200348
Yair Fried06552292013-11-11 12:10:09 +0200349 for remote_ip in address_list:
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900350 self.check_remote_connectivity(ssh_source, remote_ip,
351 should_connect)
Yair Fried3097dc12014-01-26 08:46:43 +0200352
Yoshihiro Kaneko05670262014-01-18 19:22:44 +0900353 @test.attr(type='smoke')
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800354 @decorators.idempotent_id('f323b3ba-82f8-4db7-8ea6-6a895869ec49')
Yoshihiro Kaneko05670262014-01-18 19:22:44 +0900355 @test.services('compute', 'network')
Matthew Treinish2b59f842013-09-09 20:32:51 +0000356 def test_network_basic_ops(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000357 """Basic network operation test
358
Yair Fried3097dc12014-01-26 08:46:43 +0200359 For a freshly-booted VM with an IP address ("port") on a given
360 network:
361
362 - the Tempest host can ping the IP address. This implies, but
363 does not guarantee (see the ssh check that follows), that the
364 VM has been assigned the correct IP address and has
365 connectivity to the Tempest host.
366
367 - the Tempest host can perform key-based authentication to an
368 ssh server hosted at the IP address. This check guarantees
369 that the IP address is associated with the target VM.
370
Yair Fried3097dc12014-01-26 08:46:43 +0200371 - the Tempest host can ssh into the VM via the IP address and
372 successfully execute the following:
373
374 - ping an external IP address, implying external connectivity.
375
376 - ping an external hostname, implying that dns is correctly
377 configured.
378
379 - ping an internal IP address, implying connectivity to another
380 VM on the same network.
381
Yair Fried06552292013-11-11 12:10:09 +0200382 - detach the floating-ip from the VM and verify that it becomes
383 unreachable
384
385 - associate detached floating ip to a new VM and verify connectivity.
386 VMs are created with unique keypair so connectivity also asserts that
387 floating IP is associated with the new VM instead of the old one
388
Yair Fried45f92952014-06-26 05:19:19 +0300389 Verifies that floating IP status is updated correctly after each change
390
Yair Fried06552292013-11-11 12:10:09 +0200391
Yair Fried3097dc12014-01-26 08:46:43 +0200392 """
David Shrewsbury9bac3662014-08-07 15:07:01 -0400393 self._setup_network_and_servers()
Yair Friedae0e73d2014-11-24 11:56:26 +0200394 self.check_public_network_connectivity(should_connect=True)
Yair Fried06552292013-11-11 12:10:09 +0200395 self._check_network_internal_connectivity(network=self.network)
396 self._check_network_external_connectivity()
Yair Fried9a551c42013-12-15 14:59:34 +0200397 self._disassociate_floating_ips()
Yair Friedae0e73d2014-11-24 11:56:26 +0200398 self.check_public_network_connectivity(should_connect=False,
399 msg="after disassociate "
400 "floating ip")
Yair Fried05db2522013-11-18 11:02:10 +0200401 self._reassociate_floating_ips()
Yair Friedae0e73d2014-11-24 11:56:26 +0200402 self.check_public_network_connectivity(should_connect=True,
403 msg="after re-associate "
404 "floating ip")
Yair Fried3097dc12014-01-26 08:46:43 +0200405
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800406 @decorators.idempotent_id('b158ea55-472e-4086-8fa9-c64ac0c6c1d0')
Ihar Hrachyshkaf9227c02016-09-15 11:16:47 +0000407 @testtools.skipUnless(test.is_extension_enabled('net-mtu', 'network'),
408 'No way to calculate MTU for networks')
Sean Dague49505df2017-03-01 11:35:58 -0500409 @test.attr(type='slow')
Ihar Hrachyshkaf9227c02016-09-15 11:16:47 +0000410 @test.services('compute', 'network')
411 def test_mtu_sized_frames(self):
412 """Validate that network MTU sized frames fit through."""
413 self._setup_network_and_servers()
414 self.check_public_network_connectivity(
415 should_connect=True, mtu=self.network['mtu'])
416
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800417 @decorators.idempotent_id('1546850e-fbaa-42f5-8b5f-03d8a6a95f15')
Thiago Paiva66cded22016-08-15 14:55:58 -0300418 @testtools.skipIf(CONF.network.shared_physical_network,
419 'Connectivity can only be tested when in a '
420 'multitenant network environment')
Sean Dague17487fb2016-08-08 10:44:20 -0400421 @decorators.skip_because(bug="1610994")
Sean Dague49505df2017-03-01 11:35:58 -0500422 @test.attr(type='slow')
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300423 @test.services('compute', 'network')
424 def test_connectivity_between_vms_on_different_networks(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000425 """Test connectivity between VMs on different networks
426
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300427 For a freshly-booted VM with an IP address ("port") on a given
428 network:
429
430 - the Tempest host can ping the IP address.
431
432 - the Tempest host can ssh into the VM via the IP address and
433 successfully execute the following:
434
435 - ping an external IP address, implying external connectivity.
436
437 - ping an external hostname, implying that dns is correctly
438 configured.
439
440 - ping an internal IP address, implying connectivity to another
441 VM on the same network.
442
443 - Create another network on the same tenant with subnet, create
444 an VM on the new network.
445
446 - Ping the new VM from previous VM failed since the new network
447 was not attached to router yet.
448
449 - Attach the new network to the router, Ping the new VM from
450 previous VM succeed.
451
452 """
453 self._setup_network_and_servers()
454 self.check_public_network_connectivity(should_connect=True)
455 self._check_network_internal_connectivity(network=self.network)
456 self._check_network_external_connectivity()
457 self._create_new_network(create_gateway=True)
zhufl24208c22016-10-25 15:23:48 +0800458 self._create_server(self.new_net)
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300459 self._check_network_internal_connectivity(network=self.new_net,
460 should_connect=False)
Steve Heyman33735f22016-05-24 09:28:08 -0500461 router_id = self.router['id']
462 self.routers_client.add_router_interface(
463 router_id, subnet_id=self.new_subnet['id'])
464
465 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
466 self.routers_client.remove_router_interface,
467 router_id, subnet_id=self.new_subnet['id'])
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300468 self._check_network_internal_connectivity(network=self.new_net,
469 should_connect=True)
470
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800471 @decorators.idempotent_id('c5adff73-e961-41f1-b4a9-343614f18cfa')
Adam Gandelman7186f7a2014-07-23 09:28:56 -0400472 @testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
473 'NIC hotplug not available')
Itzik Brown2ca01cd2014-12-08 12:58:20 +0200474 @testtools.skipIf(CONF.network.port_vnic_type in ['direct', 'macvtap'],
475 'NIC hotplug not supported for '
476 'vnic_type direct or macvtap')
Yair Fried3097dc12014-01-26 08:46:43 +0200477 @test.services('compute', 'network')
478 def test_hotplug_nic(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000479 """Test hotplug network interface
480
Arief3f6e812016-09-28 16:48:20 +0300481 1. Create a network and a VM.
482 2. Check connectivity to the VM via a public network.
483 3. Create a new network, with no gateway.
484 4. Bring up a new interface
485 5. check the VM reach the new network
Yair Fried3097dc12014-01-26 08:46:43 +0200486
487 """
David Shrewsbury9bac3662014-08-07 15:07:01 -0400488 self._setup_network_and_servers()
Yair Friedae0e73d2014-11-24 11:56:26 +0200489 self.check_public_network_connectivity(should_connect=True)
Yair Fried3097dc12014-01-26 08:46:43 +0200490 self._create_new_network()
491 self._hotplug_server()
Yair Fried06552292013-11-11 12:10:09 +0200492 self._check_network_internal_connectivity(network=self.new_net)
Alok Maurya6384bbb2014-07-13 06:44:29 -0700493
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800494 @decorators.idempotent_id('04b9fe4e-85e8-4aea-b937-ea93885ac59f')
Thiago Paiva66cded22016-08-15 14:55:58 -0300495 @testtools.skipIf(CONF.network.shared_physical_network,
496 'Router state can be altered only with multitenant '
497 'networks capabilities')
Sean Dague49505df2017-03-01 11:35:58 -0500498 @test.attr(type='slow')
Alok Maurya6384bbb2014-07-13 06:44:29 -0700499 @test.services('compute', 'network')
500 def test_update_router_admin_state(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000501 """Test to update admin state up of router
502
Alok Maurya6384bbb2014-07-13 06:44:29 -0700503 1. Check public connectivity before updating
504 admin_state_up attribute of router to False
505 2. Check public connectivity after updating
506 admin_state_up attribute of router to False
507 3. Check public connectivity after updating
508 admin_state_up attribute of router to True
509 """
510 self._setup_network_and_servers()
511 self.check_public_network_connectivity(
512 should_connect=True, msg="before updating "
513 "admin_state_up of router to False")
514 self._update_router_admin_state(self.router, False)
515 # TODO(alokmaurya): Remove should_check_floating_ip_status=False check
516 # once bug 1396310 is fixed
517
518 self.check_public_network_connectivity(
519 should_connect=False, msg="after updating "
520 "admin_state_up of router to False",
521 should_check_floating_ip_status=False)
522 self._update_router_admin_state(self.router, True)
523 self.check_public_network_connectivity(
524 should_connect=True, msg="after updating "
525 "admin_state_up of router to True")
Yair Fried413bf2d2014-11-19 17:07:11 +0200526
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800527 @decorators.idempotent_id('d8bb918e-e2df-48b2-97cd-b73c95450980')
Thiago Paiva66cded22016-08-15 14:55:58 -0300528 @testtools.skipIf(CONF.network.shared_physical_network,
529 'network isolation not available')
Yair Fried413bf2d2014-11-19 17:07:11 +0200530 @testtools.skipUnless(CONF.scenario.dhcp_client,
531 "DHCP client is not available.")
Sean Dague49505df2017-03-01 11:35:58 -0500532 @test.attr(type='slow')
Yair Fried413bf2d2014-11-19 17:07:11 +0200533 @test.services('compute', 'network')
534 def test_subnet_details(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000535 """Tests that subnet's extra configuration details are affecting VMs.
536
537 This test relies on non-shared, isolated tenant networks.
Yair Fried413bf2d2014-11-19 17:07:11 +0200538
539 NOTE: Neutron subnets push data to servers via dhcp-agent, so any
540 update in subnet requires server to actively renew its DHCP lease.
541
542 1. Configure subnet with dns nameserver
543 2. retrieve the VM's configured dns and verify it matches the one
544 configured for the subnet.
545 3. update subnet's dns
546 4. retrieve the VM's configured dns and verify it matches the new one
547 configured for the subnet.
548
549 TODO(yfried): add host_routes
550
551 any resolution check would be testing either:
552 * l3 forwarding (tested in test_network_basic_ops)
553 * Name resolution of an external DNS nameserver - out of scope for
554 Tempest
555 """
556 # this test check only updates (no actual resolution) so using
557 # arbitrary ip addresses as nameservers, instead of parsing CONF
558 initial_dns_server = '1.2.3.4'
559 alt_dns_server = '9.8.7.6'
Yair Friedbb0ea392015-01-19 07:26:08 +0000560
561 # renewal should be immediate.
562 # Timeouts are suggested by salvatore-orlando in
563 # https://bugs.launchpad.net/neutron/+bug/1412325/comments/3
564 renew_delay = CONF.network.build_interval
565 renew_timeout = CONF.network.build_timeout
566
Yair Fried413bf2d2014-11-19 17:07:11 +0200567 self._setup_network_and_servers(dns_nameservers=[initial_dns_server])
568 self.check_public_network_connectivity(should_connect=True)
569
570 floating_ip, server = self.floating_ip_tuple
Steve Heyman33735f22016-05-24 09:28:08 -0500571 ip_address = floating_ip['floating_ip_address']
Yair Fried413bf2d2014-11-19 17:07:11 +0200572 private_key = self._get_server_key(server)
Jordan Pittierbbb17122016-01-26 17:10:55 +0100573 ssh_client = self.get_remote_client(
574 ip_address, private_key=private_key)
Yair Fried413bf2d2014-11-19 17:07:11 +0200575
armando-migliaccio424aa412015-02-22 17:55:17 -0800576 dns_servers = [initial_dns_server]
577 servers = ssh_client.get_dns_servers()
578 self.assertEqual(set(dns_servers), set(servers),
579 'Looking for servers: {trgt_serv}. '
580 'Retrieved DNS nameservers: {act_serv} '
581 'From host: {host}.'
582 .format(host=ssh_client.ssh_client.host,
583 act_serv=servers,
584 trgt_serv=dns_servers))
Yair Fried413bf2d2014-11-19 17:07:11 +0200585
Steve Heyman33735f22016-05-24 09:28:08 -0500586 self.subnet = self.subnets_client.update_subnet(
587 self.subnet['id'], dns_nameservers=[alt_dns_server])['subnet']
588
Yair Fried413bf2d2014-11-19 17:07:11 +0200589 # asserts that Neutron DB has updated the nameservers
Steve Heyman33735f22016-05-24 09:28:08 -0500590 self.assertEqual([alt_dns_server], self.subnet['dns_nameservers'],
Yair Fried413bf2d2014-11-19 17:07:11 +0200591 "Failed to update subnet's nameservers")
592
Yair Friedbb0ea392015-01-19 07:26:08 +0000593 def check_new_dns_server():
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000594 # NOTE: Server needs to renew its dhcp lease in order to get new
595 # definitions from subnet
596 # NOTE(amuller): we are renewing the lease as part of the retry
597 # because Neutron updates dnsmasq asynchronously after the
598 # subnet-update API call returns.
Ken'ichi Ohmichi4e337852017-03-01 12:04:23 -0800599 ssh_client.renew_lease(fixed_ip=floating_ip['fixed_ip_address'],
600 dhcp_client=CONF.scenario.dhcp_client)
armando-migliaccio424aa412015-02-22 17:55:17 -0800601 if ssh_client.get_dns_servers() != [alt_dns_server]:
Yair Friedbb0ea392015-01-19 07:26:08 +0000602 LOG.debug("Failed to update DNS nameservers")
603 return False
604 return True
605
Jordan Pittier35a63752016-08-30 13:09:12 +0200606 self.assertTrue(test_utils.call_until_true(check_new_dns_server,
607 renew_timeout,
608 renew_delay),
Yair Friedbb0ea392015-01-19 07:26:08 +0000609 msg="DHCP renewal failed to fetch "
610 "new DNS nameservers")
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800611
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800612 @decorators.idempotent_id('f5dfcc22-45fd-409f-954c-5bd500d7890b')
Itzik Brownbeb30d32015-03-29 09:42:54 +0300613 @testtools.skipUnless(CONF.network_feature_enabled.port_admin_state_change,
614 "Changing a port's admin state is not supported "
615 "by the test environment")
Sean Dague49505df2017-03-01 11:35:58 -0500616 @test.attr(type='slow')
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800617 @test.services('compute', 'network')
618 def test_update_instance_port_admin_state(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000619 """Test to update admin_state_up attribute of instance port
620
Carlos Goncalves539f8362016-11-04 14:55:02 +0100621 1. Check public and project connectivity before updating
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800622 admin_state_up attribute of instance port to False
Carlos Goncalves539f8362016-11-04 14:55:02 +0100623 2. Check public and project connectivity after updating
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800624 admin_state_up attribute of instance port to False
Carlos Goncalves539f8362016-11-04 14:55:02 +0100625 3. Check public and project connectivity after updating
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800626 admin_state_up attribute of instance port to True
627 """
628 self._setup_network_and_servers()
629 floating_ip, server = self.floating_ip_tuple
630 server_id = server['id']
Jordan Pittier64e6b442017-02-20 19:29:02 +0100631 port_id = self.admin_manager.ports_client.list_ports(
632 device_id=server_id)['ports'][0]['id']
Carlos Goncalves539f8362016-11-04 14:55:02 +0100633 server_pip = server['addresses'][self.network['name']][0]['addr']
634
635 server2 = self._create_server(self.network)
636 server2_fip = self.create_floating_ip(server2)
637
638 private_key = self._get_server_key(server2)
639 ssh_client = self.get_remote_client(server2_fip['floating_ip_address'],
640 private_key=private_key)
641
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800642 self.check_public_network_connectivity(
643 should_connect=True, msg="before updating "
644 "admin_state_up of instance port to False")
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900645 self.check_remote_connectivity(ssh_client, dest=server_pip,
646 should_succeed=True)
John Warren49c0fe52015-10-22 12:35:54 -0400647 self.ports_client.update_port(port_id, admin_state_up=False)
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800648 self.check_public_network_connectivity(
649 should_connect=False, msg="after updating "
650 "admin_state_up of instance port to False",
651 should_check_floating_ip_status=False)
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900652 self.check_remote_connectivity(ssh_client, dest=server_pip,
653 should_succeed=False)
John Warren49c0fe52015-10-22 12:35:54 -0400654 self.ports_client.update_port(port_id, admin_state_up=True)
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800655 self.check_public_network_connectivity(
656 should_connect=True, msg="after updating "
657 "admin_state_up of instance port to True")
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900658 self.check_remote_connectivity(ssh_client, dest=server_pip,
659 should_succeed=True)
Matt Riedemann17940732015-03-13 14:18:19 +0000660
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800661 @decorators.idempotent_id('759462e1-8535-46b0-ab3a-33aa45c55aaa')
Sean Dague49505df2017-03-01 11:35:58 -0500662 @test.attr(type='slow')
Matt Riedemann17940732015-03-13 14:18:19 +0000663 @test.services('compute', 'network')
664 def test_preserve_preexisting_port(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000665 """Test preserve pre-existing port
666
667 Tests that a pre-existing port provided on server boot is not deleted
668 if the server is deleted.
Matt Riedemann17940732015-03-13 14:18:19 +0000669
670 Nova should unbind the port from the instance on delete if the port was
671 not created by Nova as part of the boot request.
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400672
673 We should also be able to boot another server with the same port.
Matt Riedemann17940732015-03-13 14:18:19 +0000674 """
675 # Setup the network, create a port and boot the server from that port.
676 self._setup_network_and_servers(boot_with_port=True)
677 _, server = self.floating_ip_tuple
Shuquan Huangb5c8beb2015-08-05 14:14:01 +0000678 self.assertEqual(1, len(self.ports),
679 'There should only be one port created for '
680 'server %s.' % server['id'])
681 port_id = self.ports[0]['port']
682 self.assertIsNotNone(port_id,
Matt Riedemann17940732015-03-13 14:18:19 +0000683 'Server should have been created from a '
684 'pre-existing port.')
685 # Assert the port is bound to the server.
Jordan Pittier64e6b442017-02-20 19:29:02 +0100686 port_list = self.admin_manager.ports_client.list_ports(
687 device_id=server['id'], network_id=self.network['id'])['ports']
Matt Riedemann17940732015-03-13 14:18:19 +0000688 self.assertEqual(1, len(port_list),
689 'There should only be one port created for '
690 'server %s.' % server['id'])
Shuquan Huangb5c8beb2015-08-05 14:14:01 +0000691 self.assertEqual(port_id, port_list[0]['id'])
Matt Riedemann17940732015-03-13 14:18:19 +0000692 # Delete the server.
693 self.servers_client.delete_server(server['id'])
Ken'ichi Ohmichie91a0c62015-08-13 02:09:16 +0000694 waiters.wait_for_server_termination(self.servers_client, server['id'])
Matt Riedemann17940732015-03-13 14:18:19 +0000695 # Assert the port still exists on the network but is unbound from
696 # the deleted server.
John Warren49c0fe52015-10-22 12:35:54 -0400697 port = self.ports_client.show_port(port_id)['port']
Matt Riedemann17940732015-03-13 14:18:19 +0000698 self.assertEqual(self.network['id'], port['network_id'])
699 self.assertEqual('', port['device_id'])
700 self.assertEqual('', port['device_owner'])
Yair Fried564d89d2015-08-06 17:02:12 +0300701
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400702 # Boot another server with the same port to make sure nothing was
703 # left around that could cause issues.
zhufl24208c22016-10-25 15:23:48 +0800704 server = self._create_server(self.network, port['id'])
Jordan Pittier64e6b442017-02-20 19:29:02 +0100705 port_list = self.admin_manager.ports_client.list_ports(
706 device_id=server['id'], network_id=self.network['id'])['ports']
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400707 self.assertEqual(1, len(port_list),
708 'There should only be one port created for '
709 'server %s.' % server['id'])
710 self.assertEqual(port['id'], port_list[0]['id'])
711
YAMAMOTO Takashi56216312015-09-10 20:05:03 +0900712 @test.requires_ext(service='network', extension='l3_agent_scheduler')
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800713 @decorators.idempotent_id('2e788c46-fb3f-4ac9-8f82-0561555bea73')
Sean Dague49505df2017-03-01 11:35:58 -0500714 @test.attr(type='slow')
Yair Fried564d89d2015-08-06 17:02:12 +0300715 @test.services('compute', 'network')
716 def test_router_rescheduling(self):
717 """Tests that router can be removed from agent and add to a new agent.
718
719 1. Verify connectivity
720 2. Remove router from all l3-agents
721 3. Verify connectivity is down
722 4. Assign router to new l3-agent (or old one if no new agent is
723 available)
724 5. Verify connectivity
725 """
726
727 # TODO(yfried): refactor this test to be used for other agents (dhcp)
728 # as well
729
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000730 list_hosts = (self.admin_manager.routers_client.
Yair Fried564d89d2015-08-06 17:02:12 +0300731 list_l3_agents_hosting_router)
Ken'ichi Ohmichi71860062015-12-15 08:20:13 +0000732 schedule_router = (self.admin_manager.network_agents_client.
Ken'ichi Ohmichi70a24e92016-01-06 01:08:27 +0000733 create_router_on_l3_agent)
Ken'ichi Ohmichi71860062015-12-15 08:20:13 +0000734 unschedule_router = (self.admin_manager.network_agents_client.
Ken'ichi Ohmichi70a24e92016-01-06 01:08:27 +0000735 delete_router_from_l3_agent)
Yair Fried564d89d2015-08-06 17:02:12 +0300736
Jordan Pittier64e6b442017-02-20 19:29:02 +0100737 agent_list_alive = set(
738 a["id"] for a in
739 self.admin_manager.network_agents_client.list_agents(
740 agent_type="L3 agent")['agents'] if a["alive"] is True
741 )
Yair Fried564d89d2015-08-06 17:02:12 +0300742 self._setup_network_and_servers()
Kevin Benton3b63aa12015-08-27 17:15:44 -0700743
744 # NOTE(kevinbenton): we have to use the admin credentials to check
Sean Dagueed6e5862016-04-04 10:49:13 -0400745 # for the distributed flag because self.router only has a project view.
Steve Heyman33735f22016-05-24 09:28:08 -0500746 admin = self.admin_manager.routers_client.show_router(
747 self.router['id'])
Kevin Benton3b63aa12015-08-27 17:15:44 -0700748 if admin['router'].get('distributed', False):
749 msg = "Rescheduling test does not apply to distributed routers."
750 raise self.skipException(msg)
751
Yair Fried564d89d2015-08-06 17:02:12 +0300752 self.check_public_network_connectivity(should_connect=True)
753
754 # remove resource from agents
755 hosting_agents = set(a["id"] for a in
Steve Heyman33735f22016-05-24 09:28:08 -0500756 list_hosts(self.router['id'])['agents'])
shipeiqic9a4a102016-04-20 17:39:03 +0800757 no_migration = agent_list_alive == hosting_agents
Yair Fried564d89d2015-08-06 17:02:12 +0300758 LOG.info("Router will be assigned to {mig} hosting agent".
759 format(mig="the same" if no_migration else "a new"))
760
761 for hosting_agent in hosting_agents:
Steve Heyman33735f22016-05-24 09:28:08 -0500762 unschedule_router(hosting_agent, self.router['id'])
Yair Fried564d89d2015-08-06 17:02:12 +0300763 self.assertNotIn(hosting_agent,
764 [a["id"] for a in
Steve Heyman33735f22016-05-24 09:28:08 -0500765 list_hosts(self.router['id'])['agents']],
Yair Fried564d89d2015-08-06 17:02:12 +0300766 'unscheduling router failed')
767
768 # verify resource is un-functional
769 self.check_public_network_connectivity(
770 should_connect=False,
771 msg='after router unscheduling',
Yair Fried564d89d2015-08-06 17:02:12 +0300772 )
773
774 # schedule resource to new agent
775 target_agent = list(hosting_agents if no_migration else
shipeiqic9a4a102016-04-20 17:39:03 +0800776 agent_list_alive - hosting_agents)[0]
Yair Fried564d89d2015-08-06 17:02:12 +0300777 schedule_router(target_agent,
piyush110786bc0faa62015-12-03 14:54:48 +0530778 router_id=self.router['id'])
Yair Fried564d89d2015-08-06 17:02:12 +0300779 self.assertEqual(
780 target_agent,
Steve Heyman33735f22016-05-24 09:28:08 -0500781 list_hosts(self.router['id'])['agents'][0]['id'],
Yair Fried564d89d2015-08-06 17:02:12 +0300782 "Router failed to reschedule. Hosting agent doesn't match "
783 "target agent")
784
785 # verify resource is functional
786 self.check_public_network_connectivity(
787 should_connect=True,
788 msg='After router rescheduling')
Yair Friedbc46f592015-11-18 16:29:34 +0200789
790 @test.requires_ext(service='network', extension='port-security')
Evgeny Antyshevaaf3fc92016-02-15 11:49:22 +0000791 @testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
792 'NIC hotplug not available')
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800793 @decorators.idempotent_id('7c0bb1a2-d053-49a4-98f9-ca1a1d849f63')
Sean Dague49505df2017-03-01 11:35:58 -0500794 @test.attr(type='slow')
Yair Friedbc46f592015-11-18 16:29:34 +0200795 @test.services('compute', 'network')
796 def test_port_security_macspoofing_port(self):
797 """Tests port_security extension enforces mac spoofing
798
Eran Kuris7969e802015-12-15 13:43:46 +0200799 Neutron security groups always apply anti-spoof rules on the VMs. This
800 allows traffic to originate and terminate at the VM as expected, but
801 prevents traffic to pass through the VM. Anti-spoof rules are not
802 required in cases where the VM routes traffic through it.
803
804 The test steps are :
805 1. Create a new network.
806 2. Connect (hotplug) the VM to a new network.
YAMAMOTO Takashic3978412015-11-30 23:55:56 +0900807 3. Check the VM can ping a server on the new network ("peer")
Eran Kuris7969e802015-12-15 13:43:46 +0200808 4. Spoof the mac address of the new VM interface.
809 5. Check the Security Group enforces mac spoofing and blocks pings via
YAMAMOTO Takashic3978412015-11-30 23:55:56 +0900810 spoofed interface (VM cannot ping the peer).
Eran Kuris7969e802015-12-15 13:43:46 +0200811 6. Disable port-security of the spoofed port- set the flag to false.
812 7. Retest 3rd step and check that the Security Group allows pings via
813 the spoofed interface.
Yair Friedbc46f592015-11-18 16:29:34 +0200814 """
Eran Kuris7969e802015-12-15 13:43:46 +0200815
Yair Friedbc46f592015-11-18 16:29:34 +0200816 spoof_mac = "00:00:00:00:00:01"
817
818 # Create server
819 self._setup_network_and_servers()
YAMAMOTO Takashic368dde2015-11-30 23:04:14 +0900820 self.check_public_network_connectivity(should_connect=True)
Yair Friedbc46f592015-11-18 16:29:34 +0200821 self._create_new_network()
822 self._hotplug_server()
823 fip, server = self.floating_ip_tuple
Jordan Pittier64e6b442017-02-20 19:29:02 +0100824 new_ports = self.admin_manager.ports_client.list_ports(
825 device_id=server["id"], network_id=self.new_net["id"])['ports']
Yair Friedbc46f592015-11-18 16:29:34 +0200826 spoof_port = new_ports[0]
827 private_key = self._get_server_key(server)
Steve Heyman33735f22016-05-24 09:28:08 -0500828 ssh_client = self.get_remote_client(fip['floating_ip_address'],
Yair Friedbc46f592015-11-18 16:29:34 +0200829 private_key=private_key)
Evgeny Antyshev9b77ae52016-02-16 09:48:57 +0000830 spoof_nic = ssh_client.get_nic_name_by_mac(spoof_port["mac_address"])
zhufl24208c22016-10-25 15:23:48 +0800831 peer = self._create_server(self.new_net)
Steve Heyman33735f22016-05-24 09:28:08 -0500832 peer_address = peer['addresses'][self.new_net['name']][0]['addr']
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900833 self.check_remote_connectivity(ssh_client, dest=peer_address,
834 nic=spoof_nic, should_succeed=True)
Yair Friedbc46f592015-11-18 16:29:34 +0200835 ssh_client.set_mac_address(spoof_nic, spoof_mac)
836 new_mac = ssh_client.get_mac_address(nic=spoof_nic)
837 self.assertEqual(spoof_mac, new_mac)
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900838 self.check_remote_connectivity(ssh_client, dest=peer_address,
839 nic=spoof_nic, should_succeed=False)
Yair Friedbc46f592015-11-18 16:29:34 +0200840 self.ports_client.update_port(spoof_port["id"],
841 port_security_enabled=False,
842 security_groups=[])
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900843 self.check_remote_connectivity(ssh_client, dest=peer_address,
844 nic=spoof_nic, should_succeed=True)