blob: 15a0a70aea37a5c72841c0e800cf100095f1b8db [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)
Yair Fried413bf2d2014-11-19 17:07:11 +0200107 self.network, self.subnet, self.router = self.create_networks(**kwargs)
David Shrewsbury9bac3662014-08-07 15:07:01 -0400108 self.check_networks()
109
Shuquan Huangb5c8beb2015-08-05 14:14:01 +0000110 self.ports = []
zhufl7a8f29d2017-02-17 10:16:45 +0800111 port_id = None
Jordan Pittierf72a1dc2015-08-04 12:50:33 +0000112 if boot_with_port:
Matt Riedemann17940732015-03-13 14:18:19 +0000113 # create a port on the network and boot with that
zhufl7a8f29d2017-02-17 10:16:45 +0800114 port_id = self._create_port(self.network['id'])['id']
115 self.ports.append({'port': port_id})
Matt Riedemann17940732015-03-13 14:18:19 +0000116
zhufl7a8f29d2017-02-17 10:16:45 +0800117 server = self._create_server(self.network, port_id)
Yair Frieded8392f2014-01-15 17:21:35 +0200118 self._check_tenant_network_connectivity()
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200119
Yair Friedae0e73d2014-11-24 11:56:26 +0200120 floating_ip = self.create_floating_ip(server)
121 self.floating_ip_tuple = Floating_IP_tuple(floating_ip, server)
Maru Newby81f07a02012-09-05 20:21:19 -0700122
Yair Frieded8392f2014-01-15 17:21:35 +0200123 def check_networks(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000124 """Checks that we see the newly created network/subnet/router
125
126 via checking the result of list_[networks,routers,subnets]
Yair Frieded8392f2014-01-15 17:21:35 +0200127 """
128
Jordan Pittier64e6b442017-02-20 19:29:02 +0100129 seen_nets = self.admin_manager.networks_client.list_networks()
130 seen_names = [n['name'] for n in seen_nets['networks']]
131 seen_ids = [n['id'] for n in seen_nets['networks']]
Steve Heyman33735f22016-05-24 09:28:08 -0500132 self.assertIn(self.network['name'], seen_names)
133 self.assertIn(self.network['id'], seen_ids)
Yair Frieded8392f2014-01-15 17:21:35 +0200134
David Shrewsbury9bac3662014-08-07 15:07:01 -0400135 if self.subnet:
Jordan Pittier64e6b442017-02-20 19:29:02 +0100136 seen_subnets = self.admin_manager.subnets_client.list_subnets()
137 seen_net_ids = [n['network_id'] for n in seen_subnets['subnets']]
138 seen_subnet_ids = [n['id'] for n in seen_subnets['subnets']]
Steve Heyman33735f22016-05-24 09:28:08 -0500139 self.assertIn(self.network['id'], seen_net_ids)
140 self.assertIn(self.subnet['id'], seen_subnet_ids)
Yair Frieded8392f2014-01-15 17:21:35 +0200141
David Shrewsbury9bac3662014-08-07 15:07:01 -0400142 if self.router:
Jordan Pittier64e6b442017-02-20 19:29:02 +0100143 seen_routers = self.admin_manager.routers_client.list_routers()
144 seen_router_ids = [n['id'] for n in seen_routers['routers']]
145 seen_router_names = [n['name'] for n in seen_routers['routers']]
Steve Heyman33735f22016-05-24 09:28:08 -0500146 self.assertIn(self.router['name'],
David Shrewsbury9bac3662014-08-07 15:07:01 -0400147 seen_router_names)
Steve Heyman33735f22016-05-24 09:28:08 -0500148 self.assertIn(self.router['id'],
David Shrewsbury9bac3662014-08-07 15:07:01 -0400149 seen_router_ids)
Gavin Brebner851c3502013-01-18 13:14:10 +0000150
zhufl24208c22016-10-25 15:23:48 +0800151 def _create_server(self, network, port_id=None):
Yair Fried1fc32a12014-08-04 09:11:30 +0300152 keypair = self.create_keypair()
153 self.keypairs[keypair['name']] = keypair
Jordan Pittier37b94a02017-02-21 18:11:55 +0100154 security_groups = [
155 {'name': self._create_security_group()['name']}
156 ]
Steve Heyman33735f22016-05-24 09:28:08 -0500157 network = {'uuid': network['id']}
Matt Riedemann17940732015-03-13 14:18:19 +0000158 if port_id is not None:
lanoux5fc14522015-09-21 08:17:35 +0000159 network['port'] = port_id
160
161 server = self.create_server(
lanoux5fc14522015-09-21 08:17:35 +0000162 networks=[network],
163 key_name=keypair['name'],
zhufl13c9c892017-02-10 12:04:07 +0800164 security_groups=security_groups)
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
Jordan Pittier64e6b442017-02-20 19:29:02 +0100244 port_list = self.admin_manager.ports_client.list_ports(
245 device_id=server['id'])['ports']
Yair Fried3097dc12014-01-26 08:46:43 +0200246 self.assertEqual(1, len(port_list))
247 old_port = port_list[0]
David Kranzb2b0c182015-02-18 13:28:19 -0500248 interface = self.interface_client.create_interface(
Ken'ichi Ohmichi9509b962015-07-07 05:30:15 +0000249 server_id=server['id'],
Steve Heyman33735f22016-05-24 09:28:08 -0500250 net_id=self.new_net['id'])['interfaceAttachment']
Ken'ichi Ohmichi43e7fcf2016-04-04 11:59:13 -0700251 self.addCleanup(self.ports_client.wait_for_resource_deletion,
252 interface['port_id'])
Jordan Pittier9e227c52016-02-09 14:35:18 +0100253 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
Yair Fried1fc32a12014-08-04 09:11:30 +0300254 self.interface_client.delete_interface,
255 server['id'], interface['port_id'])
Yair Fried3097dc12014-01-26 08:46:43 +0200256
257 def check_ports():
Jordan Pittier64e6b442017-02-20 19:29:02 +0100258 self.new_port_list = [
259 port for port in
260 self.admin_manager.ports_client.list_ports(
261 device_id=server['id'])['ports']
262 if port['id'] != old_port['id']
263 ]
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200264 return len(self.new_port_list) == 1
Yair Fried3097dc12014-01-26 08:46:43 +0200265
Jordan Pittier35a63752016-08-30 13:09:12 +0200266 if not test_utils.call_until_true(
267 check_ports, CONF.network.build_timeout,
268 CONF.network.build_interval):
Matt Riedemann892094e2015-02-05 07:24:02 -0800269 raise exceptions.TimeoutException(
270 "No new port attached to the server in time (%s sec)! "
271 "Old port: %s. Number of new ports: %d" % (
272 CONF.network.build_timeout, old_port,
273 len(self.new_port_list)))
Steve Heyman33735f22016-05-24 09:28:08 -0500274 new_port = self.new_port_list[0]
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200275
276 def check_new_nic():
277 new_nic_list = self._get_server_nics(ssh_client)
278 self.diff_list = [n for n in new_nic_list if n not in old_nic_list]
279 return len(self.diff_list) == 1
280
Jordan Pittier35a63752016-08-30 13:09:12 +0200281 if not test_utils.call_until_true(
282 check_new_nic, CONF.network.build_timeout,
283 CONF.network.build_interval):
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200284 raise exceptions.TimeoutException("Interface not visible on the "
285 "guest after %s sec"
286 % CONF.network.build_timeout)
287
288 num, new_nic = self.diff_list[0]
Ken'ichi Ohmichicc1264c2017-03-01 12:27:28 -0800289 ssh_client.assign_static_ip(
290 nic=new_nic, addr=new_port['fixed_ips'][0]['ip_address'],
291 network_mask_bits=CONF.network.project_network_mask_bits)
Yair Friedbc46f592015-11-18 16:29:34 +0200292 ssh_client.set_nic_state(nic=new_nic)
Yair Fried3097dc12014-01-26 08:46:43 +0200293
294 def _get_server_nics(self, ssh_client):
295 reg = re.compile(r'(?P<num>\d+): (?P<nic_name>\w+):')
Ken'ichi Ohmichi84aeba62017-03-01 18:31:20 -0800296 ipatxt = ssh_client.exec_command("ip address")
Yair Fried3097dc12014-01-26 08:46:43 +0200297 return reg.findall(ipatxt)
298
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300299 def _check_network_internal_connectivity(self, network,
300 should_connect=True):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000301 """via ssh check VM internal connectivity:
302
Yair Fried06552292013-11-11 12:10:09 +0200303 - ping internal gateway and DHCP port, implying in-tenant connectivity
304 pinging both, because L3 and DHCP agents might be on different nodes
Yair Fried3097dc12014-01-26 08:46:43 +0200305 """
306 floating_ip, server = self.floating_ip_tuple
307 # get internal ports' ips:
308 # get all network ports in the new network
Jordan Pittier64e6b442017-02-20 19:29:02 +0100309 internal_ips = (
310 p['fixed_ips'][0]['ip_address'] for p in
311 self.admin_manager.ports_client.list_ports(
312 tenant_id=server['tenant_id'],
313 network_id=network['id'])['ports']
314 if p['device_owner'].startswith('network')
315 )
Yair Fried3097dc12014-01-26 08:46:43 +0200316
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300317 self._check_server_connectivity(floating_ip,
318 internal_ips,
319 should_connect)
Yair Fried06552292013-11-11 12:10:09 +0200320
321 def _check_network_external_connectivity(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000322 """ping default gateway to imply external connectivity"""
Yair Fried06552292013-11-11 12:10:09 +0200323 if not CONF.network.public_network_id:
324 msg = 'public network not defined.'
325 LOG.info(msg)
326 return
327
Andrew Boik4a3daf12015-03-27 01:59:31 -0400328 # We ping the external IP from the instance using its floating IP
329 # which is always IPv4, so we must only test connectivity to
330 # external IPv4 IPs if the external network is dualstack.
Jordan Pittier64e6b442017-02-20 19:29:02 +0100331 v4_subnets = [
332 s for s in self.admin_manager.subnets_client.list_subnets(
333 network_id=CONF.network.public_network_id)['subnets']
334 if s['ip_version'] == 4
335 ]
Andrew Boik4a3daf12015-03-27 01:59:31 -0400336 self.assertEqual(1, len(v4_subnets),
337 "Found %d IPv4 subnets" % len(v4_subnets))
Yair Fried06552292013-11-11 12:10:09 +0200338
Andrew Boik4a3daf12015-03-27 01:59:31 -0400339 external_ips = [v4_subnets[0]['gateway_ip']]
Yair Fried06552292013-11-11 12:10:09 +0200340 self._check_server_connectivity(self.floating_ip_tuple.floating_ip,
341 external_ips)
342
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300343 def _check_server_connectivity(self, floating_ip, address_list,
344 should_connect=True):
Steve Heyman33735f22016-05-24 09:28:08 -0500345 ip_address = floating_ip['floating_ip_address']
Yair Fried1fc32a12014-08-04 09:11:30 +0300346 private_key = self._get_server_key(self.floating_ip_tuple.server)
Jordan Pittierbbb17122016-01-26 17:10:55 +0100347 ssh_source = self.get_remote_client(
348 ip_address, private_key=private_key)
Yair Fried3097dc12014-01-26 08:46:43 +0200349
Yair Fried06552292013-11-11 12:10:09 +0200350 for remote_ip in address_list:
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900351 self.check_remote_connectivity(ssh_source, remote_ip,
352 should_connect)
Yair Fried3097dc12014-01-26 08:46:43 +0200353
Yoshihiro Kaneko05670262014-01-18 19:22:44 +0900354 @test.attr(type='smoke')
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800355 @decorators.idempotent_id('f323b3ba-82f8-4db7-8ea6-6a895869ec49')
Yoshihiro Kaneko05670262014-01-18 19:22:44 +0900356 @test.services('compute', 'network')
Matthew Treinish2b59f842013-09-09 20:32:51 +0000357 def test_network_basic_ops(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000358 """Basic network operation test
359
Yair Fried3097dc12014-01-26 08:46:43 +0200360 For a freshly-booted VM with an IP address ("port") on a given
361 network:
362
363 - the Tempest host can ping the IP address. This implies, but
364 does not guarantee (see the ssh check that follows), that the
365 VM has been assigned the correct IP address and has
366 connectivity to the Tempest host.
367
368 - the Tempest host can perform key-based authentication to an
369 ssh server hosted at the IP address. This check guarantees
370 that the IP address is associated with the target VM.
371
Yair Fried3097dc12014-01-26 08:46:43 +0200372 - the Tempest host can ssh into the VM via the IP address and
373 successfully execute the following:
374
375 - ping an external IP address, implying external connectivity.
376
377 - ping an external hostname, implying that dns is correctly
378 configured.
379
380 - ping an internal IP address, implying connectivity to another
381 VM on the same network.
382
Yair Fried06552292013-11-11 12:10:09 +0200383 - detach the floating-ip from the VM and verify that it becomes
384 unreachable
385
386 - associate detached floating ip to a new VM and verify connectivity.
387 VMs are created with unique keypair so connectivity also asserts that
388 floating IP is associated with the new VM instead of the old one
389
Yair Fried45f92952014-06-26 05:19:19 +0300390 Verifies that floating IP status is updated correctly after each change
391
Yair Fried06552292013-11-11 12:10:09 +0200392
Yair Fried3097dc12014-01-26 08:46:43 +0200393 """
David Shrewsbury9bac3662014-08-07 15:07:01 -0400394 self._setup_network_and_servers()
Yair Friedae0e73d2014-11-24 11:56:26 +0200395 self.check_public_network_connectivity(should_connect=True)
Yair Fried06552292013-11-11 12:10:09 +0200396 self._check_network_internal_connectivity(network=self.network)
397 self._check_network_external_connectivity()
Yair Fried9a551c42013-12-15 14:59:34 +0200398 self._disassociate_floating_ips()
Yair Friedae0e73d2014-11-24 11:56:26 +0200399 self.check_public_network_connectivity(should_connect=False,
400 msg="after disassociate "
401 "floating ip")
Yair Fried05db2522013-11-18 11:02:10 +0200402 self._reassociate_floating_ips()
Yair Friedae0e73d2014-11-24 11:56:26 +0200403 self.check_public_network_connectivity(should_connect=True,
404 msg="after re-associate "
405 "floating ip")
Yair Fried3097dc12014-01-26 08:46:43 +0200406
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800407 @decorators.idempotent_id('b158ea55-472e-4086-8fa9-c64ac0c6c1d0')
Ihar Hrachyshkaf9227c02016-09-15 11:16:47 +0000408 @testtools.skipUnless(test.is_extension_enabled('net-mtu', 'network'),
409 'No way to calculate MTU for networks')
Sean Dague49505df2017-03-01 11:35:58 -0500410 @test.attr(type='slow')
Ihar Hrachyshkaf9227c02016-09-15 11:16:47 +0000411 @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")
Sean Dague49505df2017-03-01 11:35:58 -0500423 @test.attr(type='slow')
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300424 @test.services('compute', 'network')
425 def test_connectivity_between_vms_on_different_networks(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000426 """Test connectivity between VMs on different networks
427
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300428 For a freshly-booted VM with an IP address ("port") on a given
429 network:
430
431 - the Tempest host can ping the IP address.
432
433 - the Tempest host can ssh into the VM via the IP address and
434 successfully execute the following:
435
436 - ping an external IP address, implying external connectivity.
437
438 - ping an external hostname, implying that dns is correctly
439 configured.
440
441 - ping an internal IP address, implying connectivity to another
442 VM on the same network.
443
444 - Create another network on the same tenant with subnet, create
445 an VM on the new network.
446
447 - Ping the new VM from previous VM failed since the new network
448 was not attached to router yet.
449
450 - Attach the new network to the router, Ping the new VM from
451 previous VM succeed.
452
453 """
454 self._setup_network_and_servers()
455 self.check_public_network_connectivity(should_connect=True)
456 self._check_network_internal_connectivity(network=self.network)
457 self._check_network_external_connectivity()
458 self._create_new_network(create_gateway=True)
zhufl24208c22016-10-25 15:23:48 +0800459 self._create_server(self.new_net)
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300460 self._check_network_internal_connectivity(network=self.new_net,
461 should_connect=False)
Steve Heyman33735f22016-05-24 09:28:08 -0500462 router_id = self.router['id']
463 self.routers_client.add_router_interface(
464 router_id, subnet_id=self.new_subnet['id'])
465
466 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
467 self.routers_client.remove_router_interface,
468 router_id, subnet_id=self.new_subnet['id'])
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300469 self._check_network_internal_connectivity(network=self.new_net,
470 should_connect=True)
471
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800472 @decorators.idempotent_id('c5adff73-e961-41f1-b4a9-343614f18cfa')
Adam Gandelman7186f7a2014-07-23 09:28:56 -0400473 @testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
474 'NIC hotplug not available')
Itzik Brown2ca01cd2014-12-08 12:58:20 +0200475 @testtools.skipIf(CONF.network.port_vnic_type in ['direct', 'macvtap'],
476 'NIC hotplug not supported for '
477 'vnic_type direct or macvtap')
Yair Fried3097dc12014-01-26 08:46:43 +0200478 @test.services('compute', 'network')
479 def test_hotplug_nic(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000480 """Test hotplug network interface
481
Arief3f6e812016-09-28 16:48:20 +0300482 1. Create a network and a VM.
483 2. Check connectivity to the VM via a public network.
484 3. Create a new network, with no gateway.
485 4. Bring up a new interface
486 5. check the VM reach the new network
Yair Fried3097dc12014-01-26 08:46:43 +0200487
488 """
David Shrewsbury9bac3662014-08-07 15:07:01 -0400489 self._setup_network_and_servers()
Yair Friedae0e73d2014-11-24 11:56:26 +0200490 self.check_public_network_connectivity(should_connect=True)
Yair Fried3097dc12014-01-26 08:46:43 +0200491 self._create_new_network()
492 self._hotplug_server()
Yair Fried06552292013-11-11 12:10:09 +0200493 self._check_network_internal_connectivity(network=self.new_net)
Alok Maurya6384bbb2014-07-13 06:44:29 -0700494
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800495 @decorators.idempotent_id('04b9fe4e-85e8-4aea-b937-ea93885ac59f')
Thiago Paiva66cded22016-08-15 14:55:58 -0300496 @testtools.skipIf(CONF.network.shared_physical_network,
497 'Router state can be altered only with multitenant '
498 'networks capabilities')
Sean Dague49505df2017-03-01 11:35:58 -0500499 @test.attr(type='slow')
Alok Maurya6384bbb2014-07-13 06:44:29 -0700500 @test.services('compute', 'network')
501 def test_update_router_admin_state(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000502 """Test to update admin state up of router
503
Alok Maurya6384bbb2014-07-13 06:44:29 -0700504 1. Check public connectivity before updating
505 admin_state_up attribute of router to False
506 2. Check public connectivity after updating
507 admin_state_up attribute of router to False
508 3. Check public connectivity after updating
509 admin_state_up attribute of router to True
510 """
511 self._setup_network_and_servers()
512 self.check_public_network_connectivity(
513 should_connect=True, msg="before updating "
514 "admin_state_up of router to False")
515 self._update_router_admin_state(self.router, False)
516 # TODO(alokmaurya): Remove should_check_floating_ip_status=False check
517 # once bug 1396310 is fixed
518
519 self.check_public_network_connectivity(
520 should_connect=False, msg="after updating "
521 "admin_state_up of router to False",
522 should_check_floating_ip_status=False)
523 self._update_router_admin_state(self.router, True)
524 self.check_public_network_connectivity(
525 should_connect=True, msg="after updating "
526 "admin_state_up of router to True")
Yair Fried413bf2d2014-11-19 17:07:11 +0200527
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800528 @decorators.idempotent_id('d8bb918e-e2df-48b2-97cd-b73c95450980')
Thiago Paiva66cded22016-08-15 14:55:58 -0300529 @testtools.skipIf(CONF.network.shared_physical_network,
530 'network isolation not available')
Yair Fried413bf2d2014-11-19 17:07:11 +0200531 @testtools.skipUnless(CONF.scenario.dhcp_client,
532 "DHCP client is not available.")
Sean Dague49505df2017-03-01 11:35:58 -0500533 @test.attr(type='slow')
Yair Fried413bf2d2014-11-19 17:07:11 +0200534 @test.services('compute', 'network')
535 def test_subnet_details(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000536 """Tests that subnet's extra configuration details are affecting VMs.
537
538 This test relies on non-shared, isolated tenant networks.
Yair Fried413bf2d2014-11-19 17:07:11 +0200539
540 NOTE: Neutron subnets push data to servers via dhcp-agent, so any
541 update in subnet requires server to actively renew its DHCP lease.
542
543 1. Configure subnet with dns nameserver
544 2. retrieve the VM's configured dns and verify it matches the one
545 configured for the subnet.
546 3. update subnet's dns
547 4. retrieve the VM's configured dns and verify it matches the new one
548 configured for the subnet.
549
550 TODO(yfried): add host_routes
551
552 any resolution check would be testing either:
553 * l3 forwarding (tested in test_network_basic_ops)
554 * Name resolution of an external DNS nameserver - out of scope for
555 Tempest
556 """
557 # this test check only updates (no actual resolution) so using
558 # arbitrary ip addresses as nameservers, instead of parsing CONF
559 initial_dns_server = '1.2.3.4'
560 alt_dns_server = '9.8.7.6'
Yair Friedbb0ea392015-01-19 07:26:08 +0000561
562 # renewal should be immediate.
563 # Timeouts are suggested by salvatore-orlando in
564 # https://bugs.launchpad.net/neutron/+bug/1412325/comments/3
565 renew_delay = CONF.network.build_interval
566 renew_timeout = CONF.network.build_timeout
567
Yair Fried413bf2d2014-11-19 17:07:11 +0200568 self._setup_network_and_servers(dns_nameservers=[initial_dns_server])
569 self.check_public_network_connectivity(should_connect=True)
570
571 floating_ip, server = self.floating_ip_tuple
Steve Heyman33735f22016-05-24 09:28:08 -0500572 ip_address = floating_ip['floating_ip_address']
Yair Fried413bf2d2014-11-19 17:07:11 +0200573 private_key = self._get_server_key(server)
Jordan Pittierbbb17122016-01-26 17:10:55 +0100574 ssh_client = self.get_remote_client(
575 ip_address, private_key=private_key)
Yair Fried413bf2d2014-11-19 17:07:11 +0200576
armando-migliaccio424aa412015-02-22 17:55:17 -0800577 dns_servers = [initial_dns_server]
578 servers = ssh_client.get_dns_servers()
579 self.assertEqual(set(dns_servers), set(servers),
580 'Looking for servers: {trgt_serv}. '
581 'Retrieved DNS nameservers: {act_serv} '
582 'From host: {host}.'
583 .format(host=ssh_client.ssh_client.host,
584 act_serv=servers,
585 trgt_serv=dns_servers))
Yair Fried413bf2d2014-11-19 17:07:11 +0200586
Steve Heyman33735f22016-05-24 09:28:08 -0500587 self.subnet = self.subnets_client.update_subnet(
588 self.subnet['id'], dns_nameservers=[alt_dns_server])['subnet']
589
Yair Fried413bf2d2014-11-19 17:07:11 +0200590 # asserts that Neutron DB has updated the nameservers
Steve Heyman33735f22016-05-24 09:28:08 -0500591 self.assertEqual([alt_dns_server], self.subnet['dns_nameservers'],
Yair Fried413bf2d2014-11-19 17:07:11 +0200592 "Failed to update subnet's nameservers")
593
Yair Friedbb0ea392015-01-19 07:26:08 +0000594 def check_new_dns_server():
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000595 # NOTE: Server needs to renew its dhcp lease in order to get new
596 # definitions from subnet
597 # NOTE(amuller): we are renewing the lease as part of the retry
598 # because Neutron updates dnsmasq asynchronously after the
599 # subnet-update API call returns.
Ken'ichi Ohmichi4e337852017-03-01 12:04:23 -0800600 ssh_client.renew_lease(fixed_ip=floating_ip['fixed_ip_address'],
601 dhcp_client=CONF.scenario.dhcp_client)
armando-migliaccio424aa412015-02-22 17:55:17 -0800602 if ssh_client.get_dns_servers() != [alt_dns_server]:
Yair Friedbb0ea392015-01-19 07:26:08 +0000603 LOG.debug("Failed to update DNS nameservers")
604 return False
605 return True
606
Jordan Pittier35a63752016-08-30 13:09:12 +0200607 self.assertTrue(test_utils.call_until_true(check_new_dns_server,
608 renew_timeout,
609 renew_delay),
Yair Friedbb0ea392015-01-19 07:26:08 +0000610 msg="DHCP renewal failed to fetch "
611 "new DNS nameservers")
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800612
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800613 @decorators.idempotent_id('f5dfcc22-45fd-409f-954c-5bd500d7890b')
Itzik Brownbeb30d32015-03-29 09:42:54 +0300614 @testtools.skipUnless(CONF.network_feature_enabled.port_admin_state_change,
615 "Changing a port's admin state is not supported "
616 "by the test environment")
Sean Dague49505df2017-03-01 11:35:58 -0500617 @test.attr(type='slow')
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800618 @test.services('compute', 'network')
619 def test_update_instance_port_admin_state(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000620 """Test to update admin_state_up attribute of instance port
621
Carlos Goncalves539f8362016-11-04 14:55:02 +0100622 1. Check public and project connectivity before updating
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800623 admin_state_up attribute of instance port to False
Carlos Goncalves539f8362016-11-04 14:55:02 +0100624 2. Check public and project connectivity after updating
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800625 admin_state_up attribute of instance port to False
Carlos Goncalves539f8362016-11-04 14:55:02 +0100626 3. Check public and project connectivity after updating
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800627 admin_state_up attribute of instance port to True
628 """
629 self._setup_network_and_servers()
630 floating_ip, server = self.floating_ip_tuple
631 server_id = server['id']
Jordan Pittier64e6b442017-02-20 19:29:02 +0100632 port_id = self.admin_manager.ports_client.list_ports(
633 device_id=server_id)['ports'][0]['id']
Carlos Goncalves539f8362016-11-04 14:55:02 +0100634 server_pip = server['addresses'][self.network['name']][0]['addr']
635
636 server2 = self._create_server(self.network)
637 server2_fip = self.create_floating_ip(server2)
638
639 private_key = self._get_server_key(server2)
640 ssh_client = self.get_remote_client(server2_fip['floating_ip_address'],
641 private_key=private_key)
642
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800643 self.check_public_network_connectivity(
644 should_connect=True, msg="before updating "
645 "admin_state_up of instance port to False")
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900646 self.check_remote_connectivity(ssh_client, dest=server_pip,
647 should_succeed=True)
John Warren49c0fe52015-10-22 12:35:54 -0400648 self.ports_client.update_port(port_id, admin_state_up=False)
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800649 self.check_public_network_connectivity(
650 should_connect=False, msg="after updating "
651 "admin_state_up of instance port to False",
652 should_check_floating_ip_status=False)
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900653 self.check_remote_connectivity(ssh_client, dest=server_pip,
654 should_succeed=False)
John Warren49c0fe52015-10-22 12:35:54 -0400655 self.ports_client.update_port(port_id, admin_state_up=True)
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800656 self.check_public_network_connectivity(
657 should_connect=True, msg="after updating "
658 "admin_state_up of instance port to True")
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900659 self.check_remote_connectivity(ssh_client, dest=server_pip,
660 should_succeed=True)
Matt Riedemann17940732015-03-13 14:18:19 +0000661
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800662 @decorators.idempotent_id('759462e1-8535-46b0-ab3a-33aa45c55aaa')
Sean Dague49505df2017-03-01 11:35:58 -0500663 @test.attr(type='slow')
Matt Riedemann17940732015-03-13 14:18:19 +0000664 @test.services('compute', 'network')
665 def test_preserve_preexisting_port(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000666 """Test preserve pre-existing port
667
668 Tests that a pre-existing port provided on server boot is not deleted
669 if the server is deleted.
Matt Riedemann17940732015-03-13 14:18:19 +0000670
671 Nova should unbind the port from the instance on delete if the port was
672 not created by Nova as part of the boot request.
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400673
674 We should also be able to boot another server with the same port.
Matt Riedemann17940732015-03-13 14:18:19 +0000675 """
676 # Setup the network, create a port and boot the server from that port.
677 self._setup_network_and_servers(boot_with_port=True)
678 _, server = self.floating_ip_tuple
Shuquan Huangb5c8beb2015-08-05 14:14:01 +0000679 self.assertEqual(1, len(self.ports),
680 'There should only be one port created for '
681 'server %s.' % server['id'])
682 port_id = self.ports[0]['port']
683 self.assertIsNotNone(port_id,
Matt Riedemann17940732015-03-13 14:18:19 +0000684 'Server should have been created from a '
685 'pre-existing port.')
686 # Assert the port is bound to the server.
Jordan Pittier64e6b442017-02-20 19:29:02 +0100687 port_list = self.admin_manager.ports_client.list_ports(
688 device_id=server['id'], network_id=self.network['id'])['ports']
Matt Riedemann17940732015-03-13 14:18:19 +0000689 self.assertEqual(1, len(port_list),
690 'There should only be one port created for '
691 'server %s.' % server['id'])
Shuquan Huangb5c8beb2015-08-05 14:14:01 +0000692 self.assertEqual(port_id, port_list[0]['id'])
Matt Riedemann17940732015-03-13 14:18:19 +0000693 # Delete the server.
694 self.servers_client.delete_server(server['id'])
Ken'ichi Ohmichie91a0c62015-08-13 02:09:16 +0000695 waiters.wait_for_server_termination(self.servers_client, server['id'])
Matt Riedemann17940732015-03-13 14:18:19 +0000696 # Assert the port still exists on the network but is unbound from
697 # the deleted server.
John Warren49c0fe52015-10-22 12:35:54 -0400698 port = self.ports_client.show_port(port_id)['port']
Matt Riedemann17940732015-03-13 14:18:19 +0000699 self.assertEqual(self.network['id'], port['network_id'])
700 self.assertEqual('', port['device_id'])
701 self.assertEqual('', port['device_owner'])
Yair Fried564d89d2015-08-06 17:02:12 +0300702
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400703 # Boot another server with the same port to make sure nothing was
704 # left around that could cause issues.
zhufl24208c22016-10-25 15:23:48 +0800705 server = self._create_server(self.network, port['id'])
Jordan Pittier64e6b442017-02-20 19:29:02 +0100706 port_list = self.admin_manager.ports_client.list_ports(
707 device_id=server['id'], network_id=self.network['id'])['ports']
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400708 self.assertEqual(1, len(port_list),
709 'There should only be one port created for '
710 'server %s.' % server['id'])
711 self.assertEqual(port['id'], port_list[0]['id'])
712
YAMAMOTO Takashi56216312015-09-10 20:05:03 +0900713 @test.requires_ext(service='network', extension='l3_agent_scheduler')
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800714 @decorators.idempotent_id('2e788c46-fb3f-4ac9-8f82-0561555bea73')
Sean Dague49505df2017-03-01 11:35:58 -0500715 @test.attr(type='slow')
Yair Fried564d89d2015-08-06 17:02:12 +0300716 @test.services('compute', 'network')
717 def test_router_rescheduling(self):
718 """Tests that router can be removed from agent and add to a new agent.
719
720 1. Verify connectivity
721 2. Remove router from all l3-agents
722 3. Verify connectivity is down
723 4. Assign router to new l3-agent (or old one if no new agent is
724 available)
725 5. Verify connectivity
726 """
727
728 # TODO(yfried): refactor this test to be used for other agents (dhcp)
729 # as well
730
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000731 list_hosts = (self.admin_manager.routers_client.
Yair Fried564d89d2015-08-06 17:02:12 +0300732 list_l3_agents_hosting_router)
Ken'ichi Ohmichi71860062015-12-15 08:20:13 +0000733 schedule_router = (self.admin_manager.network_agents_client.
Ken'ichi Ohmichi70a24e92016-01-06 01:08:27 +0000734 create_router_on_l3_agent)
Ken'ichi Ohmichi71860062015-12-15 08:20:13 +0000735 unschedule_router = (self.admin_manager.network_agents_client.
Ken'ichi Ohmichi70a24e92016-01-06 01:08:27 +0000736 delete_router_from_l3_agent)
Yair Fried564d89d2015-08-06 17:02:12 +0300737
Jordan Pittier64e6b442017-02-20 19:29:02 +0100738 agent_list_alive = set(
739 a["id"] for a in
740 self.admin_manager.network_agents_client.list_agents(
741 agent_type="L3 agent")['agents'] if a["alive"] is True
742 )
Yair Fried564d89d2015-08-06 17:02:12 +0300743 self._setup_network_and_servers()
Kevin Benton3b63aa12015-08-27 17:15:44 -0700744
745 # NOTE(kevinbenton): we have to use the admin credentials to check
Sean Dagueed6e5862016-04-04 10:49:13 -0400746 # for the distributed flag because self.router only has a project view.
Steve Heyman33735f22016-05-24 09:28:08 -0500747 admin = self.admin_manager.routers_client.show_router(
748 self.router['id'])
Kevin Benton3b63aa12015-08-27 17:15:44 -0700749 if admin['router'].get('distributed', False):
750 msg = "Rescheduling test does not apply to distributed routers."
751 raise self.skipException(msg)
752
Yair Fried564d89d2015-08-06 17:02:12 +0300753 self.check_public_network_connectivity(should_connect=True)
754
755 # remove resource from agents
756 hosting_agents = set(a["id"] for a in
Steve Heyman33735f22016-05-24 09:28:08 -0500757 list_hosts(self.router['id'])['agents'])
shipeiqic9a4a102016-04-20 17:39:03 +0800758 no_migration = agent_list_alive == hosting_agents
Yair Fried564d89d2015-08-06 17:02:12 +0300759 LOG.info("Router will be assigned to {mig} hosting agent".
760 format(mig="the same" if no_migration else "a new"))
761
762 for hosting_agent in hosting_agents:
Steve Heyman33735f22016-05-24 09:28:08 -0500763 unschedule_router(hosting_agent, self.router['id'])
Yair Fried564d89d2015-08-06 17:02:12 +0300764 self.assertNotIn(hosting_agent,
765 [a["id"] for a in
Steve Heyman33735f22016-05-24 09:28:08 -0500766 list_hosts(self.router['id'])['agents']],
Yair Fried564d89d2015-08-06 17:02:12 +0300767 'unscheduling router failed')
768
769 # verify resource is un-functional
770 self.check_public_network_connectivity(
771 should_connect=False,
772 msg='after router unscheduling',
Yair Fried564d89d2015-08-06 17:02:12 +0300773 )
774
775 # schedule resource to new agent
776 target_agent = list(hosting_agents if no_migration else
shipeiqic9a4a102016-04-20 17:39:03 +0800777 agent_list_alive - hosting_agents)[0]
Yair Fried564d89d2015-08-06 17:02:12 +0300778 schedule_router(target_agent,
piyush110786bc0faa62015-12-03 14:54:48 +0530779 router_id=self.router['id'])
Yair Fried564d89d2015-08-06 17:02:12 +0300780 self.assertEqual(
781 target_agent,
Steve Heyman33735f22016-05-24 09:28:08 -0500782 list_hosts(self.router['id'])['agents'][0]['id'],
Yair Fried564d89d2015-08-06 17:02:12 +0300783 "Router failed to reschedule. Hosting agent doesn't match "
784 "target agent")
785
786 # verify resource is functional
787 self.check_public_network_connectivity(
788 should_connect=True,
789 msg='After router rescheduling')
Yair Friedbc46f592015-11-18 16:29:34 +0200790
791 @test.requires_ext(service='network', extension='port-security')
Evgeny Antyshevaaf3fc92016-02-15 11:49:22 +0000792 @testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
793 'NIC hotplug not available')
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800794 @decorators.idempotent_id('7c0bb1a2-d053-49a4-98f9-ca1a1d849f63')
Sean Dague49505df2017-03-01 11:35:58 -0500795 @test.attr(type='slow')
Yair Friedbc46f592015-11-18 16:29:34 +0200796 @test.services('compute', 'network')
797 def test_port_security_macspoofing_port(self):
798 """Tests port_security extension enforces mac spoofing
799
Eran Kuris7969e802015-12-15 13:43:46 +0200800 Neutron security groups always apply anti-spoof rules on the VMs. This
801 allows traffic to originate and terminate at the VM as expected, but
802 prevents traffic to pass through the VM. Anti-spoof rules are not
803 required in cases where the VM routes traffic through it.
804
805 The test steps are :
806 1. Create a new network.
807 2. Connect (hotplug) the VM to a new network.
YAMAMOTO Takashic3978412015-11-30 23:55:56 +0900808 3. Check the VM can ping a server on the new network ("peer")
Eran Kuris7969e802015-12-15 13:43:46 +0200809 4. Spoof the mac address of the new VM interface.
810 5. Check the Security Group enforces mac spoofing and blocks pings via
YAMAMOTO Takashic3978412015-11-30 23:55:56 +0900811 spoofed interface (VM cannot ping the peer).
Eran Kuris7969e802015-12-15 13:43:46 +0200812 6. Disable port-security of the spoofed port- set the flag to false.
813 7. Retest 3rd step and check that the Security Group allows pings via
814 the spoofed interface.
Yair Friedbc46f592015-11-18 16:29:34 +0200815 """
Eran Kuris7969e802015-12-15 13:43:46 +0200816
Yair Friedbc46f592015-11-18 16:29:34 +0200817 spoof_mac = "00:00:00:00:00:01"
818
819 # Create server
820 self._setup_network_and_servers()
YAMAMOTO Takashic368dde2015-11-30 23:04:14 +0900821 self.check_public_network_connectivity(should_connect=True)
Yair Friedbc46f592015-11-18 16:29:34 +0200822 self._create_new_network()
823 self._hotplug_server()
824 fip, server = self.floating_ip_tuple
Jordan Pittier64e6b442017-02-20 19:29:02 +0100825 new_ports = self.admin_manager.ports_client.list_ports(
826 device_id=server["id"], network_id=self.new_net["id"])['ports']
Yair Friedbc46f592015-11-18 16:29:34 +0200827 spoof_port = new_ports[0]
828 private_key = self._get_server_key(server)
Steve Heyman33735f22016-05-24 09:28:08 -0500829 ssh_client = self.get_remote_client(fip['floating_ip_address'],
Yair Friedbc46f592015-11-18 16:29:34 +0200830 private_key=private_key)
Evgeny Antyshev9b77ae52016-02-16 09:48:57 +0000831 spoof_nic = ssh_client.get_nic_name_by_mac(spoof_port["mac_address"])
zhufl24208c22016-10-25 15:23:48 +0800832 peer = self._create_server(self.new_net)
Steve Heyman33735f22016-05-24 09:28:08 -0500833 peer_address = peer['addresses'][self.new_net['name']][0]['addr']
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900834 self.check_remote_connectivity(ssh_client, dest=peer_address,
835 nic=spoof_nic, should_succeed=True)
Yair Friedbc46f592015-11-18 16:29:34 +0200836 ssh_client.set_mac_address(spoof_nic, spoof_mac)
837 new_mac = ssh_client.get_mac_address(nic=spoof_nic)
838 self.assertEqual(spoof_mac, new_mac)
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900839 self.check_remote_connectivity(ssh_client, dest=peer_address,
840 nic=spoof_nic, should_succeed=False)
Yair Friedbc46f592015-11-18 16:29:34 +0200841 self.ports_client.update_port(spoof_port["id"],
842 port_security_enabled=False,
843 security_groups=[])
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900844 self.check_remote_connectivity(ssh_client, dest=peer_address,
845 nic=spoof_nic, should_succeed=True)