blob: af313a5c2d37fb4243bfa0fe3db2ff9860d74ced [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'],
163 security_groups=security_groups,
164 wait_until='ACTIVE')
Yair Fried1fc32a12014-08-04 09:11:30 +0300165 self.servers.append(server)
166 return server
167
168 def _get_server_key(self, server):
169 return self.keypairs[server['key_name']]['private_key']
Salvatore Orlando5ed3b6e2013-09-17 01:27:26 -0700170
Matthew Treinish2b59f842013-09-09 20:32:51 +0000171 def _check_tenant_network_connectivity(self):
lanoux283273b2015-12-04 03:01:54 -0800172 ssh_login = CONF.validation.image_ssh_user
Yair Fried1fc32a12014-08-04 09:11:30 +0300173 for server in self.servers:
Matt Riedemann2d005be2014-05-27 10:52:35 -0700174 # call the common method in the parent class
175 super(TestNetworkBasicOps, self).\
176 _check_tenant_network_connectivity(
Yair Fried1fc32a12014-08-04 09:11:30 +0300177 server, ssh_login, self._get_server_key(server),
178 servers_for_debug=self.servers)
Brent Eaglesc26d4522013-12-02 13:28:49 -0500179
Alok Maurya6384bbb2014-07-13 06:44:29 -0700180 def check_public_network_connectivity(
181 self, should_connect=True, msg=None,
Ihar Hrachyshkaf9227c02016-09-15 11:16:47 +0000182 should_check_floating_ip_status=True, mtu=None):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000183 """Verifies connectivty to a VM via public network and floating IP
184
Yair Fried45f92952014-06-26 05:19:19 +0300185 and verifies floating IP has resource status is correct.
186
Yair Fried45f92952014-06-26 05:19:19 +0300187 :param should_connect: bool. determines if connectivity check is
188 negative or positive.
189 :param msg: Failure message to add to Error message. Should describe
190 the place in the test scenario where the method was called,
191 to indicate the context of the failure
Alok Maurya6384bbb2014-07-13 06:44:29 -0700192 :param should_check_floating_ip_status: bool. should status of
193 floating_ip be checked or not
Ihar Hrachyshkaf9227c02016-09-15 11:16:47 +0000194 :param mtu: int. MTU network to use for connectivity validation
Yair Fried45f92952014-06-26 05:19:19 +0300195 """
lanoux283273b2015-12-04 03:01:54 -0800196 ssh_login = CONF.validation.image_ssh_user
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200197 floating_ip, server = self.floating_ip_tuple
Steve Heyman33735f22016-05-24 09:28:08 -0500198 ip_address = floating_ip['floating_ip_address']
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200199 private_key = None
Yair Fried45f92952014-06-26 05:19:19 +0300200 floatingip_status = 'DOWN'
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200201 if should_connect:
Yair Fried1fc32a12014-08-04 09:11:30 +0300202 private_key = self._get_server_key(server)
Yair Fried45f92952014-06-26 05:19:19 +0300203 floatingip_status = 'ACTIVE'
Swaminathan Vasudevandc8bcdb2015-02-28 12:47:21 -0800204 # Check FloatingIP Status before initiating a connection
205 if should_check_floating_ip_status:
206 self.check_floating_ip_status(floating_ip, floatingip_status)
Matt Riedemann343305f2014-05-27 09:55:03 -0700207 # call the common method in the parent class
Yair Friedae0e73d2014-11-24 11:56:26 +0200208 super(TestNetworkBasicOps, self).check_public_network_connectivity(
Matt Riedemann343305f2014-05-27 09:55:03 -0700209 ip_address, ssh_login, private_key, should_connect, msg,
Ihar Hrachyshkaf9227c02016-09-15 11:16:47 +0000210 self.servers, mtu=mtu)
Matthew Treinish2b59f842013-09-09 20:32:51 +0000211
Yair Fried9a551c42013-12-15 14:59:34 +0200212 def _disassociate_floating_ips(self):
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200213 floating_ip, server = self.floating_ip_tuple
214 self._disassociate_floating_ip(floating_ip)
215 self.floating_ip_tuple = Floating_IP_tuple(
216 floating_ip, None)
Yair Fried9a551c42013-12-15 14:59:34 +0200217
Yair Fried05db2522013-11-18 11:02:10 +0200218 def _reassociate_floating_ips(self):
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200219 floating_ip, server = self.floating_ip_tuple
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200220 # create a new server for the floating ip
zhufl24208c22016-10-25 15:23:48 +0800221 server = self._create_server(self.network)
Yair Fried1fc32a12014-08-04 09:11:30 +0300222 self._associate_floating_ip(floating_ip, server)
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200223 self.floating_ip_tuple = Floating_IP_tuple(
Yair Fried1fc32a12014-08-04 09:11:30 +0300224 floating_ip, server)
Yair Fried05db2522013-11-18 11:02:10 +0200225
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300226 def _create_new_network(self, create_gateway=False):
Marc Koderer410c7822016-11-08 11:47:00 +0100227 self.new_net = self._create_network()
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300228 if create_gateway:
229 self.new_subnet = self._create_subnet(
230 network=self.new_net)
231 else:
232 self.new_subnet = self._create_subnet(
233 network=self.new_net,
234 gateway_ip=None)
Yair Fried3097dc12014-01-26 08:46:43 +0200235
236 def _hotplug_server(self):
237 old_floating_ip, server = self.floating_ip_tuple
Steve Heyman33735f22016-05-24 09:28:08 -0500238 ip_address = old_floating_ip['floating_ip_address']
Yair Fried1fc32a12014-08-04 09:11:30 +0300239 private_key = self._get_server_key(server)
Jordan Pittierbbb17122016-01-26 17:10:55 +0100240 ssh_client = self.get_remote_client(
241 ip_address, private_key=private_key)
Yair Fried3097dc12014-01-26 08:46:43 +0200242 old_nic_list = self._get_server_nics(ssh_client)
243 # get a port from a list of one item
Yair Fried1fc32a12014-08-04 09:11:30 +0300244 port_list = self._list_ports(device_id=server['id'])
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():
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200257 self.new_port_list = [port for port in
Yair Fried1fc32a12014-08-04 09:11:30 +0300258 self._list_ports(device_id=server['id'])
armando-migliaccio3820a062015-02-12 19:31:54 -0800259 if port['id'] != old_port['id']]
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200260 return len(self.new_port_list) == 1
Yair Fried3097dc12014-01-26 08:46:43 +0200261
Jordan Pittier35a63752016-08-30 13:09:12 +0200262 if not test_utils.call_until_true(
263 check_ports, CONF.network.build_timeout,
264 CONF.network.build_interval):
Matt Riedemann892094e2015-02-05 07:24:02 -0800265 raise exceptions.TimeoutException(
266 "No new port attached to the server in time (%s sec)! "
267 "Old port: %s. Number of new ports: %d" % (
268 CONF.network.build_timeout, old_port,
269 len(self.new_port_list)))
Steve Heyman33735f22016-05-24 09:28:08 -0500270 new_port = self.new_port_list[0]
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200271
272 def check_new_nic():
273 new_nic_list = self._get_server_nics(ssh_client)
274 self.diff_list = [n for n in new_nic_list if n not in old_nic_list]
275 return len(self.diff_list) == 1
276
Jordan Pittier35a63752016-08-30 13:09:12 +0200277 if not test_utils.call_until_true(
278 check_new_nic, CONF.network.build_timeout,
279 CONF.network.build_interval):
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200280 raise exceptions.TimeoutException("Interface not visible on the "
281 "guest after %s sec"
282 % CONF.network.build_timeout)
283
284 num, new_nic = self.diff_list[0]
Yair Fried3097dc12014-01-26 08:46:43 +0200285 ssh_client.assign_static_ip(nic=new_nic,
Steve Heyman33735f22016-05-24 09:28:08 -0500286 addr=new_port['fixed_ips'][0][
287 'ip_address'])
Yair Friedbc46f592015-11-18 16:29:34 +0200288 ssh_client.set_nic_state(nic=new_nic)
Yair Fried3097dc12014-01-26 08:46:43 +0200289
290 def _get_server_nics(self, ssh_client):
291 reg = re.compile(r'(?P<num>\d+): (?P<nic_name>\w+):')
292 ipatxt = ssh_client.get_ip_list()
293 return reg.findall(ipatxt)
294
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300295 def _check_network_internal_connectivity(self, network,
296 should_connect=True):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000297 """via ssh check VM internal connectivity:
298
Yair Fried06552292013-11-11 12:10:09 +0200299 - ping internal gateway and DHCP port, implying in-tenant connectivity
300 pinging both, because L3 and DHCP agents might be on different nodes
Yair Fried3097dc12014-01-26 08:46:43 +0200301 """
302 floating_ip, server = self.floating_ip_tuple
303 # get internal ports' ips:
304 # get all network ports in the new network
305 internal_ips = (p['fixed_ips'][0]['ip_address'] for p in
Yair Fried1fc32a12014-08-04 09:11:30 +0300306 self._list_ports(tenant_id=server['tenant_id'],
Steve Heyman33735f22016-05-24 09:28:08 -0500307 network_id=network['id'])
Yair Fried3097dc12014-01-26 08:46:43 +0200308 if p['device_owner'].startswith('network'))
309
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300310 self._check_server_connectivity(floating_ip,
311 internal_ips,
312 should_connect)
Yair Fried06552292013-11-11 12:10:09 +0200313
314 def _check_network_external_connectivity(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000315 """ping default gateway to imply external connectivity"""
Yair Fried06552292013-11-11 12:10:09 +0200316 if not CONF.network.public_network_id:
317 msg = 'public network not defined.'
318 LOG.info(msg)
319 return
320
Andrew Boik4a3daf12015-03-27 01:59:31 -0400321 # We ping the external IP from the instance using its floating IP
322 # which is always IPv4, so we must only test connectivity to
323 # external IPv4 IPs if the external network is dualstack.
324 v4_subnets = [s for s in self._list_subnets(
325 network_id=CONF.network.public_network_id) if s['ip_version'] == 4]
326 self.assertEqual(1, len(v4_subnets),
327 "Found %d IPv4 subnets" % len(v4_subnets))
Yair Fried06552292013-11-11 12:10:09 +0200328
Andrew Boik4a3daf12015-03-27 01:59:31 -0400329 external_ips = [v4_subnets[0]['gateway_ip']]
Yair Fried06552292013-11-11 12:10:09 +0200330 self._check_server_connectivity(self.floating_ip_tuple.floating_ip,
331 external_ips)
332
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300333 def _check_server_connectivity(self, floating_ip, address_list,
334 should_connect=True):
Steve Heyman33735f22016-05-24 09:28:08 -0500335 ip_address = floating_ip['floating_ip_address']
Yair Fried1fc32a12014-08-04 09:11:30 +0300336 private_key = self._get_server_key(self.floating_ip_tuple.server)
Jordan Pittierbbb17122016-01-26 17:10:55 +0100337 ssh_source = self.get_remote_client(
338 ip_address, private_key=private_key)
Yair Fried3097dc12014-01-26 08:46:43 +0200339
Yair Fried06552292013-11-11 12:10:09 +0200340 for remote_ip in address_list:
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300341 if should_connect:
PranaliDeoreb68b9472015-08-11 00:14:50 -0700342 msg = ("Timed out waiting for %s to become "
343 "reachable") % remote_ip
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300344 else:
345 msg = "ip address %s is reachable" % remote_ip
Yair Fried3097dc12014-01-26 08:46:43 +0200346 try:
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300347 self.assertTrue(self._check_remote_connectivity
348 (ssh_source, remote_ip, should_connect),
349 msg)
Yair Fried3097dc12014-01-26 08:46:43 +0200350 except Exception:
351 LOG.exception("Unable to access {dest} via ssh to "
352 "floating-ip {src}".format(dest=remote_ip,
353 src=floating_ip))
Yair Fried3097dc12014-01-26 08:46:43 +0200354 raise
355
Yoshihiro Kaneko05670262014-01-18 19:22:44 +0900356 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800357 @test.idempotent_id('f323b3ba-82f8-4db7-8ea6-6a895869ec49')
Yoshihiro Kaneko05670262014-01-18 19:22:44 +0900358 @test.services('compute', 'network')
Matthew Treinish2b59f842013-09-09 20:32:51 +0000359 def test_network_basic_ops(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000360 """Basic network operation test
361
Yair Fried3097dc12014-01-26 08:46:43 +0200362 For a freshly-booted VM with an IP address ("port") on a given
363 network:
364
365 - the Tempest host can ping the IP address. This implies, but
366 does not guarantee (see the ssh check that follows), that the
367 VM has been assigned the correct IP address and has
368 connectivity to the Tempest host.
369
370 - the Tempest host can perform key-based authentication to an
371 ssh server hosted at the IP address. This check guarantees
372 that the IP address is associated with the target VM.
373
Yair Fried3097dc12014-01-26 08:46:43 +0200374 - the Tempest host can ssh into the VM via the IP address and
375 successfully execute the following:
376
377 - ping an external IP address, implying external connectivity.
378
379 - ping an external hostname, implying that dns is correctly
380 configured.
381
382 - ping an internal IP address, implying connectivity to another
383 VM on the same network.
384
Yair Fried06552292013-11-11 12:10:09 +0200385 - detach the floating-ip from the VM and verify that it becomes
386 unreachable
387
388 - associate detached floating ip to a new VM and verify connectivity.
389 VMs are created with unique keypair so connectivity also asserts that
390 floating IP is associated with the new VM instead of the old one
391
Yair Fried45f92952014-06-26 05:19:19 +0300392 Verifies that floating IP status is updated correctly after each change
393
Yair Fried06552292013-11-11 12:10:09 +0200394
Yair Fried3097dc12014-01-26 08:46:43 +0200395 """
David Shrewsbury9bac3662014-08-07 15:07:01 -0400396 self._setup_network_and_servers()
Yair Friedae0e73d2014-11-24 11:56:26 +0200397 self.check_public_network_connectivity(should_connect=True)
Yair Fried06552292013-11-11 12:10:09 +0200398 self._check_network_internal_connectivity(network=self.network)
399 self._check_network_external_connectivity()
Yair Fried9a551c42013-12-15 14:59:34 +0200400 self._disassociate_floating_ips()
Yair Friedae0e73d2014-11-24 11:56:26 +0200401 self.check_public_network_connectivity(should_connect=False,
402 msg="after disassociate "
403 "floating ip")
Yair Fried05db2522013-11-18 11:02:10 +0200404 self._reassociate_floating_ips()
Yair Friedae0e73d2014-11-24 11:56:26 +0200405 self.check_public_network_connectivity(should_connect=True,
406 msg="after re-associate "
407 "floating ip")
Yair Fried3097dc12014-01-26 08:46:43 +0200408
Ihar Hrachyshkaf9227c02016-09-15 11:16:47 +0000409 @test.idempotent_id('b158ea55-472e-4086-8fa9-c64ac0c6c1d0')
410 @testtools.skipUnless(test.is_extension_enabled('net-mtu', 'network'),
411 'No way to calculate MTU for networks')
412 @test.services('compute', 'network')
413 def test_mtu_sized_frames(self):
414 """Validate that network MTU sized frames fit through."""
415 self._setup_network_and_servers()
416 self.check_public_network_connectivity(
417 should_connect=True, mtu=self.network['mtu'])
418
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300419 @test.idempotent_id('1546850e-fbaa-42f5-8b5f-03d8a6a95f15')
Adam Gandelman36b71fc2015-03-12 12:24:08 -0700420 @testtools.skipIf(CONF.baremetal.driver_enabled,
421 'Baremetal relies on a shared physical network.')
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
Chris Hoge7579c1a2015-02-26 14:12:15 -0800471 @test.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
Chris Hoge7579c1a2015-02-26 14:12:15 -0800494 @test.idempotent_id('04b9fe4e-85e8-4aea-b937-ea93885ac59f')
Adam Gandelmancf611212014-12-09 14:13:28 -0800495 @testtools.skipIf(CONF.baremetal.driver_enabled,
496 'Router state cannot be altered on a shared baremetal '
497 'network')
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
Chris Hoge7579c1a2015-02-26 14:12:15 -0800526 @test.idempotent_id('d8bb918e-e2df-48b2-97cd-b73c95450980')
Adam Gandelman40371682015-03-03 11:27:03 -0800527 @testtools.skipIf(CONF.baremetal.driver_enabled,
528 'network isolation not available for baremetal nodes')
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
Chris Hoge7579c1a2015-02-26 14:12:15 -0800609 @test.idempotent_id('f5dfcc22-45fd-409f-954c-5bd500d7890b')
Adam Gandelman0a7948e2015-02-16 15:13:50 -0800610 @testtools.skipIf(CONF.baremetal.driver_enabled,
611 'admin_state of instance ports cannot be altered '
612 'for baremetal nodes')
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")
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800616 @test.services('compute', 'network')
617 def test_update_instance_port_admin_state(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000618 """Test to update admin_state_up attribute of instance port
619
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800620 1. Check public connectivity before updating
621 admin_state_up attribute of instance port to False
622 2. Check public connectivity after updating
623 admin_state_up attribute of instance port to False
624 3. Check public connectivity after updating
625 admin_state_up attribute of instance port to True
626 """
627 self._setup_network_and_servers()
628 floating_ip, server = self.floating_ip_tuple
629 server_id = server['id']
630 port_id = self._list_ports(device_id=server_id)[0]['id']
631 self.check_public_network_connectivity(
632 should_connect=True, msg="before updating "
633 "admin_state_up of instance port to False")
John Warren49c0fe52015-10-22 12:35:54 -0400634 self.ports_client.update_port(port_id, admin_state_up=False)
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800635 self.check_public_network_connectivity(
636 should_connect=False, msg="after updating "
637 "admin_state_up of instance port to False",
638 should_check_floating_ip_status=False)
John Warren49c0fe52015-10-22 12:35:54 -0400639 self.ports_client.update_port(port_id, admin_state_up=True)
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800640 self.check_public_network_connectivity(
641 should_connect=True, msg="after updating "
642 "admin_state_up of instance port to True")
Matt Riedemann17940732015-03-13 14:18:19 +0000643
644 @test.idempotent_id('759462e1-8535-46b0-ab3a-33aa45c55aaa')
Matt Riedemann17940732015-03-13 14:18:19 +0000645 @test.services('compute', 'network')
646 def test_preserve_preexisting_port(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000647 """Test preserve pre-existing port
648
649 Tests that a pre-existing port provided on server boot is not deleted
650 if the server is deleted.
Matt Riedemann17940732015-03-13 14:18:19 +0000651
652 Nova should unbind the port from the instance on delete if the port was
653 not created by Nova as part of the boot request.
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400654
655 We should also be able to boot another server with the same port.
Matt Riedemann17940732015-03-13 14:18:19 +0000656 """
657 # Setup the network, create a port and boot the server from that port.
658 self._setup_network_and_servers(boot_with_port=True)
659 _, server = self.floating_ip_tuple
Shuquan Huangb5c8beb2015-08-05 14:14:01 +0000660 self.assertEqual(1, len(self.ports),
661 'There should only be one port created for '
662 'server %s.' % server['id'])
663 port_id = self.ports[0]['port']
664 self.assertIsNotNone(port_id,
Matt Riedemann17940732015-03-13 14:18:19 +0000665 'Server should have been created from a '
666 'pre-existing port.')
667 # Assert the port is bound to the server.
668 port_list = self._list_ports(device_id=server['id'],
669 network_id=self.network['id'])
670 self.assertEqual(1, len(port_list),
671 'There should only be one port created for '
672 'server %s.' % server['id'])
Shuquan Huangb5c8beb2015-08-05 14:14:01 +0000673 self.assertEqual(port_id, port_list[0]['id'])
Matt Riedemann17940732015-03-13 14:18:19 +0000674 # Delete the server.
675 self.servers_client.delete_server(server['id'])
Ken'ichi Ohmichie91a0c62015-08-13 02:09:16 +0000676 waiters.wait_for_server_termination(self.servers_client, server['id'])
Matt Riedemann17940732015-03-13 14:18:19 +0000677 # Assert the port still exists on the network but is unbound from
678 # the deleted server.
John Warren49c0fe52015-10-22 12:35:54 -0400679 port = self.ports_client.show_port(port_id)['port']
Matt Riedemann17940732015-03-13 14:18:19 +0000680 self.assertEqual(self.network['id'], port['network_id'])
681 self.assertEqual('', port['device_id'])
682 self.assertEqual('', port['device_owner'])
Yair Fried564d89d2015-08-06 17:02:12 +0300683
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400684 # Boot another server with the same port to make sure nothing was
685 # left around that could cause issues.
zhufl24208c22016-10-25 15:23:48 +0800686 server = self._create_server(self.network, port['id'])
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400687 port_list = self._list_ports(device_id=server['id'],
688 network_id=self.network['id'])
689 self.assertEqual(1, len(port_list),
690 'There should only be one port created for '
691 'server %s.' % server['id'])
692 self.assertEqual(port['id'], port_list[0]['id'])
693
YAMAMOTO Takashi56216312015-09-10 20:05:03 +0900694 @test.requires_ext(service='network', extension='l3_agent_scheduler')
Yair Fried564d89d2015-08-06 17:02:12 +0300695 @test.idempotent_id('2e788c46-fb3f-4ac9-8f82-0561555bea73')
Yair Fried564d89d2015-08-06 17:02:12 +0300696 @test.services('compute', 'network')
697 def test_router_rescheduling(self):
698 """Tests that router can be removed from agent and add to a new agent.
699
700 1. Verify connectivity
701 2. Remove router from all l3-agents
702 3. Verify connectivity is down
703 4. Assign router to new l3-agent (or old one if no new agent is
704 available)
705 5. Verify connectivity
706 """
707
708 # TODO(yfried): refactor this test to be used for other agents (dhcp)
709 # as well
710
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000711 list_hosts = (self.admin_manager.routers_client.
Yair Fried564d89d2015-08-06 17:02:12 +0300712 list_l3_agents_hosting_router)
Ken'ichi Ohmichi71860062015-12-15 08:20:13 +0000713 schedule_router = (self.admin_manager.network_agents_client.
Ken'ichi Ohmichi70a24e92016-01-06 01:08:27 +0000714 create_router_on_l3_agent)
Ken'ichi Ohmichi71860062015-12-15 08:20:13 +0000715 unschedule_router = (self.admin_manager.network_agents_client.
Ken'ichi Ohmichi70a24e92016-01-06 01:08:27 +0000716 delete_router_from_l3_agent)
Yair Fried564d89d2015-08-06 17:02:12 +0300717
shipeiqic9a4a102016-04-20 17:39:03 +0800718 agent_list_alive = set(a["id"] for a in
719 self._list_agents(agent_type="L3 agent") if
720 a["alive"] is True)
Yair Fried564d89d2015-08-06 17:02:12 +0300721 self._setup_network_and_servers()
Kevin Benton3b63aa12015-08-27 17:15:44 -0700722
723 # NOTE(kevinbenton): we have to use the admin credentials to check
Sean Dagueed6e5862016-04-04 10:49:13 -0400724 # for the distributed flag because self.router only has a project view.
Steve Heyman33735f22016-05-24 09:28:08 -0500725 admin = self.admin_manager.routers_client.show_router(
726 self.router['id'])
Kevin Benton3b63aa12015-08-27 17:15:44 -0700727 if admin['router'].get('distributed', False):
728 msg = "Rescheduling test does not apply to distributed routers."
729 raise self.skipException(msg)
730
Yair Fried564d89d2015-08-06 17:02:12 +0300731 self.check_public_network_connectivity(should_connect=True)
732
733 # remove resource from agents
734 hosting_agents = set(a["id"] for a in
Steve Heyman33735f22016-05-24 09:28:08 -0500735 list_hosts(self.router['id'])['agents'])
shipeiqic9a4a102016-04-20 17:39:03 +0800736 no_migration = agent_list_alive == hosting_agents
Yair Fried564d89d2015-08-06 17:02:12 +0300737 LOG.info("Router will be assigned to {mig} hosting agent".
738 format(mig="the same" if no_migration else "a new"))
739
740 for hosting_agent in hosting_agents:
Steve Heyman33735f22016-05-24 09:28:08 -0500741 unschedule_router(hosting_agent, self.router['id'])
Yair Fried564d89d2015-08-06 17:02:12 +0300742 self.assertNotIn(hosting_agent,
743 [a["id"] for a in
Steve Heyman33735f22016-05-24 09:28:08 -0500744 list_hosts(self.router['id'])['agents']],
Yair Fried564d89d2015-08-06 17:02:12 +0300745 'unscheduling router failed')
746
747 # verify resource is un-functional
748 self.check_public_network_connectivity(
749 should_connect=False,
750 msg='after router unscheduling',
751 should_check_floating_ip_status=False
752 )
753
754 # schedule resource to new agent
755 target_agent = list(hosting_agents if no_migration else
shipeiqic9a4a102016-04-20 17:39:03 +0800756 agent_list_alive - hosting_agents)[0]
Yair Fried564d89d2015-08-06 17:02:12 +0300757 schedule_router(target_agent,
piyush110786bc0faa62015-12-03 14:54:48 +0530758 router_id=self.router['id'])
Yair Fried564d89d2015-08-06 17:02:12 +0300759 self.assertEqual(
760 target_agent,
Steve Heyman33735f22016-05-24 09:28:08 -0500761 list_hosts(self.router['id'])['agents'][0]['id'],
Yair Fried564d89d2015-08-06 17:02:12 +0300762 "Router failed to reschedule. Hosting agent doesn't match "
763 "target agent")
764
765 # verify resource is functional
766 self.check_public_network_connectivity(
767 should_connect=True,
768 msg='After router rescheduling')
Yair Friedbc46f592015-11-18 16:29:34 +0200769
770 @test.requires_ext(service='network', extension='port-security')
Evgeny Antyshevaaf3fc92016-02-15 11:49:22 +0000771 @testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
772 'NIC hotplug not available')
Yair Friedbc46f592015-11-18 16:29:34 +0200773 @test.idempotent_id('7c0bb1a2-d053-49a4-98f9-ca1a1d849f63')
774 @test.services('compute', 'network')
775 def test_port_security_macspoofing_port(self):
776 """Tests port_security extension enforces mac spoofing
777
Eran Kuris7969e802015-12-15 13:43:46 +0200778 Neutron security groups always apply anti-spoof rules on the VMs. This
779 allows traffic to originate and terminate at the VM as expected, but
780 prevents traffic to pass through the VM. Anti-spoof rules are not
781 required in cases where the VM routes traffic through it.
782
783 The test steps are :
784 1. Create a new network.
785 2. Connect (hotplug) the VM to a new network.
YAMAMOTO Takashic3978412015-11-30 23:55:56 +0900786 3. Check the VM can ping a server on the new network ("peer")
Eran Kuris7969e802015-12-15 13:43:46 +0200787 4. Spoof the mac address of the new VM interface.
788 5. Check the Security Group enforces mac spoofing and blocks pings via
YAMAMOTO Takashic3978412015-11-30 23:55:56 +0900789 spoofed interface (VM cannot ping the peer).
Eran Kuris7969e802015-12-15 13:43:46 +0200790 6. Disable port-security of the spoofed port- set the flag to false.
791 7. Retest 3rd step and check that the Security Group allows pings via
792 the spoofed interface.
Yair Friedbc46f592015-11-18 16:29:34 +0200793 """
Eran Kuris7969e802015-12-15 13:43:46 +0200794
Yair Friedbc46f592015-11-18 16:29:34 +0200795 spoof_mac = "00:00:00:00:00:01"
796
797 # Create server
798 self._setup_network_and_servers()
YAMAMOTO Takashic368dde2015-11-30 23:04:14 +0900799 self.check_public_network_connectivity(should_connect=True)
Yair Friedbc46f592015-11-18 16:29:34 +0200800 self._create_new_network()
801 self._hotplug_server()
802 fip, server = self.floating_ip_tuple
803 new_ports = self._list_ports(device_id=server["id"],
804 network_id=self.new_net["id"])
805 spoof_port = new_ports[0]
806 private_key = self._get_server_key(server)
Steve Heyman33735f22016-05-24 09:28:08 -0500807 ssh_client = self.get_remote_client(fip['floating_ip_address'],
Yair Friedbc46f592015-11-18 16:29:34 +0200808 private_key=private_key)
Evgeny Antyshev9b77ae52016-02-16 09:48:57 +0000809 spoof_nic = ssh_client.get_nic_name_by_mac(spoof_port["mac_address"])
zhufl24208c22016-10-25 15:23:48 +0800810 peer = self._create_server(self.new_net)
Steve Heyman33735f22016-05-24 09:28:08 -0500811 peer_address = peer['addresses'][self.new_net['name']][0]['addr']
YAMAMOTO Takashic3978412015-11-30 23:55:56 +0900812 self._check_remote_connectivity(ssh_client, dest=peer_address,
Yair Friedbc46f592015-11-18 16:29:34 +0200813 nic=spoof_nic, should_succeed=True)
814 ssh_client.set_mac_address(spoof_nic, spoof_mac)
815 new_mac = ssh_client.get_mac_address(nic=spoof_nic)
816 self.assertEqual(spoof_mac, new_mac)
YAMAMOTO Takashic3978412015-11-30 23:55:56 +0900817 self._check_remote_connectivity(ssh_client, dest=peer_address,
Yair Friedbc46f592015-11-18 16:29:34 +0200818 nic=spoof_nic, should_succeed=False)
819 self.ports_client.update_port(spoof_port["id"],
820 port_security_enabled=False,
821 security_groups=[])
YAMAMOTO Takashic3978412015-11-30 23:55:56 +0900822 self._check_remote_connectivity(ssh_client, dest=peer_address,
Yair Friedbc46f592015-11-18 16:29:34 +0200823 nic=spoof_nic, should_succeed=True)