blob: 72b61c83c436297a02ad9c95f89fa93709b1322a [file] [log] [blame]
Yair Fried4d7efa62013-11-17 17:12:29 +02001# Copyright 2013 Red Hat, Inc.
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
Yair Friedca5cfb52016-01-04 15:41:55 +020015from oslo_log import log
Markus Zoeller156b5da2016-07-11 18:10:31 +020016import testtools
Yair Fried4d7efa62013-11-17 17:12:29 +020017
Attila Fazekasd7e08a62016-10-07 13:05:05 +020018from tempest.common.utils import net_info
Matthew Treinish6c072292014-01-29 19:15:52 +000019from tempest import config
Ken'ichi Ohmichibe4fb502017-03-10 10:04:48 -080020from tempest.lib.common.utils import data_utils
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -080021from tempest.lib import decorators
Yair Fried4d7efa62013-11-17 17:12:29 +020022from tempest.scenario import manager
Masayuki Igawa4ded9f02014-02-17 15:05:59 +090023from tempest import test
Yair Fried4d7efa62013-11-17 17:12:29 +020024
Matthew Treinish6c072292014-01-29 19:15:52 +000025CONF = config.CONF
Yair Friedca5cfb52016-01-04 15:41:55 +020026LOG = log.getLogger(__name__)
Matthew Treinish6c072292014-01-29 19:15:52 +000027
Yair Fried4d7efa62013-11-17 17:12:29 +020028
Andrea Frittoli4971fc82014-09-25 10:22:20 +010029class TestSecurityGroupsBasicOps(manager.NetworkScenarioTest):
Yair Fried4d7efa62013-11-17 17:12:29 +020030
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +000031 """The test suite for security groups
32
Yair Fried4d7efa62013-11-17 17:12:29 +020033 This test suite assumes that Nova has been configured to
34 boot VM's with Neutron-managed networking, and attempts to
35 verify cross tenant connectivity as follows
36
37 ssh:
38 in order to overcome "ip namespace", each tenant has an "access point"
39 VM with floating-ip open to incoming ssh connection allowing network
40 commands (ping/ssh) to be executed from within the
41 tenant-network-namespace
42 Tempest host performs key-based authentication to the ssh server via
43 floating IP address
44
45 connectivity test is done by pinging destination server via source server
46 ssh connection.
47 success - ping returns
48 failure - ping_timeout reached
49
Eran Kurisb5f69782016-04-10 11:48:28 +030050 multi-node:
51 Multi-Node mode is enabled when CONF.compute.min_compute_nodes > 1.
52 Tests connectivity between servers on different compute nodes.
53 When enabled, test will boot each new server to different
54 compute nodes.
55
Yair Fried4d7efa62013-11-17 17:12:29 +020056 setup:
Yair Friedbf2e2c42014-01-28 12:06:38 +020057 for primary tenant:
Yair Fried4d7efa62013-11-17 17:12:29 +020058 1. create a network&subnet
59 2. create a router (if public router isn't configured)
60 3. connect tenant network to public network via router
61 4. create an access point:
62 a. a security group open to incoming ssh connection
63 b. a VM with a floating ip
64 5. create a general empty security group (same as "default", but
65 without rules allowing in-tenant traffic)
Yair Fried4d7efa62013-11-17 17:12:29 +020066
67 tests:
68 1. _verify_network_details
69 2. _verify_mac_addr: for each access point verify that
70 (subnet, fix_ip, mac address) are as defined in the port list
71 3. _test_in_tenant_block: test that in-tenant traffic is disabled
72 without rules allowing it
73 4. _test_in_tenant_allow: test that in-tenant traffic is enabled
74 once an appropriate rule has been created
75 5. _test_cross_tenant_block: test that cross-tenant traffic is disabled
76 without a rule allowing it on destination tenant
77 6. _test_cross_tenant_allow:
78 * test that cross-tenant traffic is enabled once an appropriate
79 rule has been created on destination tenant.
80 * test that reverse traffic is still blocked
Fei Long Wang50131ee2015-02-02 16:58:24 +130081 * test than reverse traffic is enabled once an appropriate rule has
Yair Fried4d7efa62013-11-17 17:12:29 +020082 been created on source tenant
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -080083 7._test_port_update_new_security_group:
84 * test that traffic is blocked with default security group
85 * test that traffic is enabled after updating port with new security
86 group having appropriate rule
prdsilva8b733ad2014-12-09 02:54:49 -080087 8. _test_multiple_security_groups: test multiple security groups can be
88 associated with the vm
Yair Fried4d7efa62013-11-17 17:12:29 +020089
90 assumptions:
Yair Friedbf2e2c42014-01-28 12:06:38 +020091 1. alt_tenant/user existed and is different from primary_tenant/user
Yair Fried4d7efa62013-11-17 17:12:29 +020092 2. Public network is defined and reachable from the Tempest host
93 3. Public router can either be:
94 * defined, in which case all tenants networks can connect directly
95 to it, and cross tenant check will be done on the private IP of the
96 destination tenant
97 or
Fei Long Wang50131ee2015-02-02 16:58:24 +130098 * not defined (empty string), in which case each tenant will have
Yair Fried4d7efa62013-11-17 17:12:29 +020099 its own router connected to the public network
100 """
101
Andrea Frittolib21de6c2015-02-06 20:12:38 +0000102 credentials = ['primary', 'alt', 'admin']
103
Joe Gordon28788b42015-02-25 12:42:37 -0800104 class TenantProperties(object):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000105 """helper class to save tenant details
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000106
Yair Fried4d7efa62013-11-17 17:12:29 +0200107 id
108 credentials
109 network
110 subnet
111 security groups
112 servers
113 access point
Yair Friedbf2e2c42014-01-28 12:06:38 +0200114 """
Yair Fried4d7efa62013-11-17 17:12:29 +0200115
Andrea Frittoli73224672016-12-09 21:08:19 +0000116 def __init__(self, clients):
Andrea Frittoli422fbdf2014-03-20 10:05:18 +0000117 # Credentials from manager are filled with both names and IDs
Andrea Frittoli73224672016-12-09 21:08:19 +0000118 self.manager = clients
Andrea Frittoli422fbdf2014-03-20 10:05:18 +0000119 self.creds = self.manager.credentials
Yair Fried4d7efa62013-11-17 17:12:29 +0200120 self.network = None
121 self.subnet = None
122 self.router = None
123 self.security_groups = {}
124 self.servers = list()
125
Yair Friedbf2e2c42014-01-28 12:06:38 +0200126 def set_network(self, network, subnet, router):
Yair Fried4d7efa62013-11-17 17:12:29 +0200127 self.network = network
128 self.subnet = subnet
129 self.router = router
130
Yair Fried4d7efa62013-11-17 17:12:29 +0200131 @classmethod
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000132 def skip_checks(cls):
133 super(TestSecurityGroupsBasicOps, cls).skip_checks()
Itzik Brown06952672015-03-29 12:38:58 +0300134 if CONF.network.port_vnic_type in ['direct', 'macvtap']:
135 msg = ('Not currently supported when using vnic_type'
136 ' direct or macvtap')
137 raise cls.skipException(msg)
Sean Dagueed6e5862016-04-04 10:49:13 -0400138 if not (CONF.network.project_networks_reachable or
Matthew Treinish6c072292014-01-29 19:15:52 +0000139 CONF.network.public_network_id):
Sean Dagueed6e5862016-04-04 10:49:13 -0400140 msg = ('Either project_networks_reachable must be "true", or '
Yair Fried4d7efa62013-11-17 17:12:29 +0200141 'public_network_id must be defined.')
Yair Fried4d7efa62013-11-17 17:12:29 +0200142 raise cls.skipException(msg)
Bence Romsics41f3f852016-01-11 13:48:23 +0100143 if not test.is_extension_enabled('security-group', 'network'):
144 msg = "security-group extension not enabled."
145 raise cls.skipException(msg)
ghanshyam929b3482016-12-05 11:47:53 +0900146 if CONF.network.shared_physical_network:
Thiago Paiva66cded22016-08-15 14:55:58 -0300147 msg = ('Deployment uses a shared physical network, security '
148 'groups not supported')
149 raise cls.skipException(msg)
Yair Fried4d7efa62013-11-17 17:12:29 +0200150
151 @classmethod
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000152 def setup_credentials(cls):
Yair Fried764610a2014-04-07 12:17:05 +0300153 # Create no network resources for these tests.
154 cls.set_network_resources()
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000155 super(TestSecurityGroupsBasicOps, cls).setup_credentials()
Yair Fried79b0a912014-10-20 11:15:37 +0300156
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000157 @classmethod
158 def resource_setup(cls):
159 super(TestSecurityGroupsBasicOps, cls).resource_setup()
Yair Friedca5cfb52016-01-04 15:41:55 +0200160
161 cls.multi_node = CONF.compute.min_compute_nodes > 1 and \
Yair Fried95914122016-03-03 09:14:40 +0200162 test.is_scheduler_filter_enabled("DifferentHostFilter")
Yair Friedca5cfb52016-01-04 15:41:55 +0200163 if cls.multi_node:
164 LOG.info("Working in Multi Node mode")
165 else:
166 LOG.info("Working in Single Node mode")
167
Yair Fried4d7efa62013-11-17 17:12:29 +0200168 cls.floating_ips = {}
169 cls.tenants = {}
Andrea Frittoli73224672016-12-09 21:08:19 +0000170 cls.primary_tenant = cls.TenantProperties(cls.os)
171 cls.alt_tenant = cls.TenantProperties(cls.os_alt)
Yair Friedbf2e2c42014-01-28 12:06:38 +0200172 for tenant in [cls.primary_tenant, cls.alt_tenant]:
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000173 cls.tenants[tenant.creds.tenant_id] = tenant
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000174
Yair Friedbf2e2c42014-01-28 12:06:38 +0200175 cls.floating_ip_access = not CONF.network.public_router_id
Yair Fried4d7efa62013-11-17 17:12:29 +0200176
Yair Friedbf2e2c42014-01-28 12:06:38 +0200177 def setUp(self):
Yair Friedca5cfb52016-01-04 15:41:55 +0200178 """Set up a single tenant with an accessible server.
179
180 If multi-host is enabled, save created server uuids.
181 """
182 self.servers = []
183
Yair Friedbf2e2c42014-01-28 12:06:38 +0200184 super(TestSecurityGroupsBasicOps, self).setUp()
185 self._deploy_tenant(self.primary_tenant)
186 self._verify_network_details(self.primary_tenant)
187 self._verify_mac_addr(self.primary_tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200188
Yair Frieddb6c9e92014-08-06 08:53:13 +0300189 def _create_tenant_keypairs(self, tenant):
190 keypair = self.create_keypair(tenant.manager.keypairs_client)
191 tenant.keypair = keypair
Yair Fried4d7efa62013-11-17 17:12:29 +0200192
193 def _create_tenant_security_groups(self, tenant):
Yair Fried4d7efa62013-11-17 17:12:29 +0200194 access_sg = self._create_empty_security_group(
195 namestart='secgroup_access-',
Yair Frieddb6c9e92014-08-06 08:53:13 +0300196 tenant_id=tenant.creds.tenant_id,
John Warrenf9606e92015-12-10 12:12:42 -0500197 client=tenant.manager.security_groups_client
Yair Fried4d7efa62013-11-17 17:12:29 +0200198 )
Yair Friedbf2e2c42014-01-28 12:06:38 +0200199
Sean Dagueed6e5862016-04-04 10:49:13 -0400200 # don't use default secgroup since it allows in-project traffic
Yair Fried4d7efa62013-11-17 17:12:29 +0200201 def_sg = self._create_empty_security_group(
202 namestart='secgroup_general-',
Yair Frieddb6c9e92014-08-06 08:53:13 +0300203 tenant_id=tenant.creds.tenant_id,
John Warrenf9606e92015-12-10 12:12:42 -0500204 client=tenant.manager.security_groups_client
Yair Fried4d7efa62013-11-17 17:12:29 +0200205 )
206 tenant.security_groups.update(access=access_sg, default=def_sg)
207 ssh_rule = dict(
208 protocol='tcp',
209 port_range_min=22,
210 port_range_max=22,
211 direction='ingress',
212 )
John Warren456d9ae2016-01-12 15:36:33 -0500213 sec_group_rules_client = tenant.manager.security_group_rules_client
214 self._create_security_group_rule(
215 secgroup=access_sg,
216 sec_group_rules_client=sec_group_rules_client,
217 **ssh_rule)
Yair Fried4d7efa62013-11-17 17:12:29 +0200218
219 def _verify_network_details(self, tenant):
220 # Checks that we see the newly created network/subnet/router via
221 # checking the result of list_[networks,routers,subnets]
222 # Check that (router, subnet) couple exist in port_list
Jordan Pittier64e6b442017-02-20 19:29:02 +0100223 seen_nets = self.admin_manager.networks_client.list_networks()
224 seen_names = [n['name'] for n in seen_nets['networks']]
225 seen_ids = [n['id'] for n in seen_nets['networks']]
Yair Fried4d7efa62013-11-17 17:12:29 +0200226
Steve Heyman33735f22016-05-24 09:28:08 -0500227 self.assertIn(tenant.network['name'], seen_names)
228 self.assertIn(tenant.network['id'], seen_ids)
Yair Fried4d7efa62013-11-17 17:12:29 +0200229
Jordan Pittier64e6b442017-02-20 19:29:02 +0100230 seen_subnets = [
231 (n['id'], n['cidr'], n['network_id']) for n in
232 self.admin_manager.subnets_client.list_subnets()['subnets']
233 ]
Steve Heyman33735f22016-05-24 09:28:08 -0500234 mysubnet = (tenant.subnet['id'], tenant.subnet['cidr'],
235 tenant.network['id'])
Yair Fried4d7efa62013-11-17 17:12:29 +0200236 self.assertIn(mysubnet, seen_subnets)
237
Jordan Pittier64e6b442017-02-20 19:29:02 +0100238 seen_routers = self.admin_manager.routers_client.list_routers()
239 seen_router_ids = [n['id'] for n in seen_routers['routers']]
240 seen_router_names = [n['name'] for n in seen_routers['routers']]
Yair Fried4d7efa62013-11-17 17:12:29 +0200241
Steve Heyman33735f22016-05-24 09:28:08 -0500242 self.assertIn(tenant.router['name'], seen_router_names)
243 self.assertIn(tenant.router['id'], seen_router_ids)
Yair Fried4d7efa62013-11-17 17:12:29 +0200244
Steve Heyman33735f22016-05-24 09:28:08 -0500245 myport = (tenant.router['id'], tenant.subnet['id'])
Kevin Benton8801e362017-02-12 19:17:55 -0800246 router_ports = [
247 (i['device_id'], f['subnet_id'])
Jordan Pittier64e6b442017-02-20 19:29:02 +0100248 for i in self.admin_manager.ports_client.list_ports(
249 device_id=tenant.router['id'])['ports']
Kevin Benton8801e362017-02-12 19:17:55 -0800250 if net_info.is_router_interface_port(i)
Jordan Pittier64e6b442017-02-20 19:29:02 +0100251 for f in i['fixed_ips']
252 ]
Yair Fried4d7efa62013-11-17 17:12:29 +0200253
254 self.assertIn(myport, router_ports)
255
Markus Zoeller156b5da2016-07-11 18:10:31 +0200256 def _create_server(self, name, tenant, security_groups, **kwargs):
Yair Friedca5cfb52016-01-04 15:41:55 +0200257 """Creates a server and assigns it to security group.
258
259 If multi-host is enabled, Ensures servers are created on different
260 compute nodes, by storing created servers' ids and uses different_host
261 as scheduler_hints on creation.
262 Validates servers are created as requested, using admin client.
263 """
Ken'ichi Ohmichi1b3461e2014-12-02 03:41:07 +0000264 security_groups_names = [{'name': s['name']} for s in security_groups]
Yair Friedca5cfb52016-01-04 15:41:55 +0200265 if self.multi_node:
266 kwargs["scheduler_hints"] = {'different_host': self.servers}
Ken'ichi Ohmichif2d436e2015-09-03 01:13:16 +0000267 server = self.create_server(
268 name=name,
Steve Heyman33735f22016-05-24 09:28:08 -0500269 networks=[{'uuid': tenant.network["id"]}],
lanoux5fc14522015-09-21 08:17:35 +0000270 key_name=tenant.keypair['name'],
271 security_groups=security_groups_names,
Yair Friedca5cfb52016-01-04 15:41:55 +0200272 clients=tenant.manager,
273 **kwargs)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200274 if 'security_groups' in server:
275 self.assertEqual(
276 sorted([s['name'] for s in security_groups]),
277 sorted([s['name'] for s in server['security_groups']]))
Yair Friedca5cfb52016-01-04 15:41:55 +0200278
279 # Verify servers are on different compute nodes
280 if self.multi_node:
281 adm_get_server = self.admin_manager.servers_client.show_server
282 new_host = adm_get_server(server["id"])["server"][
283 "OS-EXT-SRV-ATTR:host"]
284 host_list = [adm_get_server(s)["server"]["OS-EXT-SRV-ATTR:host"]
285 for s in self.servers]
286 self.assertNotIn(new_host, host_list,
287 message="Failed to boot servers on different "
288 "Compute nodes.")
289
290 self.servers.append(server["id"])
291
Claudiu Belufaa98912014-09-01 16:50:28 +0300292 return server
Yair Fried4d7efa62013-11-17 17:12:29 +0200293
294 def _create_tenant_servers(self, tenant, num=1):
295 for i in range(num):
Ken'ichi Ohmichi6ded8df2015-03-23 02:00:19 +0000296 name = 'server-{tenant}-gen-{num}'.format(
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000297 tenant=tenant.creds.tenant_name,
Yair Fried4d7efa62013-11-17 17:12:29 +0200298 num=i
299 )
300 name = data_utils.rand_name(name)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200301 server = self._create_server(name, tenant,
302 [tenant.security_groups['default']])
Yair Fried4d7efa62013-11-17 17:12:29 +0200303 tenant.servers.append(server)
304
305 def _set_access_point(self, tenant):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000306 # creates a server in a secgroup with rule allowing external ssh
Sean Dagueed6e5862016-04-04 10:49:13 -0400307 # in order to access project internal network
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000308 # workaround ip namespace
Yair Frieddb6c9e92014-08-06 08:53:13 +0300309 secgroups = tenant.security_groups.values()
Ken'ichi Ohmichi6ded8df2015-03-23 02:00:19 +0000310 name = 'server-{tenant}-access_point'.format(
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000311 tenant=tenant.creds.tenant_name)
Yair Fried4d7efa62013-11-17 17:12:29 +0200312 name = data_utils.rand_name(name)
313 server = self._create_server(name, tenant,
314 security_groups=secgroups)
Yair Fried4d7efa62013-11-17 17:12:29 +0200315 tenant.access_point = server
Yair Frieddb6c9e92014-08-06 08:53:13 +0300316 self._assign_floating_ips(tenant, server)
Yair Fried4d7efa62013-11-17 17:12:29 +0200317
Yair Frieddb6c9e92014-08-06 08:53:13 +0300318 def _assign_floating_ips(self, tenant, server):
Matthew Treinish6c072292014-01-29 19:15:52 +0000319 public_network_id = CONF.network.public_network_id
Yair Friedae0e73d2014-11-24 11:56:26 +0200320 floating_ip = self.create_floating_ip(
Yair Frieddb6c9e92014-08-06 08:53:13 +0300321 server, public_network_id,
John Warrenfbf2a892015-11-17 12:36:14 -0500322 client=tenant.manager.floating_ips_client)
Yair Frieddb6c9e92014-08-06 08:53:13 +0300323 self.floating_ips.setdefault(server['id'], floating_ip)
Yair Fried4d7efa62013-11-17 17:12:29 +0200324
Markus Zoeller156b5da2016-07-11 18:10:31 +0200325 def _create_tenant_network(self, tenant, port_security_enabled=True):
Yair Frieddb6c9e92014-08-06 08:53:13 +0300326 network, subnet, router = self.create_networks(
John Warren3961acd2015-10-02 14:38:53 -0400327 networks_client=tenant.manager.networks_client,
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000328 routers_client=tenant.manager.routers_client,
Markus Zoeller156b5da2016-07-11 18:10:31 +0200329 subnets_client=tenant.manager.subnets_client,
330 port_security_enabled=port_security_enabled)
Yair Friedbf2e2c42014-01-28 12:06:38 +0200331 tenant.set_network(network, subnet, router)
Yair Fried4d7efa62013-11-17 17:12:29 +0200332
Yair Fried4d7efa62013-11-17 17:12:29 +0200333 def _deploy_tenant(self, tenant_or_id):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000334 """creates:
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000335
Yair Fried4d7efa62013-11-17 17:12:29 +0200336 network
337 subnet
338 router (if public not defined)
339 access security group
340 access-point server
Yair Fried4d7efa62013-11-17 17:12:29 +0200341 """
342 if not isinstance(tenant_or_id, self.TenantProperties):
343 tenant = self.tenants[tenant_or_id]
Yair Fried4d7efa62013-11-17 17:12:29 +0200344 else:
345 tenant = tenant_or_id
Yair Frieddb6c9e92014-08-06 08:53:13 +0300346 self._create_tenant_keypairs(tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200347 self._create_tenant_network(tenant)
348 self._create_tenant_security_groups(tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200349 self._set_access_point(tenant)
350
351 def _get_server_ip(self, server, floating=False):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000352 """returns the ip (floating/internal) of a server"""
Yair Fried4d7efa62013-11-17 17:12:29 +0200353 if floating:
Steve Heyman33735f22016-05-24 09:28:08 -0500354 server_ip = self.floating_ips[server['id']]['floating_ip_address']
Yair Fried4d7efa62013-11-17 17:12:29 +0200355 else:
armando-migliacciod03f2642014-02-21 19:55:50 -0800356 server_ip = None
Steve Heyman33735f22016-05-24 09:28:08 -0500357 network_name = self.tenants[server['tenant_id']].network['name']
Yair Frieddb6c9e92014-08-06 08:53:13 +0300358 if network_name in server['addresses']:
359 server_ip = server['addresses'][network_name][0]['addr']
armando-migliacciod03f2642014-02-21 19:55:50 -0800360 return server_ip
Yair Fried4d7efa62013-11-17 17:12:29 +0200361
362 def _connect_to_access_point(self, tenant):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000363 """create ssh connection to tenant access point"""
Yair Fried4d7efa62013-11-17 17:12:29 +0200364 access_point_ssh = \
Steve Heyman33735f22016-05-24 09:28:08 -0500365 self.floating_ips[tenant.access_point['id']]['floating_ip_address']
Yair Frieddb6c9e92014-08-06 08:53:13 +0300366 private_key = tenant.keypair['private_key']
Jordan Pittierbbb17122016-01-26 17:10:55 +0100367 access_point_ssh = self.get_remote_client(
368 access_point_ssh, private_key=private_key)
Yair Fried4d7efa62013-11-17 17:12:29 +0200369 return access_point_ssh
370
Yair Fried4d7efa62013-11-17 17:12:29 +0200371 def _test_in_tenant_block(self, tenant):
372 access_point_ssh = self._connect_to_access_point(tenant)
373 for server in tenant.servers:
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900374 self.check_remote_connectivity(source=access_point_ssh,
375 dest=self._get_server_ip(server),
376 should_succeed=False)
Yair Fried4d7efa62013-11-17 17:12:29 +0200377
378 def _test_in_tenant_allow(self, tenant):
379 ruleset = dict(
380 protocol='icmp',
Steve Heyman33735f22016-05-24 09:28:08 -0500381 remote_group_id=tenant.security_groups['default']['id'],
Yair Fried4d7efa62013-11-17 17:12:29 +0200382 direction='ingress'
383 )
Matthew Treinishb7144eb2013-12-13 22:57:35 +0000384 self._create_security_group_rule(
Yair Fried4d7efa62013-11-17 17:12:29 +0200385 secgroup=tenant.security_groups['default'],
Yair Friedca5cfb52016-01-04 15:41:55 +0200386 security_groups_client=tenant.manager.security_groups_client,
Yair Fried4d7efa62013-11-17 17:12:29 +0200387 **ruleset
388 )
389 access_point_ssh = self._connect_to_access_point(tenant)
390 for server in tenant.servers:
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900391 self.check_remote_connectivity(source=access_point_ssh,
392 dest=self._get_server_ip(server))
Yair Fried4d7efa62013-11-17 17:12:29 +0200393
394 def _test_cross_tenant_block(self, source_tenant, dest_tenant):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000395 # if public router isn't defined, then dest_tenant access is via
396 # floating-ip
Yair Fried4d7efa62013-11-17 17:12:29 +0200397 access_point_ssh = self._connect_to_access_point(source_tenant)
398 ip = self._get_server_ip(dest_tenant.access_point,
399 floating=self.floating_ip_access)
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900400 self.check_remote_connectivity(source=access_point_ssh, dest=ip,
401 should_succeed=False)
Yair Fried4d7efa62013-11-17 17:12:29 +0200402
403 def _test_cross_tenant_allow(self, source_tenant, dest_tenant):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000404 """check for each direction:
405
Yair Fried4d7efa62013-11-17 17:12:29 +0200406 creating rule for tenant incoming traffic enables only 1way traffic
Yair Friedbf2e2c42014-01-28 12:06:38 +0200407 """
Yair Fried4d7efa62013-11-17 17:12:29 +0200408 ruleset = dict(
409 protocol='icmp',
410 direction='ingress'
411 )
John Warren456d9ae2016-01-12 15:36:33 -0500412 sec_group_rules_client = (
413 dest_tenant.manager.security_group_rules_client)
Matthew Treinishb7144eb2013-12-13 22:57:35 +0000414 self._create_security_group_rule(
Yair Fried4d7efa62013-11-17 17:12:29 +0200415 secgroup=dest_tenant.security_groups['default'],
John Warren456d9ae2016-01-12 15:36:33 -0500416 sec_group_rules_client=sec_group_rules_client,
Yair Fried4d7efa62013-11-17 17:12:29 +0200417 **ruleset
418 )
Yair Friedbf2e2c42014-01-28 12:06:38 +0200419 access_point_ssh = self._connect_to_access_point(source_tenant)
420 ip = self._get_server_ip(dest_tenant.access_point,
421 floating=self.floating_ip_access)
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900422 self.check_remote_connectivity(access_point_ssh, ip)
Yair Fried4d7efa62013-11-17 17:12:29 +0200423
Yair Friedbf2e2c42014-01-28 12:06:38 +0200424 # test that reverse traffic is still blocked
425 self._test_cross_tenant_block(dest_tenant, source_tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200426
Yair Friedbf2e2c42014-01-28 12:06:38 +0200427 # allow reverse traffic and check
John Warren456d9ae2016-01-12 15:36:33 -0500428 sec_group_rules_client = (
429 source_tenant.manager.security_group_rules_client)
Matthew Treinishb7144eb2013-12-13 22:57:35 +0000430 self._create_security_group_rule(
Yair Friedbf2e2c42014-01-28 12:06:38 +0200431 secgroup=source_tenant.security_groups['default'],
John Warren456d9ae2016-01-12 15:36:33 -0500432 sec_group_rules_client=sec_group_rules_client,
Yair Friedbf2e2c42014-01-28 12:06:38 +0200433 **ruleset
434 )
Yair Fried4d7efa62013-11-17 17:12:29 +0200435
Yair Friedbf2e2c42014-01-28 12:06:38 +0200436 access_point_ssh_2 = self._connect_to_access_point(dest_tenant)
437 ip = self._get_server_ip(source_tenant.access_point,
438 floating=self.floating_ip_access)
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900439 self.check_remote_connectivity(access_point_ssh_2, ip)
Yair Fried4d7efa62013-11-17 17:12:29 +0200440
441 def _verify_mac_addr(self, tenant):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000442 """Verify that VM has the same ip, mac as listed in port"""
443
Yair Fried4d7efa62013-11-17 17:12:29 +0200444 access_point_ssh = self._connect_to_access_point(tenant)
445 mac_addr = access_point_ssh.get_mac_address()
446 mac_addr = mac_addr.strip().lower()
Henry Gessau78ab4b02014-03-31 15:10:13 -0400447 # Get the fixed_ips and mac_address fields of all ports. Select
448 # only those two columns to reduce the size of the response.
Jordan Pittier64e6b442017-02-20 19:29:02 +0100449 port_list = self.admin_manager.ports_client.list_ports(
450 fields=['fixed_ips', 'mac_address'])['ports']
Yair Fried4d7efa62013-11-17 17:12:29 +0200451 port_detail_list = [
452 (port['fixed_ips'][0]['subnet_id'],
453 port['fixed_ips'][0]['ip_address'],
Henry Gessau78ab4b02014-03-31 15:10:13 -0400454 port['mac_address'].lower())
455 for port in port_list if port['fixed_ips']
Yair Fried4d7efa62013-11-17 17:12:29 +0200456 ]
457 server_ip = self._get_server_ip(tenant.access_point)
Steve Heyman33735f22016-05-24 09:28:08 -0500458 subnet_id = tenant.subnet['id']
Yair Fried4d7efa62013-11-17 17:12:29 +0200459 self.assertIn((subnet_id, server_ip, mac_addr), port_detail_list)
460
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800461 @decorators.idempotent_id('e79f879e-debb-440c-a7e4-efeda05b6848')
Masayuki Igawa4ded9f02014-02-17 15:05:59 +0900462 @test.services('compute', 'network')
Yair Fried4d7efa62013-11-17 17:12:29 +0200463 def test_cross_tenant_traffic(self):
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100464 if not self.credentials_provider.is_multi_tenant():
Yair Fried79b0a912014-10-20 11:15:37 +0300465 raise self.skipException("No secondary tenant defined")
Nachi Ueno26b4c972014-01-17 06:15:13 -0800466 try:
Sean Dagueed6e5862016-04-04 10:49:13 -0400467 # deploy new project
Yair Friedbf2e2c42014-01-28 12:06:38 +0200468 self._deploy_tenant(self.alt_tenant)
469 self._verify_network_details(self.alt_tenant)
470 self._verify_mac_addr(self.alt_tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200471
Nachi Ueno26b4c972014-01-17 06:15:13 -0800472 # cross tenant check
Yair Friedbf2e2c42014-01-28 12:06:38 +0200473 source_tenant = self.primary_tenant
Nachi Ueno26b4c972014-01-17 06:15:13 -0800474 dest_tenant = self.alt_tenant
475 self._test_cross_tenant_block(source_tenant, dest_tenant)
476 self._test_cross_tenant_allow(source_tenant, dest_tenant)
477 except Exception:
Yair Friedbf2e2c42014-01-28 12:06:38 +0200478 for tenant in self.tenants.values():
479 self._log_console_output(servers=tenant.servers)
480 raise
481
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800482 @decorators.idempotent_id('63163892-bbf6-4249-aa12-d5ea1f8f421b')
Masayuki Igawa4ded9f02014-02-17 15:05:59 +0900483 @test.services('compute', 'network')
Yair Friedbf2e2c42014-01-28 12:06:38 +0200484 def test_in_tenant_traffic(self):
485 try:
486 self._create_tenant_servers(self.primary_tenant, num=1)
487
488 # in-tenant check
489 self._test_in_tenant_block(self.primary_tenant)
490 self._test_in_tenant_allow(self.primary_tenant)
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800491 except Exception:
492 for tenant in self.tenants.values():
493 self._log_console_output(servers=tenant.servers)
494 raise
Yair Friedbf2e2c42014-01-28 12:06:38 +0200495
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800496 @decorators.idempotent_id('f4d556d7-1526-42ad-bafb-6bebf48568f6')
Sean Dague49505df2017-03-01 11:35:58 -0500497 @test.attr(type='slow')
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800498 @test.services('compute', 'network')
499 def test_port_update_new_security_group(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000500 """Verifies the traffic after updating the vm port
501
502 With new security group having appropriate rule.
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800503 """
504 new_tenant = self.primary_tenant
505
506 # Create empty security group and add icmp rule in it
507 new_sg = self._create_empty_security_group(
508 namestart='secgroup_new-',
509 tenant_id=new_tenant.creds.tenant_id,
John Warrenf9606e92015-12-10 12:12:42 -0500510 client=new_tenant.manager.security_groups_client)
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800511 icmp_rule = dict(
512 protocol='icmp',
513 direction='ingress',
514 )
John Warren456d9ae2016-01-12 15:36:33 -0500515 sec_group_rules_client = new_tenant.manager.security_group_rules_client
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800516 self._create_security_group_rule(
517 secgroup=new_sg,
John Warren456d9ae2016-01-12 15:36:33 -0500518 sec_group_rules_client=sec_group_rules_client,
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800519 **icmp_rule)
520 new_tenant.security_groups.update(new_sg=new_sg)
521
522 # Create server with default security group
Ken'ichi Ohmichi6ded8df2015-03-23 02:00:19 +0000523 name = 'server-{tenant}-gen-1'.format(
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800524 tenant=new_tenant.creds.tenant_name
525 )
526 name = data_utils.rand_name(name)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200527 server = self._create_server(name, new_tenant,
528 [new_tenant.security_groups['default']])
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800529
530 # Check connectivity failure with default security group
531 try:
532 access_point_ssh = self._connect_to_access_point(new_tenant)
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900533 self.check_remote_connectivity(source=access_point_ssh,
534 dest=self._get_server_ip(server),
535 should_succeed=False)
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800536 server_id = server['id']
Jordan Pittier64e6b442017-02-20 19:29:02 +0100537 port_id = self.admin_manager.ports_client.list_ports(
538 device_id=server_id)['ports'][0]['id']
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800539
540 # update port with new security group and check connectivity
John Warren49c0fe52015-10-22 12:35:54 -0400541 self.ports_client.update_port(port_id, security_groups=[
Steve Heyman33735f22016-05-24 09:28:08 -0500542 new_tenant.security_groups['new_sg']['id']])
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900543 self.check_remote_connectivity(
544 source=access_point_ssh,
545 dest=self._get_server_ip(server))
Yair Friedbf2e2c42014-01-28 12:06:38 +0200546 except Exception:
547 for tenant in self.tenants.values():
548 self._log_console_output(servers=tenant.servers)
Nachi Ueno26b4c972014-01-17 06:15:13 -0800549 raise
prdsilva8b733ad2014-12-09 02:54:49 -0800550
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800551 @decorators.idempotent_id('d2f77418-fcc4-439d-b935-72eca704e293')
Sean Dague49505df2017-03-01 11:35:58 -0500552 @test.attr(type='slow')
prdsilva8b733ad2014-12-09 02:54:49 -0800553 @test.services('compute', 'network')
554 def test_multiple_security_groups(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000555 """Verify multiple security groups and checks that rules
556
prdsilva8b733ad2014-12-09 02:54:49 -0800557 provided in the both the groups is applied onto VM
558 """
559 tenant = self.primary_tenant
560 ip = self._get_server_ip(tenant.access_point,
561 floating=self.floating_ip_access)
lanoux283273b2015-12-04 03:01:54 -0800562 ssh_login = CONF.validation.image_ssh_user
prdsilva8b733ad2014-12-09 02:54:49 -0800563 private_key = tenant.keypair['private_key']
564 self.check_vm_connectivity(ip,
565 should_connect=False)
566 ruleset = dict(
567 protocol='icmp',
568 direction='ingress'
569 )
570 self._create_security_group_rule(
571 secgroup=tenant.security_groups['default'],
572 **ruleset
573 )
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000574 # NOTE: Vm now has 2 security groups one with ssh rule(
575 # already added in setUp() method),and other with icmp rule
576 # (added in the above step).The check_vm_connectivity tests
577 # -that vm ping test is successful
578 # -ssh to vm is successful
prdsilva8b733ad2014-12-09 02:54:49 -0800579 self.check_vm_connectivity(ip,
580 username=ssh_login,
581 private_key=private_key,
582 should_connect=True)
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900583
Sean Dague49505df2017-03-01 11:35:58 -0500584 @test.attr(type='slow')
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900585 @test.requires_ext(service='network', extension='port-security')
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800586 @decorators.idempotent_id('7c811dcc-263b-49a3-92d2-1b4d8405f50c')
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900587 @test.services('compute', 'network')
588 def test_port_security_disable_security_group(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000589 """Verify the default security group rules is disabled."""
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900590 new_tenant = self.primary_tenant
591
592 # Create server
593 name = 'server-{tenant}-gen-1'.format(
594 tenant=new_tenant.creds.tenant_name
595 )
596 name = data_utils.rand_name(name)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200597 server = self._create_server(name, new_tenant,
598 [new_tenant.security_groups['default']])
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900599
600 access_point_ssh = self._connect_to_access_point(new_tenant)
601 server_id = server['id']
Jordan Pittier64e6b442017-02-20 19:29:02 +0100602 port_id = self.admin_manager.ports_client.list_ports(
603 device_id=server_id)['ports'][0]['id']
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900604
605 # Flip the port's port security and check connectivity
606 try:
John Warren49c0fe52015-10-22 12:35:54 -0400607 self.ports_client.update_port(port_id,
608 port_security_enabled=True,
609 security_groups=[])
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900610 self.check_remote_connectivity(source=access_point_ssh,
611 dest=self._get_server_ip(server),
612 should_succeed=False)
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900613
John Warren49c0fe52015-10-22 12:35:54 -0400614 self.ports_client.update_port(port_id,
615 port_security_enabled=False,
616 security_groups=[])
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900617 self.check_remote_connectivity(
618 source=access_point_ssh,
619 dest=self._get_server_ip(server))
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900620 except Exception:
621 for tenant in self.tenants.values():
622 self._log_console_output(servers=tenant.servers)
623 raise
Markus Zoeller156b5da2016-07-11 18:10:31 +0200624
Sean Dague49505df2017-03-01 11:35:58 -0500625 @test.attr(type='slow')
Markus Zoeller156b5da2016-07-11 18:10:31 +0200626 @test.requires_ext(service='network', extension='port-security')
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800627 @decorators.idempotent_id('13ccf253-e5ad-424b-9c4a-97b88a026699')
Markus Zoeller156b5da2016-07-11 18:10:31 +0200628 @testtools.skipUnless(
629 CONF.compute_feature_enabled.allow_port_security_disabled,
630 'Port security must be enabled.')
Matt Riedemann039b2fe2016-09-15 16:12:24 -0400631 # TODO(mriedem): We shouldn't actually need to check this since neutron
632 # disables the port_security extension by default, but the problem is nova
633 # assumes port_security_enabled=True if it's not set on the network
634 # resource, which will mean nova may attempt to apply a security group on
635 # a port on that network which would fail. This is really a bug in nova.
636 @testtools.skipUnless(
637 CONF.network_feature_enabled.port_security,
638 'Port security must be enabled.')
Markus Zoeller156b5da2016-07-11 18:10:31 +0200639 @test.services('compute', 'network')
640 def test_boot_into_disabled_port_security_network_without_secgroup(self):
641 tenant = self.primary_tenant
642 self._create_tenant_network(tenant, port_security_enabled=False)
643 self.assertFalse(tenant.network['port_security_enabled'])
644 name = data_utils.rand_name('server-smoke')
645 sec_groups = []
646 server = self._create_server(name, tenant, sec_groups)
647 server_id = server['id']
Jordan Pittier64e6b442017-02-20 19:29:02 +0100648 ports = self.admin_manager.ports_client.list_ports(
649 device_id=server_id)['ports']
Markus Zoeller156b5da2016-07-11 18:10:31 +0200650 self.assertEqual(1, len(ports))
651 for port in ports:
652 self.assertEmpty(port['security_groups'],
653 "Neutron shouldn't even use it's default sec "
654 "group.")