blob: e6a5f515c6ac715abe0f31f4cbba451ec2b0cf88 [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 = []
Matt Riedemann17940732015-03-13 14:18:19 +0000112 self.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
Steve Heyman33735f22016-05-24 09:28:08 -0500115 self.port_id = self._create_port(self.network['id'])['id']
Shuquan Huangb5c8beb2015-08-05 14:14:01 +0000116 self.ports.append({'port': self.port_id})
Matt Riedemann17940732015-03-13 14:18:19 +0000117
zhufl24208c22016-10-25 15:23:48 +0800118 server = self._create_server(self.network, self.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
Gavin Brebner851c3502013-01-18 13:14:10 +0000130 seen_nets = self._list_networks()
131 seen_names = [n['name'] for n in seen_nets]
132 seen_ids = [n['id'] for n in seen_nets]
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:
137 seen_subnets = self._list_subnets()
138 seen_net_ids = [n['network_id'] for n in seen_subnets]
139 seen_subnet_ids = [n['id'] for n in seen_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:
144 seen_routers = self._list_routers()
145 seen_router_ids = [n['id'] for n in seen_routers]
146 seen_router_names = [n['name'] for n in seen_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
Yair Fried1fc32a12014-08-04 09:11:30 +0300243 port_list = self._list_ports(device_id=server['id'])
Yair Fried3097dc12014-01-26 08:46:43 +0200244 self.assertEqual(1, len(port_list))
245 old_port = port_list[0]
David Kranzb2b0c182015-02-18 13:28:19 -0500246 interface = self.interface_client.create_interface(
Ken'ichi Ohmichi9509b962015-07-07 05:30:15 +0000247 server_id=server['id'],
Steve Heyman33735f22016-05-24 09:28:08 -0500248 net_id=self.new_net['id'])['interfaceAttachment']
Ken'ichi Ohmichi43e7fcf2016-04-04 11:59:13 -0700249 self.addCleanup(self.ports_client.wait_for_resource_deletion,
250 interface['port_id'])
Jordan Pittier9e227c52016-02-09 14:35:18 +0100251 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
Yair Fried1fc32a12014-08-04 09:11:30 +0300252 self.interface_client.delete_interface,
253 server['id'], interface['port_id'])
Yair Fried3097dc12014-01-26 08:46:43 +0200254
255 def check_ports():
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200256 self.new_port_list = [port for port in
Yair Fried1fc32a12014-08-04 09:11:30 +0300257 self._list_ports(device_id=server['id'])
armando-migliaccio3820a062015-02-12 19:31:54 -0800258 if port['id'] != old_port['id']]
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200259 return len(self.new_port_list) == 1
Yair Fried3097dc12014-01-26 08:46:43 +0200260
Jordan Pittier35a63752016-08-30 13:09:12 +0200261 if not test_utils.call_until_true(
262 check_ports, CONF.network.build_timeout,
263 CONF.network.build_interval):
Matt Riedemann892094e2015-02-05 07:24:02 -0800264 raise exceptions.TimeoutException(
265 "No new port attached to the server in time (%s sec)! "
266 "Old port: %s. Number of new ports: %d" % (
267 CONF.network.build_timeout, old_port,
268 len(self.new_port_list)))
Steve Heyman33735f22016-05-24 09:28:08 -0500269 new_port = self.new_port_list[0]
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200270
271 def check_new_nic():
272 new_nic_list = self._get_server_nics(ssh_client)
273 self.diff_list = [n for n in new_nic_list if n not in old_nic_list]
274 return len(self.diff_list) == 1
275
Jordan Pittier35a63752016-08-30 13:09:12 +0200276 if not test_utils.call_until_true(
277 check_new_nic, CONF.network.build_timeout,
278 CONF.network.build_interval):
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200279 raise exceptions.TimeoutException("Interface not visible on the "
280 "guest after %s sec"
281 % CONF.network.build_timeout)
282
283 num, new_nic = self.diff_list[0]
Yair Fried3097dc12014-01-26 08:46:43 +0200284 ssh_client.assign_static_ip(nic=new_nic,
Steve Heyman33735f22016-05-24 09:28:08 -0500285 addr=new_port['fixed_ips'][0][
286 'ip_address'])
Yair Friedbc46f592015-11-18 16:29:34 +0200287 ssh_client.set_nic_state(nic=new_nic)
Yair Fried3097dc12014-01-26 08:46:43 +0200288
289 def _get_server_nics(self, ssh_client):
290 reg = re.compile(r'(?P<num>\d+): (?P<nic_name>\w+):')
291 ipatxt = ssh_client.get_ip_list()
292 return reg.findall(ipatxt)
293
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300294 def _check_network_internal_connectivity(self, network,
295 should_connect=True):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000296 """via ssh check VM internal connectivity:
297
Yair Fried06552292013-11-11 12:10:09 +0200298 - ping internal gateway and DHCP port, implying in-tenant connectivity
299 pinging both, because L3 and DHCP agents might be on different nodes
Yair Fried3097dc12014-01-26 08:46:43 +0200300 """
301 floating_ip, server = self.floating_ip_tuple
302 # get internal ports' ips:
303 # get all network ports in the new network
304 internal_ips = (p['fixed_ips'][0]['ip_address'] for p in
Yair Fried1fc32a12014-08-04 09:11:30 +0300305 self._list_ports(tenant_id=server['tenant_id'],
Steve Heyman33735f22016-05-24 09:28:08 -0500306 network_id=network['id'])
Yair Fried3097dc12014-01-26 08:46:43 +0200307 if p['device_owner'].startswith('network'))
308
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300309 self._check_server_connectivity(floating_ip,
310 internal_ips,
311 should_connect)
Yair Fried06552292013-11-11 12:10:09 +0200312
313 def _check_network_external_connectivity(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000314 """ping default gateway to imply external connectivity"""
Yair Fried06552292013-11-11 12:10:09 +0200315 if not CONF.network.public_network_id:
316 msg = 'public network not defined.'
317 LOG.info(msg)
318 return
319
Andrew Boik4a3daf12015-03-27 01:59:31 -0400320 # We ping the external IP from the instance using its floating IP
321 # which is always IPv4, so we must only test connectivity to
322 # external IPv4 IPs if the external network is dualstack.
323 v4_subnets = [s for s in self._list_subnets(
Vladyslav Drok77f2d762017-02-08 15:36:52 +0000324 network_id=CONF.network.public_network_id) if s['ip_version'] == 4]
Andrew Boik4a3daf12015-03-27 01:59:31 -0400325 self.assertEqual(1, len(v4_subnets),
326 "Found %d IPv4 subnets" % len(v4_subnets))
Yair Fried06552292013-11-11 12:10:09 +0200327
Andrew Boik4a3daf12015-03-27 01:59:31 -0400328 external_ips = [v4_subnets[0]['gateway_ip']]
Yair Fried06552292013-11-11 12:10:09 +0200329 self._check_server_connectivity(self.floating_ip_tuple.floating_ip,
330 external_ips)
331
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300332 def _check_server_connectivity(self, floating_ip, address_list,
333 should_connect=True):
Steve Heyman33735f22016-05-24 09:28:08 -0500334 ip_address = floating_ip['floating_ip_address']
Yair Fried1fc32a12014-08-04 09:11:30 +0300335 private_key = self._get_server_key(self.floating_ip_tuple.server)
Jordan Pittierbbb17122016-01-26 17:10:55 +0100336 ssh_source = self.get_remote_client(
337 ip_address, private_key=private_key)
Yair Fried3097dc12014-01-26 08:46:43 +0200338
Yair Fried06552292013-11-11 12:10:09 +0200339 for remote_ip in address_list:
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300340 if should_connect:
PranaliDeoreb68b9472015-08-11 00:14:50 -0700341 msg = ("Timed out waiting for %s to become "
342 "reachable") % remote_ip
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300343 else:
344 msg = "ip address %s is reachable" % remote_ip
Yair Fried3097dc12014-01-26 08:46:43 +0200345 try:
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300346 self.assertTrue(self._check_remote_connectivity
347 (ssh_source, remote_ip, should_connect),
348 msg)
Yair Fried3097dc12014-01-26 08:46:43 +0200349 except Exception:
350 LOG.exception("Unable to access {dest} via ssh to "
351 "floating-ip {src}".format(dest=remote_ip,
352 src=floating_ip))
Yair Fried3097dc12014-01-26 08:46:43 +0200353 raise
354
Yoshihiro Kaneko05670262014-01-18 19:22:44 +0900355 @test.attr(type='smoke')
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800356 @decorators.idempotent_id('f323b3ba-82f8-4db7-8ea6-6a895869ec49')
Yoshihiro Kaneko05670262014-01-18 19:22:44 +0900357 @test.services('compute', 'network')
Matthew Treinish2b59f842013-09-09 20:32:51 +0000358 def test_network_basic_ops(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000359 """Basic network operation test
360
Yair Fried3097dc12014-01-26 08:46:43 +0200361 For a freshly-booted VM with an IP address ("port") on a given
362 network:
363
364 - the Tempest host can ping the IP address. This implies, but
365 does not guarantee (see the ssh check that follows), that the
366 VM has been assigned the correct IP address and has
367 connectivity to the Tempest host.
368
369 - the Tempest host can perform key-based authentication to an
370 ssh server hosted at the IP address. This check guarantees
371 that the IP address is associated with the target VM.
372
Yair Fried3097dc12014-01-26 08:46:43 +0200373 - the Tempest host can ssh into the VM via the IP address and
374 successfully execute the following:
375
376 - ping an external IP address, implying external connectivity.
377
378 - ping an external hostname, implying that dns is correctly
379 configured.
380
381 - ping an internal IP address, implying connectivity to another
382 VM on the same network.
383
Yair Fried06552292013-11-11 12:10:09 +0200384 - detach the floating-ip from the VM and verify that it becomes
385 unreachable
386
387 - associate detached floating ip to a new VM and verify connectivity.
388 VMs are created with unique keypair so connectivity also asserts that
389 floating IP is associated with the new VM instead of the old one
390
Yair Fried45f92952014-06-26 05:19:19 +0300391 Verifies that floating IP status is updated correctly after each change
392
Yair Fried06552292013-11-11 12:10:09 +0200393
Yair Fried3097dc12014-01-26 08:46:43 +0200394 """
David Shrewsbury9bac3662014-08-07 15:07:01 -0400395 self._setup_network_and_servers()
Yair Friedae0e73d2014-11-24 11:56:26 +0200396 self.check_public_network_connectivity(should_connect=True)
Yair Fried06552292013-11-11 12:10:09 +0200397 self._check_network_internal_connectivity(network=self.network)
398 self._check_network_external_connectivity()
Yair Fried9a551c42013-12-15 14:59:34 +0200399 self._disassociate_floating_ips()
Yair Friedae0e73d2014-11-24 11:56:26 +0200400 self.check_public_network_connectivity(should_connect=False,
401 msg="after disassociate "
402 "floating ip")
Yair Fried05db2522013-11-18 11:02:10 +0200403 self._reassociate_floating_ips()
Yair Friedae0e73d2014-11-24 11:56:26 +0200404 self.check_public_network_connectivity(should_connect=True,
405 msg="after re-associate "
406 "floating ip")
Yair Fried3097dc12014-01-26 08:46:43 +0200407
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800408 @decorators.idempotent_id('b158ea55-472e-4086-8fa9-c64ac0c6c1d0')
Ihar Hrachyshkaf9227c02016-09-15 11:16:47 +0000409 @testtools.skipUnless(test.is_extension_enabled('net-mtu', 'network'),
410 'No way to calculate MTU for networks')
411 @test.services('compute', 'network')
412 def test_mtu_sized_frames(self):
413 """Validate that network MTU sized frames fit through."""
414 self._setup_network_and_servers()
415 self.check_public_network_connectivity(
416 should_connect=True, mtu=self.network['mtu'])
417
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800418 @decorators.idempotent_id('1546850e-fbaa-42f5-8b5f-03d8a6a95f15')
Thiago Paiva66cded22016-08-15 14:55:58 -0300419 @testtools.skipIf(CONF.network.shared_physical_network,
420 'Connectivity can only be tested when in a '
421 'multitenant network environment')
Sean Dague17487fb2016-08-08 10:44:20 -0400422 @decorators.skip_because(bug="1610994")
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')
Alok Maurya6384bbb2014-07-13 06:44:29 -0700498 @test.services('compute', 'network')
499 def test_update_router_admin_state(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000500 """Test to update admin state up of router
501
Alok Maurya6384bbb2014-07-13 06:44:29 -0700502 1. Check public connectivity before updating
503 admin_state_up attribute of router to False
504 2. Check public connectivity after updating
505 admin_state_up attribute of router to False
506 3. Check public connectivity after updating
507 admin_state_up attribute of router to True
508 """
509 self._setup_network_and_servers()
510 self.check_public_network_connectivity(
511 should_connect=True, msg="before updating "
512 "admin_state_up of router to False")
513 self._update_router_admin_state(self.router, False)
514 # TODO(alokmaurya): Remove should_check_floating_ip_status=False check
515 # once bug 1396310 is fixed
516
517 self.check_public_network_connectivity(
518 should_connect=False, msg="after updating "
519 "admin_state_up of router to False",
520 should_check_floating_ip_status=False)
521 self._update_router_admin_state(self.router, True)
522 self.check_public_network_connectivity(
523 should_connect=True, msg="after updating "
524 "admin_state_up of router to True")
Yair Fried413bf2d2014-11-19 17:07:11 +0200525
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800526 @decorators.idempotent_id('d8bb918e-e2df-48b2-97cd-b73c95450980')
Thiago Paiva66cded22016-08-15 14:55:58 -0300527 @testtools.skipIf(CONF.network.shared_physical_network,
528 'network isolation not available')
Yair Fried413bf2d2014-11-19 17:07:11 +0200529 @testtools.skipUnless(CONF.scenario.dhcp_client,
530 "DHCP client is not available.")
Yair Fried413bf2d2014-11-19 17:07:11 +0200531 @test.services('compute', 'network')
532 def test_subnet_details(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000533 """Tests that subnet's extra configuration details are affecting VMs.
534
535 This test relies on non-shared, isolated tenant networks.
Yair Fried413bf2d2014-11-19 17:07:11 +0200536
537 NOTE: Neutron subnets push data to servers via dhcp-agent, so any
538 update in subnet requires server to actively renew its DHCP lease.
539
540 1. Configure subnet with dns nameserver
541 2. retrieve the VM's configured dns and verify it matches the one
542 configured for the subnet.
543 3. update subnet's dns
544 4. retrieve the VM's configured dns and verify it matches the new one
545 configured for the subnet.
546
547 TODO(yfried): add host_routes
548
549 any resolution check would be testing either:
550 * l3 forwarding (tested in test_network_basic_ops)
551 * Name resolution of an external DNS nameserver - out of scope for
552 Tempest
553 """
554 # this test check only updates (no actual resolution) so using
555 # arbitrary ip addresses as nameservers, instead of parsing CONF
556 initial_dns_server = '1.2.3.4'
557 alt_dns_server = '9.8.7.6'
Yair Friedbb0ea392015-01-19 07:26:08 +0000558
559 # renewal should be immediate.
560 # Timeouts are suggested by salvatore-orlando in
561 # https://bugs.launchpad.net/neutron/+bug/1412325/comments/3
562 renew_delay = CONF.network.build_interval
563 renew_timeout = CONF.network.build_timeout
564
Yair Fried413bf2d2014-11-19 17:07:11 +0200565 self._setup_network_and_servers(dns_nameservers=[initial_dns_server])
566 self.check_public_network_connectivity(should_connect=True)
567
568 floating_ip, server = self.floating_ip_tuple
Steve Heyman33735f22016-05-24 09:28:08 -0500569 ip_address = floating_ip['floating_ip_address']
Yair Fried413bf2d2014-11-19 17:07:11 +0200570 private_key = self._get_server_key(server)
Jordan Pittierbbb17122016-01-26 17:10:55 +0100571 ssh_client = self.get_remote_client(
572 ip_address, private_key=private_key)
Yair Fried413bf2d2014-11-19 17:07:11 +0200573
armando-migliaccio424aa412015-02-22 17:55:17 -0800574 dns_servers = [initial_dns_server]
575 servers = ssh_client.get_dns_servers()
576 self.assertEqual(set(dns_servers), set(servers),
577 'Looking for servers: {trgt_serv}. '
578 'Retrieved DNS nameservers: {act_serv} '
579 'From host: {host}.'
580 .format(host=ssh_client.ssh_client.host,
581 act_serv=servers,
582 trgt_serv=dns_servers))
Yair Fried413bf2d2014-11-19 17:07:11 +0200583
Steve Heyman33735f22016-05-24 09:28:08 -0500584 self.subnet = self.subnets_client.update_subnet(
585 self.subnet['id'], dns_nameservers=[alt_dns_server])['subnet']
586
Yair Fried413bf2d2014-11-19 17:07:11 +0200587 # asserts that Neutron DB has updated the nameservers
Steve Heyman33735f22016-05-24 09:28:08 -0500588 self.assertEqual([alt_dns_server], self.subnet['dns_nameservers'],
Yair Fried413bf2d2014-11-19 17:07:11 +0200589 "Failed to update subnet's nameservers")
590
Yair Friedbb0ea392015-01-19 07:26:08 +0000591 def check_new_dns_server():
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000592 # NOTE: Server needs to renew its dhcp lease in order to get new
593 # definitions from subnet
594 # NOTE(amuller): we are renewing the lease as part of the retry
595 # because Neutron updates dnsmasq asynchronously after the
596 # subnet-update API call returns.
Yair Friedbb0ea392015-01-19 07:26:08 +0000597 ssh_client.renew_lease(fixed_ip=floating_ip['fixed_ip_address'])
armando-migliaccio424aa412015-02-22 17:55:17 -0800598 if ssh_client.get_dns_servers() != [alt_dns_server]:
Yair Friedbb0ea392015-01-19 07:26:08 +0000599 LOG.debug("Failed to update DNS nameservers")
600 return False
601 return True
602
Jordan Pittier35a63752016-08-30 13:09:12 +0200603 self.assertTrue(test_utils.call_until_true(check_new_dns_server,
604 renew_timeout,
605 renew_delay),
Yair Friedbb0ea392015-01-19 07:26:08 +0000606 msg="DHCP renewal failed to fetch "
607 "new DNS nameservers")
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800608
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800609 @decorators.idempotent_id('f5dfcc22-45fd-409f-954c-5bd500d7890b')
Itzik Brownbeb30d32015-03-29 09:42:54 +0300610 @testtools.skipUnless(CONF.network_feature_enabled.port_admin_state_change,
611 "Changing a port's admin state is not supported "
612 "by the test environment")
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800613 @test.services('compute', 'network')
614 def test_update_instance_port_admin_state(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000615 """Test to update admin_state_up attribute of instance port
616
Carlos Goncalves539f8362016-11-04 14:55:02 +0100617 1. Check public and project connectivity before updating
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800618 admin_state_up attribute of instance port to False
Carlos Goncalves539f8362016-11-04 14:55:02 +0100619 2. Check public and project connectivity after updating
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800620 admin_state_up attribute of instance port to False
Carlos Goncalves539f8362016-11-04 14:55:02 +0100621 3. Check public and project connectivity after updating
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800622 admin_state_up attribute of instance port to True
623 """
624 self._setup_network_and_servers()
625 floating_ip, server = self.floating_ip_tuple
626 server_id = server['id']
627 port_id = self._list_ports(device_id=server_id)[0]['id']
Carlos Goncalves539f8362016-11-04 14:55:02 +0100628 server_pip = server['addresses'][self.network['name']][0]['addr']
629
630 server2 = self._create_server(self.network)
631 server2_fip = self.create_floating_ip(server2)
632
633 private_key = self._get_server_key(server2)
634 ssh_client = self.get_remote_client(server2_fip['floating_ip_address'],
635 private_key=private_key)
636
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800637 self.check_public_network_connectivity(
638 should_connect=True, msg="before updating "
639 "admin_state_up of instance port to False")
Carlos Goncalves539f8362016-11-04 14:55:02 +0100640 self._check_remote_connectivity(ssh_client, dest=server_pip,
641 should_succeed=True)
John Warren49c0fe52015-10-22 12:35:54 -0400642 self.ports_client.update_port(port_id, admin_state_up=False)
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800643 self.check_public_network_connectivity(
644 should_connect=False, msg="after updating "
645 "admin_state_up of instance port to False",
646 should_check_floating_ip_status=False)
Carlos Goncalves539f8362016-11-04 14:55:02 +0100647 self._check_remote_connectivity(ssh_client, dest=server_pip,
648 should_succeed=False)
John Warren49c0fe52015-10-22 12:35:54 -0400649 self.ports_client.update_port(port_id, admin_state_up=True)
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800650 self.check_public_network_connectivity(
651 should_connect=True, msg="after updating "
652 "admin_state_up of instance port to True")
Carlos Goncalves539f8362016-11-04 14:55:02 +0100653 self._check_remote_connectivity(ssh_client, dest=server_pip,
654 should_succeed=True)
Matt Riedemann17940732015-03-13 14:18:19 +0000655
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800656 @decorators.idempotent_id('759462e1-8535-46b0-ab3a-33aa45c55aaa')
Matt Riedemann17940732015-03-13 14:18:19 +0000657 @test.services('compute', 'network')
658 def test_preserve_preexisting_port(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000659 """Test preserve pre-existing port
660
661 Tests that a pre-existing port provided on server boot is not deleted
662 if the server is deleted.
Matt Riedemann17940732015-03-13 14:18:19 +0000663
664 Nova should unbind the port from the instance on delete if the port was
665 not created by Nova as part of the boot request.
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400666
667 We should also be able to boot another server with the same port.
Matt Riedemann17940732015-03-13 14:18:19 +0000668 """
669 # Setup the network, create a port and boot the server from that port.
670 self._setup_network_and_servers(boot_with_port=True)
671 _, server = self.floating_ip_tuple
Shuquan Huangb5c8beb2015-08-05 14:14:01 +0000672 self.assertEqual(1, len(self.ports),
673 'There should only be one port created for '
674 'server %s.' % server['id'])
675 port_id = self.ports[0]['port']
676 self.assertIsNotNone(port_id,
Matt Riedemann17940732015-03-13 14:18:19 +0000677 'Server should have been created from a '
678 'pre-existing port.')
679 # Assert the port is bound to the server.
680 port_list = self._list_ports(device_id=server['id'],
681 network_id=self.network['id'])
682 self.assertEqual(1, len(port_list),
683 'There should only be one port created for '
684 'server %s.' % server['id'])
Shuquan Huangb5c8beb2015-08-05 14:14:01 +0000685 self.assertEqual(port_id, port_list[0]['id'])
Matt Riedemann17940732015-03-13 14:18:19 +0000686 # Delete the server.
687 self.servers_client.delete_server(server['id'])
Ken'ichi Ohmichie91a0c62015-08-13 02:09:16 +0000688 waiters.wait_for_server_termination(self.servers_client, server['id'])
Matt Riedemann17940732015-03-13 14:18:19 +0000689 # Assert the port still exists on the network but is unbound from
690 # the deleted server.
John Warren49c0fe52015-10-22 12:35:54 -0400691 port = self.ports_client.show_port(port_id)['port']
Matt Riedemann17940732015-03-13 14:18:19 +0000692 self.assertEqual(self.network['id'], port['network_id'])
693 self.assertEqual('', port['device_id'])
694 self.assertEqual('', port['device_owner'])
Yair Fried564d89d2015-08-06 17:02:12 +0300695
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400696 # Boot another server with the same port to make sure nothing was
697 # left around that could cause issues.
zhufl24208c22016-10-25 15:23:48 +0800698 server = self._create_server(self.network, port['id'])
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400699 port_list = self._list_ports(device_id=server['id'],
700 network_id=self.network['id'])
701 self.assertEqual(1, len(port_list),
702 'There should only be one port created for '
703 'server %s.' % server['id'])
704 self.assertEqual(port['id'], port_list[0]['id'])
705
YAMAMOTO Takashi56216312015-09-10 20:05:03 +0900706 @test.requires_ext(service='network', extension='l3_agent_scheduler')
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800707 @decorators.idempotent_id('2e788c46-fb3f-4ac9-8f82-0561555bea73')
Yair Fried564d89d2015-08-06 17:02:12 +0300708 @test.services('compute', 'network')
709 def test_router_rescheduling(self):
710 """Tests that router can be removed from agent and add to a new agent.
711
712 1. Verify connectivity
713 2. Remove router from all l3-agents
714 3. Verify connectivity is down
715 4. Assign router to new l3-agent (or old one if no new agent is
716 available)
717 5. Verify connectivity
718 """
719
720 # TODO(yfried): refactor this test to be used for other agents (dhcp)
721 # as well
722
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000723 list_hosts = (self.admin_manager.routers_client.
Yair Fried564d89d2015-08-06 17:02:12 +0300724 list_l3_agents_hosting_router)
Ken'ichi Ohmichi71860062015-12-15 08:20:13 +0000725 schedule_router = (self.admin_manager.network_agents_client.
Ken'ichi Ohmichi70a24e92016-01-06 01:08:27 +0000726 create_router_on_l3_agent)
Ken'ichi Ohmichi71860062015-12-15 08:20:13 +0000727 unschedule_router = (self.admin_manager.network_agents_client.
Ken'ichi Ohmichi70a24e92016-01-06 01:08:27 +0000728 delete_router_from_l3_agent)
Yair Fried564d89d2015-08-06 17:02:12 +0300729
shipeiqic9a4a102016-04-20 17:39:03 +0800730 agent_list_alive = set(a["id"] for a in
731 self._list_agents(agent_type="L3 agent") if
732 a["alive"] is True)
Yair Fried564d89d2015-08-06 17:02:12 +0300733 self._setup_network_and_servers()
Kevin Benton3b63aa12015-08-27 17:15:44 -0700734
735 # NOTE(kevinbenton): we have to use the admin credentials to check
Sean Dagueed6e5862016-04-04 10:49:13 -0400736 # for the distributed flag because self.router only has a project view.
Steve Heyman33735f22016-05-24 09:28:08 -0500737 admin = self.admin_manager.routers_client.show_router(
738 self.router['id'])
Kevin Benton3b63aa12015-08-27 17:15:44 -0700739 if admin['router'].get('distributed', False):
740 msg = "Rescheduling test does not apply to distributed routers."
741 raise self.skipException(msg)
742
Yair Fried564d89d2015-08-06 17:02:12 +0300743 self.check_public_network_connectivity(should_connect=True)
744
745 # remove resource from agents
746 hosting_agents = set(a["id"] for a in
Steve Heyman33735f22016-05-24 09:28:08 -0500747 list_hosts(self.router['id'])['agents'])
shipeiqic9a4a102016-04-20 17:39:03 +0800748 no_migration = agent_list_alive == hosting_agents
Yair Fried564d89d2015-08-06 17:02:12 +0300749 LOG.info("Router will be assigned to {mig} hosting agent".
750 format(mig="the same" if no_migration else "a new"))
751
752 for hosting_agent in hosting_agents:
Steve Heyman33735f22016-05-24 09:28:08 -0500753 unschedule_router(hosting_agent, self.router['id'])
Yair Fried564d89d2015-08-06 17:02:12 +0300754 self.assertNotIn(hosting_agent,
755 [a["id"] for a in
Steve Heyman33735f22016-05-24 09:28:08 -0500756 list_hosts(self.router['id'])['agents']],
Yair Fried564d89d2015-08-06 17:02:12 +0300757 'unscheduling router failed')
758
759 # verify resource is un-functional
760 self.check_public_network_connectivity(
761 should_connect=False,
762 msg='after router unscheduling',
Yair Fried564d89d2015-08-06 17:02:12 +0300763 )
764
765 # schedule resource to new agent
766 target_agent = list(hosting_agents if no_migration else
shipeiqic9a4a102016-04-20 17:39:03 +0800767 agent_list_alive - hosting_agents)[0]
Yair Fried564d89d2015-08-06 17:02:12 +0300768 schedule_router(target_agent,
piyush110786bc0faa62015-12-03 14:54:48 +0530769 router_id=self.router['id'])
Yair Fried564d89d2015-08-06 17:02:12 +0300770 self.assertEqual(
771 target_agent,
Steve Heyman33735f22016-05-24 09:28:08 -0500772 list_hosts(self.router['id'])['agents'][0]['id'],
Yair Fried564d89d2015-08-06 17:02:12 +0300773 "Router failed to reschedule. Hosting agent doesn't match "
774 "target agent")
775
776 # verify resource is functional
777 self.check_public_network_connectivity(
778 should_connect=True,
779 msg='After router rescheduling')
Yair Friedbc46f592015-11-18 16:29:34 +0200780
781 @test.requires_ext(service='network', extension='port-security')
Evgeny Antyshevaaf3fc92016-02-15 11:49:22 +0000782 @testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
783 'NIC hotplug not available')
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800784 @decorators.idempotent_id('7c0bb1a2-d053-49a4-98f9-ca1a1d849f63')
Yair Friedbc46f592015-11-18 16:29:34 +0200785 @test.services('compute', 'network')
786 def test_port_security_macspoofing_port(self):
787 """Tests port_security extension enforces mac spoofing
788
Eran Kuris7969e802015-12-15 13:43:46 +0200789 Neutron security groups always apply anti-spoof rules on the VMs. This
790 allows traffic to originate and terminate at the VM as expected, but
791 prevents traffic to pass through the VM. Anti-spoof rules are not
792 required in cases where the VM routes traffic through it.
793
794 The test steps are :
795 1. Create a new network.
796 2. Connect (hotplug) the VM to a new network.
YAMAMOTO Takashic3978412015-11-30 23:55:56 +0900797 3. Check the VM can ping a server on the new network ("peer")
Eran Kuris7969e802015-12-15 13:43:46 +0200798 4. Spoof the mac address of the new VM interface.
799 5. Check the Security Group enforces mac spoofing and blocks pings via
YAMAMOTO Takashic3978412015-11-30 23:55:56 +0900800 spoofed interface (VM cannot ping the peer).
Eran Kuris7969e802015-12-15 13:43:46 +0200801 6. Disable port-security of the spoofed port- set the flag to false.
802 7. Retest 3rd step and check that the Security Group allows pings via
803 the spoofed interface.
Yair Friedbc46f592015-11-18 16:29:34 +0200804 """
Eran Kuris7969e802015-12-15 13:43:46 +0200805
Yair Friedbc46f592015-11-18 16:29:34 +0200806 spoof_mac = "00:00:00:00:00:01"
807
808 # Create server
809 self._setup_network_and_servers()
YAMAMOTO Takashic368dde2015-11-30 23:04:14 +0900810 self.check_public_network_connectivity(should_connect=True)
Yair Friedbc46f592015-11-18 16:29:34 +0200811 self._create_new_network()
812 self._hotplug_server()
813 fip, server = self.floating_ip_tuple
814 new_ports = self._list_ports(device_id=server["id"],
815 network_id=self.new_net["id"])
816 spoof_port = new_ports[0]
817 private_key = self._get_server_key(server)
Steve Heyman33735f22016-05-24 09:28:08 -0500818 ssh_client = self.get_remote_client(fip['floating_ip_address'],
Yair Friedbc46f592015-11-18 16:29:34 +0200819 private_key=private_key)
Evgeny Antyshev9b77ae52016-02-16 09:48:57 +0000820 spoof_nic = ssh_client.get_nic_name_by_mac(spoof_port["mac_address"])
zhufl24208c22016-10-25 15:23:48 +0800821 peer = self._create_server(self.new_net)
Steve Heyman33735f22016-05-24 09:28:08 -0500822 peer_address = peer['addresses'][self.new_net['name']][0]['addr']
YAMAMOTO Takashic3978412015-11-30 23:55:56 +0900823 self._check_remote_connectivity(ssh_client, dest=peer_address,
Yair Friedbc46f592015-11-18 16:29:34 +0200824 nic=spoof_nic, should_succeed=True)
825 ssh_client.set_mac_address(spoof_nic, spoof_mac)
826 new_mac = ssh_client.get_mac_address(nic=spoof_nic)
827 self.assertEqual(spoof_mac, new_mac)
YAMAMOTO Takashic3978412015-11-30 23:55:56 +0900828 self._check_remote_connectivity(ssh_client, dest=peer_address,
Yair Friedbc46f592015-11-18 16:29:34 +0200829 nic=spoof_nic, should_succeed=False)
830 self.ports_client.update_port(spoof_port["id"],
831 port_security_enabled=False,
832 security_groups=[])
YAMAMOTO Takashic3978412015-11-30 23:55:56 +0900833 self._check_remote_connectivity(ssh_client, dest=peer_address,
Yair Friedbc46f592015-11-18 16:29:34 +0200834 nic=spoof_nic, should_succeed=True)