blob: 401ad8d38e0da64fd56ef16b0eb009fca90fd338 [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()
Ihar Hrachyshkaa9dca2b2017-04-04 14:17:11 -0700125 self.access_point = None
Yair Fried4d7efa62013-11-17 17:12:29 +0200126
Yair Friedbf2e2c42014-01-28 12:06:38 +0200127 def set_network(self, network, subnet, router):
Yair Fried4d7efa62013-11-17 17:12:29 +0200128 self.network = network
129 self.subnet = subnet
130 self.router = router
131
Yair Fried4d7efa62013-11-17 17:12:29 +0200132 @classmethod
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000133 def skip_checks(cls):
134 super(TestSecurityGroupsBasicOps, cls).skip_checks()
Itzik Brown06952672015-03-29 12:38:58 +0300135 if CONF.network.port_vnic_type in ['direct', 'macvtap']:
136 msg = ('Not currently supported when using vnic_type'
137 ' direct or macvtap')
138 raise cls.skipException(msg)
Sean Dagueed6e5862016-04-04 10:49:13 -0400139 if not (CONF.network.project_networks_reachable or
Matthew Treinish6c072292014-01-29 19:15:52 +0000140 CONF.network.public_network_id):
Sean Dagueed6e5862016-04-04 10:49:13 -0400141 msg = ('Either project_networks_reachable must be "true", or '
Yair Fried4d7efa62013-11-17 17:12:29 +0200142 'public_network_id must be defined.')
Yair Fried4d7efa62013-11-17 17:12:29 +0200143 raise cls.skipException(msg)
Bence Romsics41f3f852016-01-11 13:48:23 +0100144 if not test.is_extension_enabled('security-group', 'network'):
145 msg = "security-group extension not enabled."
146 raise cls.skipException(msg)
ghanshyam929b3482016-12-05 11:47:53 +0900147 if CONF.network.shared_physical_network:
Thiago Paiva66cded22016-08-15 14:55:58 -0300148 msg = ('Deployment uses a shared physical network, security '
149 'groups not supported')
150 raise cls.skipException(msg)
Yair Fried4d7efa62013-11-17 17:12:29 +0200151
152 @classmethod
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000153 def setup_credentials(cls):
Yair Fried764610a2014-04-07 12:17:05 +0300154 # Create no network resources for these tests.
155 cls.set_network_resources()
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000156 super(TestSecurityGroupsBasicOps, cls).setup_credentials()
Yair Fried79b0a912014-10-20 11:15:37 +0300157
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000158 @classmethod
159 def resource_setup(cls):
160 super(TestSecurityGroupsBasicOps, cls).resource_setup()
Yair Friedca5cfb52016-01-04 15:41:55 +0200161
162 cls.multi_node = CONF.compute.min_compute_nodes > 1 and \
Yair Fried95914122016-03-03 09:14:40 +0200163 test.is_scheduler_filter_enabled("DifferentHostFilter")
Yair Friedca5cfb52016-01-04 15:41:55 +0200164 if cls.multi_node:
165 LOG.info("Working in Multi Node mode")
166 else:
167 LOG.info("Working in Single Node mode")
168
Yair Fried4d7efa62013-11-17 17:12:29 +0200169 cls.floating_ips = {}
170 cls.tenants = {}
Andrea Frittoli73224672016-12-09 21:08:19 +0000171 cls.primary_tenant = cls.TenantProperties(cls.os)
172 cls.alt_tenant = cls.TenantProperties(cls.os_alt)
Yair Friedbf2e2c42014-01-28 12:06:38 +0200173 for tenant in [cls.primary_tenant, cls.alt_tenant]:
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000174 cls.tenants[tenant.creds.tenant_id] = tenant
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000175
Yair Friedbf2e2c42014-01-28 12:06:38 +0200176 cls.floating_ip_access = not CONF.network.public_router_id
Yair Fried4d7efa62013-11-17 17:12:29 +0200177
Yair Friedbf2e2c42014-01-28 12:06:38 +0200178 def setUp(self):
Yair Friedca5cfb52016-01-04 15:41:55 +0200179 """Set up a single tenant with an accessible server.
180
181 If multi-host is enabled, save created server uuids.
182 """
183 self.servers = []
184
Yair Friedbf2e2c42014-01-28 12:06:38 +0200185 super(TestSecurityGroupsBasicOps, self).setUp()
186 self._deploy_tenant(self.primary_tenant)
187 self._verify_network_details(self.primary_tenant)
188 self._verify_mac_addr(self.primary_tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200189
Yair Frieddb6c9e92014-08-06 08:53:13 +0300190 def _create_tenant_keypairs(self, tenant):
191 keypair = self.create_keypair(tenant.manager.keypairs_client)
192 tenant.keypair = keypair
Yair Fried4d7efa62013-11-17 17:12:29 +0200193
194 def _create_tenant_security_groups(self, tenant):
Yair Fried4d7efa62013-11-17 17:12:29 +0200195 access_sg = self._create_empty_security_group(
196 namestart='secgroup_access-',
Yair Frieddb6c9e92014-08-06 08:53:13 +0300197 tenant_id=tenant.creds.tenant_id,
John Warrenf9606e92015-12-10 12:12:42 -0500198 client=tenant.manager.security_groups_client
Yair Fried4d7efa62013-11-17 17:12:29 +0200199 )
Yair Friedbf2e2c42014-01-28 12:06:38 +0200200
Sean Dagueed6e5862016-04-04 10:49:13 -0400201 # don't use default secgroup since it allows in-project traffic
Yair Fried4d7efa62013-11-17 17:12:29 +0200202 def_sg = self._create_empty_security_group(
203 namestart='secgroup_general-',
Yair Frieddb6c9e92014-08-06 08:53:13 +0300204 tenant_id=tenant.creds.tenant_id,
John Warrenf9606e92015-12-10 12:12:42 -0500205 client=tenant.manager.security_groups_client
Yair Fried4d7efa62013-11-17 17:12:29 +0200206 )
207 tenant.security_groups.update(access=access_sg, default=def_sg)
208 ssh_rule = dict(
209 protocol='tcp',
210 port_range_min=22,
211 port_range_max=22,
212 direction='ingress',
213 )
John Warren456d9ae2016-01-12 15:36:33 -0500214 sec_group_rules_client = tenant.manager.security_group_rules_client
215 self._create_security_group_rule(
216 secgroup=access_sg,
217 sec_group_rules_client=sec_group_rules_client,
218 **ssh_rule)
Yair Fried4d7efa62013-11-17 17:12:29 +0200219
220 def _verify_network_details(self, tenant):
221 # Checks that we see the newly created network/subnet/router via
222 # checking the result of list_[networks,routers,subnets]
223 # Check that (router, subnet) couple exist in port_list
Jordan Pittier64e6b442017-02-20 19:29:02 +0100224 seen_nets = self.admin_manager.networks_client.list_networks()
225 seen_names = [n['name'] for n in seen_nets['networks']]
226 seen_ids = [n['id'] for n in seen_nets['networks']]
Yair Fried4d7efa62013-11-17 17:12:29 +0200227
Steve Heyman33735f22016-05-24 09:28:08 -0500228 self.assertIn(tenant.network['name'], seen_names)
229 self.assertIn(tenant.network['id'], seen_ids)
Yair Fried4d7efa62013-11-17 17:12:29 +0200230
Jordan Pittier64e6b442017-02-20 19:29:02 +0100231 seen_subnets = [
232 (n['id'], n['cidr'], n['network_id']) for n in
233 self.admin_manager.subnets_client.list_subnets()['subnets']
234 ]
Steve Heyman33735f22016-05-24 09:28:08 -0500235 mysubnet = (tenant.subnet['id'], tenant.subnet['cidr'],
236 tenant.network['id'])
Yair Fried4d7efa62013-11-17 17:12:29 +0200237 self.assertIn(mysubnet, seen_subnets)
238
Jordan Pittier64e6b442017-02-20 19:29:02 +0100239 seen_routers = self.admin_manager.routers_client.list_routers()
240 seen_router_ids = [n['id'] for n in seen_routers['routers']]
241 seen_router_names = [n['name'] for n in seen_routers['routers']]
Yair Fried4d7efa62013-11-17 17:12:29 +0200242
Steve Heyman33735f22016-05-24 09:28:08 -0500243 self.assertIn(tenant.router['name'], seen_router_names)
244 self.assertIn(tenant.router['id'], seen_router_ids)
Yair Fried4d7efa62013-11-17 17:12:29 +0200245
Steve Heyman33735f22016-05-24 09:28:08 -0500246 myport = (tenant.router['id'], tenant.subnet['id'])
Kevin Benton8801e362017-02-12 19:17:55 -0800247 router_ports = [
248 (i['device_id'], f['subnet_id'])
Jordan Pittier64e6b442017-02-20 19:29:02 +0100249 for i in self.admin_manager.ports_client.list_ports(
250 device_id=tenant.router['id'])['ports']
Kevin Benton8801e362017-02-12 19:17:55 -0800251 if net_info.is_router_interface_port(i)
Jordan Pittier64e6b442017-02-20 19:29:02 +0100252 for f in i['fixed_ips']
253 ]
Yair Fried4d7efa62013-11-17 17:12:29 +0200254
255 self.assertIn(myport, router_ports)
256
Markus Zoeller156b5da2016-07-11 18:10:31 +0200257 def _create_server(self, name, tenant, security_groups, **kwargs):
Yair Friedca5cfb52016-01-04 15:41:55 +0200258 """Creates a server and assigns it to security group.
259
260 If multi-host is enabled, Ensures servers are created on different
261 compute nodes, by storing created servers' ids and uses different_host
262 as scheduler_hints on creation.
263 Validates servers are created as requested, using admin client.
264 """
Ken'ichi Ohmichi1b3461e2014-12-02 03:41:07 +0000265 security_groups_names = [{'name': s['name']} for s in security_groups]
Yair Friedca5cfb52016-01-04 15:41:55 +0200266 if self.multi_node:
267 kwargs["scheduler_hints"] = {'different_host': self.servers}
Ken'ichi Ohmichif2d436e2015-09-03 01:13:16 +0000268 server = self.create_server(
269 name=name,
Steve Heyman33735f22016-05-24 09:28:08 -0500270 networks=[{'uuid': tenant.network["id"]}],
lanoux5fc14522015-09-21 08:17:35 +0000271 key_name=tenant.keypair['name'],
272 security_groups=security_groups_names,
Yair Friedca5cfb52016-01-04 15:41:55 +0200273 clients=tenant.manager,
274 **kwargs)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200275 if 'security_groups' in server:
276 self.assertEqual(
277 sorted([s['name'] for s in security_groups]),
278 sorted([s['name'] for s in server['security_groups']]))
Yair Friedca5cfb52016-01-04 15:41:55 +0200279
280 # Verify servers are on different compute nodes
281 if self.multi_node:
282 adm_get_server = self.admin_manager.servers_client.show_server
283 new_host = adm_get_server(server["id"])["server"][
284 "OS-EXT-SRV-ATTR:host"]
285 host_list = [adm_get_server(s)["server"]["OS-EXT-SRV-ATTR:host"]
286 for s in self.servers]
287 self.assertNotIn(new_host, host_list,
288 message="Failed to boot servers on different "
289 "Compute nodes.")
290
291 self.servers.append(server["id"])
292
Claudiu Belufaa98912014-09-01 16:50:28 +0300293 return server
Yair Fried4d7efa62013-11-17 17:12:29 +0200294
295 def _create_tenant_servers(self, tenant, num=1):
296 for i in range(num):
Ken'ichi Ohmichi6ded8df2015-03-23 02:00:19 +0000297 name = 'server-{tenant}-gen-{num}'.format(
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000298 tenant=tenant.creds.tenant_name,
Yair Fried4d7efa62013-11-17 17:12:29 +0200299 num=i
300 )
301 name = data_utils.rand_name(name)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200302 server = self._create_server(name, tenant,
303 [tenant.security_groups['default']])
Yair Fried4d7efa62013-11-17 17:12:29 +0200304 tenant.servers.append(server)
305
306 def _set_access_point(self, tenant):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000307 # creates a server in a secgroup with rule allowing external ssh
Sean Dagueed6e5862016-04-04 10:49:13 -0400308 # in order to access project internal network
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000309 # workaround ip namespace
Yair Frieddb6c9e92014-08-06 08:53:13 +0300310 secgroups = tenant.security_groups.values()
Ken'ichi Ohmichi6ded8df2015-03-23 02:00:19 +0000311 name = 'server-{tenant}-access_point'.format(
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000312 tenant=tenant.creds.tenant_name)
Yair Fried4d7efa62013-11-17 17:12:29 +0200313 name = data_utils.rand_name(name)
314 server = self._create_server(name, tenant,
315 security_groups=secgroups)
Yair Fried4d7efa62013-11-17 17:12:29 +0200316 tenant.access_point = server
Yair Frieddb6c9e92014-08-06 08:53:13 +0300317 self._assign_floating_ips(tenant, server)
Yair Fried4d7efa62013-11-17 17:12:29 +0200318
Yair Frieddb6c9e92014-08-06 08:53:13 +0300319 def _assign_floating_ips(self, tenant, server):
Matthew Treinish6c072292014-01-29 19:15:52 +0000320 public_network_id = CONF.network.public_network_id
Yair Friedae0e73d2014-11-24 11:56:26 +0200321 floating_ip = self.create_floating_ip(
Yair Frieddb6c9e92014-08-06 08:53:13 +0300322 server, public_network_id,
John Warrenfbf2a892015-11-17 12:36:14 -0500323 client=tenant.manager.floating_ips_client)
Yair Frieddb6c9e92014-08-06 08:53:13 +0300324 self.floating_ips.setdefault(server['id'], floating_ip)
Yair Fried4d7efa62013-11-17 17:12:29 +0200325
Markus Zoeller156b5da2016-07-11 18:10:31 +0200326 def _create_tenant_network(self, tenant, port_security_enabled=True):
Yair Frieddb6c9e92014-08-06 08:53:13 +0300327 network, subnet, router = self.create_networks(
John Warren3961acd2015-10-02 14:38:53 -0400328 networks_client=tenant.manager.networks_client,
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000329 routers_client=tenant.manager.routers_client,
Markus Zoeller156b5da2016-07-11 18:10:31 +0200330 subnets_client=tenant.manager.subnets_client,
331 port_security_enabled=port_security_enabled)
Yair Friedbf2e2c42014-01-28 12:06:38 +0200332 tenant.set_network(network, subnet, router)
Yair Fried4d7efa62013-11-17 17:12:29 +0200333
Yair Fried4d7efa62013-11-17 17:12:29 +0200334 def _deploy_tenant(self, tenant_or_id):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000335 """creates:
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000336
Yair Fried4d7efa62013-11-17 17:12:29 +0200337 network
338 subnet
339 router (if public not defined)
340 access security group
341 access-point server
Yair Fried4d7efa62013-11-17 17:12:29 +0200342 """
343 if not isinstance(tenant_or_id, self.TenantProperties):
344 tenant = self.tenants[tenant_or_id]
Yair Fried4d7efa62013-11-17 17:12:29 +0200345 else:
346 tenant = tenant_or_id
Yair Frieddb6c9e92014-08-06 08:53:13 +0300347 self._create_tenant_keypairs(tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200348 self._create_tenant_network(tenant)
349 self._create_tenant_security_groups(tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200350 self._set_access_point(tenant)
351
352 def _get_server_ip(self, server, floating=False):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000353 """returns the ip (floating/internal) of a server"""
Yair Fried4d7efa62013-11-17 17:12:29 +0200354 if floating:
Steve Heyman33735f22016-05-24 09:28:08 -0500355 server_ip = self.floating_ips[server['id']]['floating_ip_address']
Yair Fried4d7efa62013-11-17 17:12:29 +0200356 else:
armando-migliacciod03f2642014-02-21 19:55:50 -0800357 server_ip = None
Steve Heyman33735f22016-05-24 09:28:08 -0500358 network_name = self.tenants[server['tenant_id']].network['name']
Yair Frieddb6c9e92014-08-06 08:53:13 +0300359 if network_name in server['addresses']:
360 server_ip = server['addresses'][network_name][0]['addr']
armando-migliacciod03f2642014-02-21 19:55:50 -0800361 return server_ip
Yair Fried4d7efa62013-11-17 17:12:29 +0200362
363 def _connect_to_access_point(self, tenant):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000364 """create ssh connection to tenant access point"""
Yair Fried4d7efa62013-11-17 17:12:29 +0200365 access_point_ssh = \
Steve Heyman33735f22016-05-24 09:28:08 -0500366 self.floating_ips[tenant.access_point['id']]['floating_ip_address']
Yair Frieddb6c9e92014-08-06 08:53:13 +0300367 private_key = tenant.keypair['private_key']
Jordan Pittierbbb17122016-01-26 17:10:55 +0100368 access_point_ssh = self.get_remote_client(
369 access_point_ssh, private_key=private_key)
Yair Fried4d7efa62013-11-17 17:12:29 +0200370 return access_point_ssh
371
Yair Fried4d7efa62013-11-17 17:12:29 +0200372 def _test_in_tenant_block(self, tenant):
373 access_point_ssh = self._connect_to_access_point(tenant)
374 for server in tenant.servers:
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900375 self.check_remote_connectivity(source=access_point_ssh,
376 dest=self._get_server_ip(server),
377 should_succeed=False)
Yair Fried4d7efa62013-11-17 17:12:29 +0200378
379 def _test_in_tenant_allow(self, tenant):
380 ruleset = dict(
381 protocol='icmp',
Steve Heyman33735f22016-05-24 09:28:08 -0500382 remote_group_id=tenant.security_groups['default']['id'],
Yair Fried4d7efa62013-11-17 17:12:29 +0200383 direction='ingress'
384 )
Matthew Treinishb7144eb2013-12-13 22:57:35 +0000385 self._create_security_group_rule(
Yair Fried4d7efa62013-11-17 17:12:29 +0200386 secgroup=tenant.security_groups['default'],
Yair Friedca5cfb52016-01-04 15:41:55 +0200387 security_groups_client=tenant.manager.security_groups_client,
Yair Fried4d7efa62013-11-17 17:12:29 +0200388 **ruleset
389 )
390 access_point_ssh = self._connect_to_access_point(tenant)
391 for server in tenant.servers:
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900392 self.check_remote_connectivity(source=access_point_ssh,
393 dest=self._get_server_ip(server))
Yair Fried4d7efa62013-11-17 17:12:29 +0200394
395 def _test_cross_tenant_block(self, source_tenant, dest_tenant):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000396 # if public router isn't defined, then dest_tenant access is via
397 # floating-ip
Yair Fried4d7efa62013-11-17 17:12:29 +0200398 access_point_ssh = self._connect_to_access_point(source_tenant)
399 ip = self._get_server_ip(dest_tenant.access_point,
400 floating=self.floating_ip_access)
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900401 self.check_remote_connectivity(source=access_point_ssh, dest=ip,
402 should_succeed=False)
Yair Fried4d7efa62013-11-17 17:12:29 +0200403
404 def _test_cross_tenant_allow(self, source_tenant, dest_tenant):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000405 """check for each direction:
406
Yair Fried4d7efa62013-11-17 17:12:29 +0200407 creating rule for tenant incoming traffic enables only 1way traffic
Yair Friedbf2e2c42014-01-28 12:06:38 +0200408 """
Yair Fried4d7efa62013-11-17 17:12:29 +0200409 ruleset = dict(
410 protocol='icmp',
411 direction='ingress'
412 )
John Warren456d9ae2016-01-12 15:36:33 -0500413 sec_group_rules_client = (
414 dest_tenant.manager.security_group_rules_client)
Matthew Treinishb7144eb2013-12-13 22:57:35 +0000415 self._create_security_group_rule(
Yair Fried4d7efa62013-11-17 17:12:29 +0200416 secgroup=dest_tenant.security_groups['default'],
John Warren456d9ae2016-01-12 15:36:33 -0500417 sec_group_rules_client=sec_group_rules_client,
Yair Fried4d7efa62013-11-17 17:12:29 +0200418 **ruleset
419 )
Yair Friedbf2e2c42014-01-28 12:06:38 +0200420 access_point_ssh = self._connect_to_access_point(source_tenant)
421 ip = self._get_server_ip(dest_tenant.access_point,
422 floating=self.floating_ip_access)
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900423 self.check_remote_connectivity(access_point_ssh, ip)
Yair Fried4d7efa62013-11-17 17:12:29 +0200424
Yair Friedbf2e2c42014-01-28 12:06:38 +0200425 # test that reverse traffic is still blocked
426 self._test_cross_tenant_block(dest_tenant, source_tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200427
Yair Friedbf2e2c42014-01-28 12:06:38 +0200428 # allow reverse traffic and check
John Warren456d9ae2016-01-12 15:36:33 -0500429 sec_group_rules_client = (
430 source_tenant.manager.security_group_rules_client)
Matthew Treinishb7144eb2013-12-13 22:57:35 +0000431 self._create_security_group_rule(
Yair Friedbf2e2c42014-01-28 12:06:38 +0200432 secgroup=source_tenant.security_groups['default'],
John Warren456d9ae2016-01-12 15:36:33 -0500433 sec_group_rules_client=sec_group_rules_client,
Yair Friedbf2e2c42014-01-28 12:06:38 +0200434 **ruleset
435 )
Yair Fried4d7efa62013-11-17 17:12:29 +0200436
Yair Friedbf2e2c42014-01-28 12:06:38 +0200437 access_point_ssh_2 = self._connect_to_access_point(dest_tenant)
438 ip = self._get_server_ip(source_tenant.access_point,
439 floating=self.floating_ip_access)
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900440 self.check_remote_connectivity(access_point_ssh_2, ip)
Yair Fried4d7efa62013-11-17 17:12:29 +0200441
442 def _verify_mac_addr(self, tenant):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000443 """Verify that VM has the same ip, mac as listed in port"""
444
Yair Fried4d7efa62013-11-17 17:12:29 +0200445 access_point_ssh = self._connect_to_access_point(tenant)
446 mac_addr = access_point_ssh.get_mac_address()
447 mac_addr = mac_addr.strip().lower()
Henry Gessau78ab4b02014-03-31 15:10:13 -0400448 # Get the fixed_ips and mac_address fields of all ports. Select
449 # only those two columns to reduce the size of the response.
Jordan Pittier64e6b442017-02-20 19:29:02 +0100450 port_list = self.admin_manager.ports_client.list_ports(
451 fields=['fixed_ips', 'mac_address'])['ports']
Yair Fried4d7efa62013-11-17 17:12:29 +0200452 port_detail_list = [
453 (port['fixed_ips'][0]['subnet_id'],
454 port['fixed_ips'][0]['ip_address'],
Henry Gessau78ab4b02014-03-31 15:10:13 -0400455 port['mac_address'].lower())
456 for port in port_list if port['fixed_ips']
Yair Fried4d7efa62013-11-17 17:12:29 +0200457 ]
458 server_ip = self._get_server_ip(tenant.access_point)
Steve Heyman33735f22016-05-24 09:28:08 -0500459 subnet_id = tenant.subnet['id']
Yair Fried4d7efa62013-11-17 17:12:29 +0200460 self.assertIn((subnet_id, server_ip, mac_addr), port_detail_list)
461
Ihar Hrachyshkaa9dca2b2017-04-04 14:17:11 -0700462 def _log_console_output_for_all_tenants(self):
463 for tenant in self.tenants.values():
464 client = tenant.manager.servers_client
465 self._log_console_output(servers=tenant.servers, client=client)
466 if tenant.access_point is not None:
467 self._log_console_output(
468 servers=[tenant.access_point], client=client)
469
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800470 @decorators.idempotent_id('e79f879e-debb-440c-a7e4-efeda05b6848')
Masayuki Igawa4ded9f02014-02-17 15:05:59 +0900471 @test.services('compute', 'network')
Yair Fried4d7efa62013-11-17 17:12:29 +0200472 def test_cross_tenant_traffic(self):
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100473 if not self.credentials_provider.is_multi_tenant():
Yair Fried79b0a912014-10-20 11:15:37 +0300474 raise self.skipException("No secondary tenant defined")
Nachi Ueno26b4c972014-01-17 06:15:13 -0800475 try:
Sean Dagueed6e5862016-04-04 10:49:13 -0400476 # deploy new project
Yair Friedbf2e2c42014-01-28 12:06:38 +0200477 self._deploy_tenant(self.alt_tenant)
478 self._verify_network_details(self.alt_tenant)
479 self._verify_mac_addr(self.alt_tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200480
Nachi Ueno26b4c972014-01-17 06:15:13 -0800481 # cross tenant check
Yair Friedbf2e2c42014-01-28 12:06:38 +0200482 source_tenant = self.primary_tenant
Nachi Ueno26b4c972014-01-17 06:15:13 -0800483 dest_tenant = self.alt_tenant
484 self._test_cross_tenant_block(source_tenant, dest_tenant)
485 self._test_cross_tenant_allow(source_tenant, dest_tenant)
486 except Exception:
Ihar Hrachyshkaa9dca2b2017-04-04 14:17:11 -0700487 self._log_console_output_for_all_tenants()
Yair Friedbf2e2c42014-01-28 12:06:38 +0200488 raise
489
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800490 @decorators.idempotent_id('63163892-bbf6-4249-aa12-d5ea1f8f421b')
Masayuki Igawa4ded9f02014-02-17 15:05:59 +0900491 @test.services('compute', 'network')
Yair Friedbf2e2c42014-01-28 12:06:38 +0200492 def test_in_tenant_traffic(self):
493 try:
494 self._create_tenant_servers(self.primary_tenant, num=1)
495
496 # in-tenant check
497 self._test_in_tenant_block(self.primary_tenant)
498 self._test_in_tenant_allow(self.primary_tenant)
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800499 except Exception:
Ihar Hrachyshkaa9dca2b2017-04-04 14:17:11 -0700500 self._log_console_output_for_all_tenants()
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800501 raise
Yair Friedbf2e2c42014-01-28 12:06:38 +0200502
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800503 @decorators.idempotent_id('f4d556d7-1526-42ad-bafb-6bebf48568f6')
Sean Dague49505df2017-03-01 11:35:58 -0500504 @test.attr(type='slow')
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800505 @test.services('compute', 'network')
506 def test_port_update_new_security_group(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000507 """Verifies the traffic after updating the vm port
508
509 With new security group having appropriate rule.
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800510 """
511 new_tenant = self.primary_tenant
512
513 # Create empty security group and add icmp rule in it
514 new_sg = self._create_empty_security_group(
515 namestart='secgroup_new-',
516 tenant_id=new_tenant.creds.tenant_id,
John Warrenf9606e92015-12-10 12:12:42 -0500517 client=new_tenant.manager.security_groups_client)
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800518 icmp_rule = dict(
519 protocol='icmp',
520 direction='ingress',
521 )
John Warren456d9ae2016-01-12 15:36:33 -0500522 sec_group_rules_client = new_tenant.manager.security_group_rules_client
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800523 self._create_security_group_rule(
524 secgroup=new_sg,
John Warren456d9ae2016-01-12 15:36:33 -0500525 sec_group_rules_client=sec_group_rules_client,
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800526 **icmp_rule)
527 new_tenant.security_groups.update(new_sg=new_sg)
528
529 # Create server with default security group
Ken'ichi Ohmichi6ded8df2015-03-23 02:00:19 +0000530 name = 'server-{tenant}-gen-1'.format(
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800531 tenant=new_tenant.creds.tenant_name
532 )
533 name = data_utils.rand_name(name)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200534 server = self._create_server(name, new_tenant,
535 [new_tenant.security_groups['default']])
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800536
537 # Check connectivity failure with default security group
538 try:
539 access_point_ssh = self._connect_to_access_point(new_tenant)
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900540 self.check_remote_connectivity(source=access_point_ssh,
541 dest=self._get_server_ip(server),
542 should_succeed=False)
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800543 server_id = server['id']
Jordan Pittier64e6b442017-02-20 19:29:02 +0100544 port_id = self.admin_manager.ports_client.list_ports(
545 device_id=server_id)['ports'][0]['id']
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800546
547 # update port with new security group and check connectivity
John Warren49c0fe52015-10-22 12:35:54 -0400548 self.ports_client.update_port(port_id, security_groups=[
Steve Heyman33735f22016-05-24 09:28:08 -0500549 new_tenant.security_groups['new_sg']['id']])
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900550 self.check_remote_connectivity(
551 source=access_point_ssh,
552 dest=self._get_server_ip(server))
Yair Friedbf2e2c42014-01-28 12:06:38 +0200553 except Exception:
Ihar Hrachyshkaa9dca2b2017-04-04 14:17:11 -0700554 self._log_console_output_for_all_tenants()
Nachi Ueno26b4c972014-01-17 06:15:13 -0800555 raise
prdsilva8b733ad2014-12-09 02:54:49 -0800556
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800557 @decorators.idempotent_id('d2f77418-fcc4-439d-b935-72eca704e293')
Sean Dague49505df2017-03-01 11:35:58 -0500558 @test.attr(type='slow')
prdsilva8b733ad2014-12-09 02:54:49 -0800559 @test.services('compute', 'network')
560 def test_multiple_security_groups(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000561 """Verify multiple security groups and checks that rules
562
prdsilva8b733ad2014-12-09 02:54:49 -0800563 provided in the both the groups is applied onto VM
564 """
565 tenant = self.primary_tenant
566 ip = self._get_server_ip(tenant.access_point,
567 floating=self.floating_ip_access)
lanoux283273b2015-12-04 03:01:54 -0800568 ssh_login = CONF.validation.image_ssh_user
prdsilva8b733ad2014-12-09 02:54:49 -0800569 private_key = tenant.keypair['private_key']
570 self.check_vm_connectivity(ip,
571 should_connect=False)
572 ruleset = dict(
573 protocol='icmp',
574 direction='ingress'
575 )
576 self._create_security_group_rule(
577 secgroup=tenant.security_groups['default'],
578 **ruleset
579 )
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000580 # NOTE: Vm now has 2 security groups one with ssh rule(
581 # already added in setUp() method),and other with icmp rule
582 # (added in the above step).The check_vm_connectivity tests
583 # -that vm ping test is successful
584 # -ssh to vm is successful
prdsilva8b733ad2014-12-09 02:54:49 -0800585 self.check_vm_connectivity(ip,
586 username=ssh_login,
587 private_key=private_key,
588 should_connect=True)
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900589
Sean Dague49505df2017-03-01 11:35:58 -0500590 @test.attr(type='slow')
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900591 @test.requires_ext(service='network', extension='port-security')
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800592 @decorators.idempotent_id('7c811dcc-263b-49a3-92d2-1b4d8405f50c')
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900593 @test.services('compute', 'network')
594 def test_port_security_disable_security_group(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000595 """Verify the default security group rules is disabled."""
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900596 new_tenant = self.primary_tenant
597
598 # Create server
599 name = 'server-{tenant}-gen-1'.format(
600 tenant=new_tenant.creds.tenant_name
601 )
602 name = data_utils.rand_name(name)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200603 server = self._create_server(name, new_tenant,
604 [new_tenant.security_groups['default']])
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900605
606 access_point_ssh = self._connect_to_access_point(new_tenant)
607 server_id = server['id']
Jordan Pittier64e6b442017-02-20 19:29:02 +0100608 port_id = self.admin_manager.ports_client.list_ports(
609 device_id=server_id)['ports'][0]['id']
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900610
611 # Flip the port's port security and check connectivity
612 try:
John Warren49c0fe52015-10-22 12:35:54 -0400613 self.ports_client.update_port(port_id,
614 port_security_enabled=True,
615 security_groups=[])
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900616 self.check_remote_connectivity(source=access_point_ssh,
617 dest=self._get_server_ip(server),
618 should_succeed=False)
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900619
John Warren49c0fe52015-10-22 12:35:54 -0400620 self.ports_client.update_port(port_id,
621 port_security_enabled=False,
622 security_groups=[])
YAMAMOTO Takashi4c3ebb02017-01-25 16:04:30 +0900623 self.check_remote_connectivity(
624 source=access_point_ssh,
625 dest=self._get_server_ip(server))
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900626 except Exception:
Ihar Hrachyshkaa9dca2b2017-04-04 14:17:11 -0700627 self._log_console_output_for_all_tenants()
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900628 raise
Markus Zoeller156b5da2016-07-11 18:10:31 +0200629
Sean Dague49505df2017-03-01 11:35:58 -0500630 @test.attr(type='slow')
Markus Zoeller156b5da2016-07-11 18:10:31 +0200631 @test.requires_ext(service='network', extension='port-security')
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800632 @decorators.idempotent_id('13ccf253-e5ad-424b-9c4a-97b88a026699')
Markus Zoeller156b5da2016-07-11 18:10:31 +0200633 @testtools.skipUnless(
634 CONF.compute_feature_enabled.allow_port_security_disabled,
635 'Port security must be enabled.')
Matt Riedemann039b2fe2016-09-15 16:12:24 -0400636 # TODO(mriedem): We shouldn't actually need to check this since neutron
637 # disables the port_security extension by default, but the problem is nova
638 # assumes port_security_enabled=True if it's not set on the network
639 # resource, which will mean nova may attempt to apply a security group on
640 # a port on that network which would fail. This is really a bug in nova.
641 @testtools.skipUnless(
642 CONF.network_feature_enabled.port_security,
643 'Port security must be enabled.')
Markus Zoeller156b5da2016-07-11 18:10:31 +0200644 @test.services('compute', 'network')
645 def test_boot_into_disabled_port_security_network_without_secgroup(self):
646 tenant = self.primary_tenant
647 self._create_tenant_network(tenant, port_security_enabled=False)
648 self.assertFalse(tenant.network['port_security_enabled'])
649 name = data_utils.rand_name('server-smoke')
650 sec_groups = []
651 server = self._create_server(name, tenant, sec_groups)
652 server_id = server['id']
Jordan Pittier64e6b442017-02-20 19:29:02 +0100653 ports = self.admin_manager.ports_client.list_ports(
654 device_id=server_id)['ports']
Markus Zoeller156b5da2016-07-11 18:10:31 +0200655 self.assertEqual(1, len(ports))
656 for port in ports:
657 self.assertEmpty(port['security_groups'],
658 "Neutron shouldn't even use it's default sec "
659 "group.")