blob: f8c5c0a09cd6e4c05fc34cda4a9c256f546aa710 [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
Fei Long Wangd39431f2015-05-14 11:30:48 +120018from tempest.common.utils import data_utils
Attila Fazekasd7e08a62016-10-07 13:05:05 +020019from tempest.common.utils import net_info
Matthew Treinish6c072292014-01-29 19:15:52 +000020from tempest import config
Yair Fried4d7efa62013-11-17 17:12:29 +020021from tempest.scenario import manager
Masayuki Igawa4ded9f02014-02-17 15:05:59 +090022from tempest import test
Yair Fried4d7efa62013-11-17 17:12:29 +020023
Matthew Treinish6c072292014-01-29 19:15:52 +000024CONF = config.CONF
Yair Friedca5cfb52016-01-04 15:41:55 +020025LOG = log.getLogger(__name__)
Matthew Treinish6c072292014-01-29 19:15:52 +000026
Yair Fried4d7efa62013-11-17 17:12:29 +020027
Andrea Frittoli4971fc82014-09-25 10:22:20 +010028class TestSecurityGroupsBasicOps(manager.NetworkScenarioTest):
Yair Fried4d7efa62013-11-17 17:12:29 +020029
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +000030 """The test suite for security groups
31
Yair Fried4d7efa62013-11-17 17:12:29 +020032 This test suite assumes that Nova has been configured to
33 boot VM's with Neutron-managed networking, and attempts to
34 verify cross tenant connectivity as follows
35
36 ssh:
37 in order to overcome "ip namespace", each tenant has an "access point"
38 VM with floating-ip open to incoming ssh connection allowing network
39 commands (ping/ssh) to be executed from within the
40 tenant-network-namespace
41 Tempest host performs key-based authentication to the ssh server via
42 floating IP address
43
44 connectivity test is done by pinging destination server via source server
45 ssh connection.
46 success - ping returns
47 failure - ping_timeout reached
48
Eran Kurisb5f69782016-04-10 11:48:28 +030049 multi-node:
50 Multi-Node mode is enabled when CONF.compute.min_compute_nodes > 1.
51 Tests connectivity between servers on different compute nodes.
52 When enabled, test will boot each new server to different
53 compute nodes.
54
Yair Fried4d7efa62013-11-17 17:12:29 +020055 setup:
Yair Friedbf2e2c42014-01-28 12:06:38 +020056 for primary tenant:
Yair Fried4d7efa62013-11-17 17:12:29 +020057 1. create a network&subnet
58 2. create a router (if public router isn't configured)
59 3. connect tenant network to public network via router
60 4. create an access point:
61 a. a security group open to incoming ssh connection
62 b. a VM with a floating ip
63 5. create a general empty security group (same as "default", but
64 without rules allowing in-tenant traffic)
Yair Fried4d7efa62013-11-17 17:12:29 +020065
66 tests:
67 1. _verify_network_details
68 2. _verify_mac_addr: for each access point verify that
69 (subnet, fix_ip, mac address) are as defined in the port list
70 3. _test_in_tenant_block: test that in-tenant traffic is disabled
71 without rules allowing it
72 4. _test_in_tenant_allow: test that in-tenant traffic is enabled
73 once an appropriate rule has been created
74 5. _test_cross_tenant_block: test that cross-tenant traffic is disabled
75 without a rule allowing it on destination tenant
76 6. _test_cross_tenant_allow:
77 * test that cross-tenant traffic is enabled once an appropriate
78 rule has been created on destination tenant.
79 * test that reverse traffic is still blocked
Fei Long Wang50131ee2015-02-02 16:58:24 +130080 * test than reverse traffic is enabled once an appropriate rule has
Yair Fried4d7efa62013-11-17 17:12:29 +020081 been created on source tenant
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -080082 7._test_port_update_new_security_group:
83 * test that traffic is blocked with default security group
84 * test that traffic is enabled after updating port with new security
85 group having appropriate rule
prdsilva8b733ad2014-12-09 02:54:49 -080086 8. _test_multiple_security_groups: test multiple security groups can be
87 associated with the vm
Yair Fried4d7efa62013-11-17 17:12:29 +020088
89 assumptions:
Yair Friedbf2e2c42014-01-28 12:06:38 +020090 1. alt_tenant/user existed and is different from primary_tenant/user
Yair Fried4d7efa62013-11-17 17:12:29 +020091 2. Public network is defined and reachable from the Tempest host
92 3. Public router can either be:
93 * defined, in which case all tenants networks can connect directly
94 to it, and cross tenant check will be done on the private IP of the
95 destination tenant
96 or
Fei Long Wang50131ee2015-02-02 16:58:24 +130097 * not defined (empty string), in which case each tenant will have
Yair Fried4d7efa62013-11-17 17:12:29 +020098 its own router connected to the public network
99 """
100
Andrea Frittolib21de6c2015-02-06 20:12:38 +0000101 credentials = ['primary', 'alt', 'admin']
102
Joe Gordon28788b42015-02-25 12:42:37 -0800103 class TenantProperties(object):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000104 """helper class to save tenant details
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000105
Yair Fried4d7efa62013-11-17 17:12:29 +0200106 id
107 credentials
108 network
109 subnet
110 security groups
111 servers
112 access point
Yair Friedbf2e2c42014-01-28 12:06:38 +0200113 """
Yair Fried4d7efa62013-11-17 17:12:29 +0200114
Andrea Frittoli73224672016-12-09 21:08:19 +0000115 def __init__(self, clients):
Andrea Frittoli422fbdf2014-03-20 10:05:18 +0000116 # Credentials from manager are filled with both names and IDs
Andrea Frittoli73224672016-12-09 21:08:19 +0000117 self.manager = clients
Andrea Frittoli422fbdf2014-03-20 10:05:18 +0000118 self.creds = self.manager.credentials
Yair Fried4d7efa62013-11-17 17:12:29 +0200119 self.network = None
120 self.subnet = None
121 self.router = None
122 self.security_groups = {}
123 self.servers = list()
124
Yair Friedbf2e2c42014-01-28 12:06:38 +0200125 def set_network(self, network, subnet, router):
Yair Fried4d7efa62013-11-17 17:12:29 +0200126 self.network = network
127 self.subnet = subnet
128 self.router = router
129
Yair Fried4d7efa62013-11-17 17:12:29 +0200130 @classmethod
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000131 def skip_checks(cls):
132 super(TestSecurityGroupsBasicOps, cls).skip_checks()
Itzik Brown06952672015-03-29 12:38:58 +0300133 if CONF.network.port_vnic_type in ['direct', 'macvtap']:
134 msg = ('Not currently supported when using vnic_type'
135 ' direct or macvtap')
136 raise cls.skipException(msg)
Sean Dagueed6e5862016-04-04 10:49:13 -0400137 if not (CONF.network.project_networks_reachable or
Matthew Treinish6c072292014-01-29 19:15:52 +0000138 CONF.network.public_network_id):
Sean Dagueed6e5862016-04-04 10:49:13 -0400139 msg = ('Either project_networks_reachable must be "true", or '
Yair Fried4d7efa62013-11-17 17:12:29 +0200140 'public_network_id must be defined.')
Yair Fried4d7efa62013-11-17 17:12:29 +0200141 raise cls.skipException(msg)
Bence Romsics41f3f852016-01-11 13:48:23 +0100142 if not test.is_extension_enabled('security-group', 'network'):
143 msg = "security-group extension not enabled."
144 raise cls.skipException(msg)
ghanshyam929b3482016-12-05 11:47:53 +0900145 if CONF.network.shared_physical_network:
Thiago Paiva66cded22016-08-15 14:55:58 -0300146 msg = ('Deployment uses a shared physical network, security '
147 'groups not supported')
148 raise cls.skipException(msg)
Yair Fried4d7efa62013-11-17 17:12:29 +0200149
150 @classmethod
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000151 def setup_credentials(cls):
Yair Fried764610a2014-04-07 12:17:05 +0300152 # Create no network resources for these tests.
153 cls.set_network_resources()
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000154 super(TestSecurityGroupsBasicOps, cls).setup_credentials()
Yair Fried79b0a912014-10-20 11:15:37 +0300155
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000156 @classmethod
157 def resource_setup(cls):
158 super(TestSecurityGroupsBasicOps, cls).resource_setup()
Yair Friedca5cfb52016-01-04 15:41:55 +0200159
160 cls.multi_node = CONF.compute.min_compute_nodes > 1 and \
Yair Fried95914122016-03-03 09:14:40 +0200161 test.is_scheduler_filter_enabled("DifferentHostFilter")
Yair Friedca5cfb52016-01-04 15:41:55 +0200162 if cls.multi_node:
163 LOG.info("Working in Multi Node mode")
164 else:
165 LOG.info("Working in Single Node mode")
166
Yair Fried4d7efa62013-11-17 17:12:29 +0200167 cls.floating_ips = {}
168 cls.tenants = {}
Andrea Frittoli73224672016-12-09 21:08:19 +0000169 cls.primary_tenant = cls.TenantProperties(cls.os)
170 cls.alt_tenant = cls.TenantProperties(cls.os_alt)
Yair Friedbf2e2c42014-01-28 12:06:38 +0200171 for tenant in [cls.primary_tenant, cls.alt_tenant]:
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000172 cls.tenants[tenant.creds.tenant_id] = tenant
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000173
Yair Friedbf2e2c42014-01-28 12:06:38 +0200174 cls.floating_ip_access = not CONF.network.public_router_id
Yair Fried4d7efa62013-11-17 17:12:29 +0200175
Yair Friedbf2e2c42014-01-28 12:06:38 +0200176 def setUp(self):
Yair Friedca5cfb52016-01-04 15:41:55 +0200177 """Set up a single tenant with an accessible server.
178
179 If multi-host is enabled, save created server uuids.
180 """
181 self.servers = []
182
Yair Friedbf2e2c42014-01-28 12:06:38 +0200183 super(TestSecurityGroupsBasicOps, self).setUp()
184 self._deploy_tenant(self.primary_tenant)
185 self._verify_network_details(self.primary_tenant)
186 self._verify_mac_addr(self.primary_tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200187
Yair Frieddb6c9e92014-08-06 08:53:13 +0300188 def _create_tenant_keypairs(self, tenant):
189 keypair = self.create_keypair(tenant.manager.keypairs_client)
190 tenant.keypair = keypair
Yair Fried4d7efa62013-11-17 17:12:29 +0200191
192 def _create_tenant_security_groups(self, tenant):
Yair Fried4d7efa62013-11-17 17:12:29 +0200193 access_sg = self._create_empty_security_group(
194 namestart='secgroup_access-',
Yair Frieddb6c9e92014-08-06 08:53:13 +0300195 tenant_id=tenant.creds.tenant_id,
John Warrenf9606e92015-12-10 12:12:42 -0500196 client=tenant.manager.security_groups_client
Yair Fried4d7efa62013-11-17 17:12:29 +0200197 )
Yair Friedbf2e2c42014-01-28 12:06:38 +0200198
Sean Dagueed6e5862016-04-04 10:49:13 -0400199 # don't use default secgroup since it allows in-project traffic
Yair Fried4d7efa62013-11-17 17:12:29 +0200200 def_sg = self._create_empty_security_group(
201 namestart='secgroup_general-',
Yair Frieddb6c9e92014-08-06 08:53:13 +0300202 tenant_id=tenant.creds.tenant_id,
John Warrenf9606e92015-12-10 12:12:42 -0500203 client=tenant.manager.security_groups_client
Yair Fried4d7efa62013-11-17 17:12:29 +0200204 )
205 tenant.security_groups.update(access=access_sg, default=def_sg)
206 ssh_rule = dict(
207 protocol='tcp',
208 port_range_min=22,
209 port_range_max=22,
210 direction='ingress',
211 )
John Warren456d9ae2016-01-12 15:36:33 -0500212 sec_group_rules_client = tenant.manager.security_group_rules_client
213 self._create_security_group_rule(
214 secgroup=access_sg,
215 sec_group_rules_client=sec_group_rules_client,
216 **ssh_rule)
Yair Fried4d7efa62013-11-17 17:12:29 +0200217
218 def _verify_network_details(self, tenant):
219 # Checks that we see the newly created network/subnet/router via
220 # checking the result of list_[networks,routers,subnets]
221 # Check that (router, subnet) couple exist in port_list
222 seen_nets = self._list_networks()
223 seen_names = [n['name'] for n in seen_nets]
224 seen_ids = [n['id'] for n in seen_nets]
225
Steve Heyman33735f22016-05-24 09:28:08 -0500226 self.assertIn(tenant.network['name'], seen_names)
227 self.assertIn(tenant.network['id'], seen_ids)
Yair Fried4d7efa62013-11-17 17:12:29 +0200228
229 seen_subnets = [(n['id'], n['cidr'], n['network_id'])
230 for n in self._list_subnets()]
Steve Heyman33735f22016-05-24 09:28:08 -0500231 mysubnet = (tenant.subnet['id'], tenant.subnet['cidr'],
232 tenant.network['id'])
Yair Fried4d7efa62013-11-17 17:12:29 +0200233 self.assertIn(mysubnet, seen_subnets)
234
235 seen_routers = self._list_routers()
236 seen_router_ids = [n['id'] for n in seen_routers]
237 seen_router_names = [n['name'] for n in seen_routers]
238
Steve Heyman33735f22016-05-24 09:28:08 -0500239 self.assertIn(tenant.router['name'], seen_router_names)
240 self.assertIn(tenant.router['id'], seen_router_ids)
Yair Fried4d7efa62013-11-17 17:12:29 +0200241
Steve Heyman33735f22016-05-24 09:28:08 -0500242 myport = (tenant.router['id'], tenant.subnet['id'])
Yair Fried4d7efa62013-11-17 17:12:29 +0200243 router_ports = [(i['device_id'], i['fixed_ips'][0]['subnet_id']) for i
Yair Frieddb6c9e92014-08-06 08:53:13 +0300244 in self._list_ports()
Attila Fazekasd7e08a62016-10-07 13:05:05 +0200245 if net_info.is_router_interface_port(i)]
Yair Fried4d7efa62013-11-17 17:12:29 +0200246
247 self.assertIn(myport, router_ports)
248
Markus Zoeller156b5da2016-07-11 18:10:31 +0200249 def _create_server(self, name, tenant, security_groups, **kwargs):
Yair Friedca5cfb52016-01-04 15:41:55 +0200250 """Creates a server and assigns it to security group.
251
252 If multi-host is enabled, Ensures servers are created on different
253 compute nodes, by storing created servers' ids and uses different_host
254 as scheduler_hints on creation.
255 Validates servers are created as requested, using admin client.
256 """
Ken'ichi Ohmichi1b3461e2014-12-02 03:41:07 +0000257 security_groups_names = [{'name': s['name']} for s in security_groups]
Yair Friedca5cfb52016-01-04 15:41:55 +0200258 if self.multi_node:
259 kwargs["scheduler_hints"] = {'different_host': self.servers}
Ken'ichi Ohmichif2d436e2015-09-03 01:13:16 +0000260 server = self.create_server(
261 name=name,
Steve Heyman33735f22016-05-24 09:28:08 -0500262 networks=[{'uuid': tenant.network["id"]}],
lanoux5fc14522015-09-21 08:17:35 +0000263 key_name=tenant.keypair['name'],
264 security_groups=security_groups_names,
265 wait_until='ACTIVE',
Yair Friedca5cfb52016-01-04 15:41:55 +0200266 clients=tenant.manager,
267 **kwargs)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200268 if 'security_groups' in server:
269 self.assertEqual(
270 sorted([s['name'] for s in security_groups]),
271 sorted([s['name'] for s in server['security_groups']]))
Yair Friedca5cfb52016-01-04 15:41:55 +0200272
273 # Verify servers are on different compute nodes
274 if self.multi_node:
275 adm_get_server = self.admin_manager.servers_client.show_server
276 new_host = adm_get_server(server["id"])["server"][
277 "OS-EXT-SRV-ATTR:host"]
278 host_list = [adm_get_server(s)["server"]["OS-EXT-SRV-ATTR:host"]
279 for s in self.servers]
280 self.assertNotIn(new_host, host_list,
281 message="Failed to boot servers on different "
282 "Compute nodes.")
283
284 self.servers.append(server["id"])
285
Claudiu Belufaa98912014-09-01 16:50:28 +0300286 return server
Yair Fried4d7efa62013-11-17 17:12:29 +0200287
288 def _create_tenant_servers(self, tenant, num=1):
289 for i in range(num):
Ken'ichi Ohmichi6ded8df2015-03-23 02:00:19 +0000290 name = 'server-{tenant}-gen-{num}'.format(
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000291 tenant=tenant.creds.tenant_name,
Yair Fried4d7efa62013-11-17 17:12:29 +0200292 num=i
293 )
294 name = data_utils.rand_name(name)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200295 server = self._create_server(name, tenant,
296 [tenant.security_groups['default']])
Yair Fried4d7efa62013-11-17 17:12:29 +0200297 tenant.servers.append(server)
298
299 def _set_access_point(self, tenant):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000300 # creates a server in a secgroup with rule allowing external ssh
Sean Dagueed6e5862016-04-04 10:49:13 -0400301 # in order to access project internal network
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000302 # workaround ip namespace
Yair Frieddb6c9e92014-08-06 08:53:13 +0300303 secgroups = tenant.security_groups.values()
Ken'ichi Ohmichi6ded8df2015-03-23 02:00:19 +0000304 name = 'server-{tenant}-access_point'.format(
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000305 tenant=tenant.creds.tenant_name)
Yair Fried4d7efa62013-11-17 17:12:29 +0200306 name = data_utils.rand_name(name)
307 server = self._create_server(name, tenant,
308 security_groups=secgroups)
Yair Fried4d7efa62013-11-17 17:12:29 +0200309 tenant.access_point = server
Yair Frieddb6c9e92014-08-06 08:53:13 +0300310 self._assign_floating_ips(tenant, server)
Yair Fried4d7efa62013-11-17 17:12:29 +0200311
Yair Frieddb6c9e92014-08-06 08:53:13 +0300312 def _assign_floating_ips(self, tenant, server):
Matthew Treinish6c072292014-01-29 19:15:52 +0000313 public_network_id = CONF.network.public_network_id
Yair Friedae0e73d2014-11-24 11:56:26 +0200314 floating_ip = self.create_floating_ip(
Yair Frieddb6c9e92014-08-06 08:53:13 +0300315 server, public_network_id,
John Warrenfbf2a892015-11-17 12:36:14 -0500316 client=tenant.manager.floating_ips_client)
Yair Frieddb6c9e92014-08-06 08:53:13 +0300317 self.floating_ips.setdefault(server['id'], floating_ip)
Yair Fried4d7efa62013-11-17 17:12:29 +0200318
Markus Zoeller156b5da2016-07-11 18:10:31 +0200319 def _create_tenant_network(self, tenant, port_security_enabled=True):
Yair Frieddb6c9e92014-08-06 08:53:13 +0300320 network, subnet, router = self.create_networks(
John Warren3961acd2015-10-02 14:38:53 -0400321 networks_client=tenant.manager.networks_client,
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000322 routers_client=tenant.manager.routers_client,
Markus Zoeller156b5da2016-07-11 18:10:31 +0200323 subnets_client=tenant.manager.subnets_client,
324 port_security_enabled=port_security_enabled)
Yair Friedbf2e2c42014-01-28 12:06:38 +0200325 tenant.set_network(network, subnet, router)
Yair Fried4d7efa62013-11-17 17:12:29 +0200326
Yair Fried4d7efa62013-11-17 17:12:29 +0200327 def _deploy_tenant(self, tenant_or_id):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000328 """creates:
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000329
Yair Fried4d7efa62013-11-17 17:12:29 +0200330 network
331 subnet
332 router (if public not defined)
333 access security group
334 access-point server
Yair Fried4d7efa62013-11-17 17:12:29 +0200335 """
336 if not isinstance(tenant_or_id, self.TenantProperties):
337 tenant = self.tenants[tenant_or_id]
Yair Fried4d7efa62013-11-17 17:12:29 +0200338 else:
339 tenant = tenant_or_id
Yair Frieddb6c9e92014-08-06 08:53:13 +0300340 self._create_tenant_keypairs(tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200341 self._create_tenant_network(tenant)
342 self._create_tenant_security_groups(tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200343 self._set_access_point(tenant)
344
345 def _get_server_ip(self, server, floating=False):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000346 """returns the ip (floating/internal) of a server"""
Yair Fried4d7efa62013-11-17 17:12:29 +0200347 if floating:
Steve Heyman33735f22016-05-24 09:28:08 -0500348 server_ip = self.floating_ips[server['id']]['floating_ip_address']
Yair Fried4d7efa62013-11-17 17:12:29 +0200349 else:
armando-migliacciod03f2642014-02-21 19:55:50 -0800350 server_ip = None
Steve Heyman33735f22016-05-24 09:28:08 -0500351 network_name = self.tenants[server['tenant_id']].network['name']
Yair Frieddb6c9e92014-08-06 08:53:13 +0300352 if network_name in server['addresses']:
353 server_ip = server['addresses'][network_name][0]['addr']
armando-migliacciod03f2642014-02-21 19:55:50 -0800354 return server_ip
Yair Fried4d7efa62013-11-17 17:12:29 +0200355
356 def _connect_to_access_point(self, tenant):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000357 """create ssh connection to tenant access point"""
Yair Fried4d7efa62013-11-17 17:12:29 +0200358 access_point_ssh = \
Steve Heyman33735f22016-05-24 09:28:08 -0500359 self.floating_ips[tenant.access_point['id']]['floating_ip_address']
Yair Frieddb6c9e92014-08-06 08:53:13 +0300360 private_key = tenant.keypair['private_key']
Jordan Pittierbbb17122016-01-26 17:10:55 +0100361 access_point_ssh = self.get_remote_client(
362 access_point_ssh, private_key=private_key)
Yair Fried4d7efa62013-11-17 17:12:29 +0200363 return access_point_ssh
364
Yair Fried4d7efa62013-11-17 17:12:29 +0200365 def _check_connectivity(self, access_point, ip, should_succeed=True):
366 if should_succeed:
367 msg = "Timed out waiting for %s to become reachable" % ip
368 else:
Yair Fried4d7efa62013-11-17 17:12:29 +0200369 msg = "%s is reachable" % ip
Matthew Treinish53483132014-12-09 18:50:06 -0500370 self.assertTrue(self._check_remote_connectivity(access_point, ip,
371 should_succeed), msg)
Yair Fried4d7efa62013-11-17 17:12:29 +0200372
373 def _test_in_tenant_block(self, tenant):
374 access_point_ssh = self._connect_to_access_point(tenant)
375 for server in tenant.servers:
376 self._check_connectivity(access_point=access_point_ssh,
377 ip=self._get_server_ip(server),
378 should_succeed=False)
379
380 def _test_in_tenant_allow(self, tenant):
381 ruleset = dict(
382 protocol='icmp',
Steve Heyman33735f22016-05-24 09:28:08 -0500383 remote_group_id=tenant.security_groups['default']['id'],
Yair Fried4d7efa62013-11-17 17:12:29 +0200384 direction='ingress'
385 )
Matthew Treinishb7144eb2013-12-13 22:57:35 +0000386 self._create_security_group_rule(
Yair Fried4d7efa62013-11-17 17:12:29 +0200387 secgroup=tenant.security_groups['default'],
Yair Friedca5cfb52016-01-04 15:41:55 +0200388 security_groups_client=tenant.manager.security_groups_client,
Yair Fried4d7efa62013-11-17 17:12:29 +0200389 **ruleset
390 )
391 access_point_ssh = self._connect_to_access_point(tenant)
392 for server in tenant.servers:
393 self._check_connectivity(access_point=access_point_ssh,
394 ip=self._get_server_ip(server))
Yair Fried4d7efa62013-11-17 17:12:29 +0200395
396 def _test_cross_tenant_block(self, source_tenant, dest_tenant):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000397 # if public router isn't defined, then dest_tenant access is via
398 # floating-ip
Yair Fried4d7efa62013-11-17 17:12:29 +0200399 access_point_ssh = self._connect_to_access_point(source_tenant)
400 ip = self._get_server_ip(dest_tenant.access_point,
401 floating=self.floating_ip_access)
402 self._check_connectivity(access_point=access_point_ssh, ip=ip,
403 should_succeed=False)
404
405 def _test_cross_tenant_allow(self, source_tenant, dest_tenant):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000406 """check for each direction:
407
Yair Fried4d7efa62013-11-17 17:12:29 +0200408 creating rule for tenant incoming traffic enables only 1way traffic
Yair Friedbf2e2c42014-01-28 12:06:38 +0200409 """
Yair Fried4d7efa62013-11-17 17:12:29 +0200410 ruleset = dict(
411 protocol='icmp',
412 direction='ingress'
413 )
John Warren456d9ae2016-01-12 15:36:33 -0500414 sec_group_rules_client = (
415 dest_tenant.manager.security_group_rules_client)
Matthew Treinishb7144eb2013-12-13 22:57:35 +0000416 self._create_security_group_rule(
Yair Fried4d7efa62013-11-17 17:12:29 +0200417 secgroup=dest_tenant.security_groups['default'],
John Warren456d9ae2016-01-12 15:36:33 -0500418 sec_group_rules_client=sec_group_rules_client,
Yair Fried4d7efa62013-11-17 17:12:29 +0200419 **ruleset
420 )
Yair Friedbf2e2c42014-01-28 12:06:38 +0200421 access_point_ssh = self._connect_to_access_point(source_tenant)
422 ip = self._get_server_ip(dest_tenant.access_point,
423 floating=self.floating_ip_access)
424 self._check_connectivity(access_point_ssh, ip)
Yair Fried4d7efa62013-11-17 17:12:29 +0200425
Yair Friedbf2e2c42014-01-28 12:06:38 +0200426 # test that reverse traffic is still blocked
427 self._test_cross_tenant_block(dest_tenant, source_tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200428
Yair Friedbf2e2c42014-01-28 12:06:38 +0200429 # allow reverse traffic and check
John Warren456d9ae2016-01-12 15:36:33 -0500430 sec_group_rules_client = (
431 source_tenant.manager.security_group_rules_client)
Matthew Treinishb7144eb2013-12-13 22:57:35 +0000432 self._create_security_group_rule(
Yair Friedbf2e2c42014-01-28 12:06:38 +0200433 secgroup=source_tenant.security_groups['default'],
John Warren456d9ae2016-01-12 15:36:33 -0500434 sec_group_rules_client=sec_group_rules_client,
Yair Friedbf2e2c42014-01-28 12:06:38 +0200435 **ruleset
436 )
Yair Fried4d7efa62013-11-17 17:12:29 +0200437
Yair Friedbf2e2c42014-01-28 12:06:38 +0200438 access_point_ssh_2 = self._connect_to_access_point(dest_tenant)
439 ip = self._get_server_ip(source_tenant.access_point,
440 floating=self.floating_ip_access)
441 self._check_connectivity(access_point_ssh_2, ip)
Yair Fried4d7efa62013-11-17 17:12:29 +0200442
443 def _verify_mac_addr(self, tenant):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000444 """Verify that VM has the same ip, mac as listed in port"""
445
Yair Fried4d7efa62013-11-17 17:12:29 +0200446 access_point_ssh = self._connect_to_access_point(tenant)
447 mac_addr = access_point_ssh.get_mac_address()
448 mac_addr = mac_addr.strip().lower()
Henry Gessau78ab4b02014-03-31 15:10:13 -0400449 # Get the fixed_ips and mac_address fields of all ports. Select
450 # only those two columns to reduce the size of the response.
Yair Frieddb6c9e92014-08-06 08:53:13 +0300451 port_list = self._list_ports(fields=['fixed_ips', 'mac_address'])
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
Chris Hoge7579c1a2015-02-26 14:12:15 -0800462 @test.idempotent_id('e79f879e-debb-440c-a7e4-efeda05b6848')
Masayuki Igawa4ded9f02014-02-17 15:05:59 +0900463 @test.services('compute', 'network')
Yair Fried4d7efa62013-11-17 17:12:29 +0200464 def test_cross_tenant_traffic(self):
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100465 if not self.credentials_provider.is_multi_tenant():
Yair Fried79b0a912014-10-20 11:15:37 +0300466 raise self.skipException("No secondary tenant defined")
Nachi Ueno26b4c972014-01-17 06:15:13 -0800467 try:
Sean Dagueed6e5862016-04-04 10:49:13 -0400468 # deploy new project
Yair Friedbf2e2c42014-01-28 12:06:38 +0200469 self._deploy_tenant(self.alt_tenant)
470 self._verify_network_details(self.alt_tenant)
471 self._verify_mac_addr(self.alt_tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200472
Nachi Ueno26b4c972014-01-17 06:15:13 -0800473 # cross tenant check
Yair Friedbf2e2c42014-01-28 12:06:38 +0200474 source_tenant = self.primary_tenant
Nachi Ueno26b4c972014-01-17 06:15:13 -0800475 dest_tenant = self.alt_tenant
476 self._test_cross_tenant_block(source_tenant, dest_tenant)
477 self._test_cross_tenant_allow(source_tenant, dest_tenant)
478 except Exception:
Yair Friedbf2e2c42014-01-28 12:06:38 +0200479 for tenant in self.tenants.values():
480 self._log_console_output(servers=tenant.servers)
481 raise
482
Chris Hoge7579c1a2015-02-26 14:12:15 -0800483 @test.idempotent_id('63163892-bbf6-4249-aa12-d5ea1f8f421b')
Masayuki Igawa4ded9f02014-02-17 15:05:59 +0900484 @test.services('compute', 'network')
Yair Friedbf2e2c42014-01-28 12:06:38 +0200485 def test_in_tenant_traffic(self):
486 try:
487 self._create_tenant_servers(self.primary_tenant, num=1)
488
489 # in-tenant check
490 self._test_in_tenant_block(self.primary_tenant)
491 self._test_in_tenant_allow(self.primary_tenant)
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800492 except Exception:
493 for tenant in self.tenants.values():
494 self._log_console_output(servers=tenant.servers)
495 raise
Yair Friedbf2e2c42014-01-28 12:06:38 +0200496
Chris Hoge7579c1a2015-02-26 14:12:15 -0800497 @test.idempotent_id('f4d556d7-1526-42ad-bafb-6bebf48568f6')
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)
533 self._check_connectivity(access_point=access_point_ssh,
534 ip=self._get_server_ip(server),
535 should_succeed=False)
536 server_id = server['id']
537 port_id = self._list_ports(device_id=server_id)[0]['id']
538
539 # update port with new security group and check connectivity
John Warren49c0fe52015-10-22 12:35:54 -0400540 self.ports_client.update_port(port_id, security_groups=[
Steve Heyman33735f22016-05-24 09:28:08 -0500541 new_tenant.security_groups['new_sg']['id']])
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800542 self._check_connectivity(
543 access_point=access_point_ssh,
544 ip=self._get_server_ip(server))
Yair Friedbf2e2c42014-01-28 12:06:38 +0200545 except Exception:
546 for tenant in self.tenants.values():
547 self._log_console_output(servers=tenant.servers)
Nachi Ueno26b4c972014-01-17 06:15:13 -0800548 raise
prdsilva8b733ad2014-12-09 02:54:49 -0800549
Chris Hoge7579c1a2015-02-26 14:12:15 -0800550 @test.idempotent_id('d2f77418-fcc4-439d-b935-72eca704e293')
prdsilva8b733ad2014-12-09 02:54:49 -0800551 @test.services('compute', 'network')
552 def test_multiple_security_groups(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000553 """Verify multiple security groups and checks that rules
554
prdsilva8b733ad2014-12-09 02:54:49 -0800555 provided in the both the groups is applied onto VM
556 """
557 tenant = self.primary_tenant
558 ip = self._get_server_ip(tenant.access_point,
559 floating=self.floating_ip_access)
lanoux283273b2015-12-04 03:01:54 -0800560 ssh_login = CONF.validation.image_ssh_user
prdsilva8b733ad2014-12-09 02:54:49 -0800561 private_key = tenant.keypair['private_key']
562 self.check_vm_connectivity(ip,
563 should_connect=False)
564 ruleset = dict(
565 protocol='icmp',
566 direction='ingress'
567 )
568 self._create_security_group_rule(
569 secgroup=tenant.security_groups['default'],
570 **ruleset
571 )
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000572 # NOTE: Vm now has 2 security groups one with ssh rule(
573 # already added in setUp() method),and other with icmp rule
574 # (added in the above step).The check_vm_connectivity tests
575 # -that vm ping test is successful
576 # -ssh to vm is successful
prdsilva8b733ad2014-12-09 02:54:49 -0800577 self.check_vm_connectivity(ip,
578 username=ssh_login,
579 private_key=private_key,
580 should_connect=True)
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900581
582 @test.requires_ext(service='network', extension='port-security')
583 @test.idempotent_id('7c811dcc-263b-49a3-92d2-1b4d8405f50c')
584 @test.services('compute', 'network')
585 def test_port_security_disable_security_group(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000586 """Verify the default security group rules is disabled."""
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900587 new_tenant = self.primary_tenant
588
589 # Create server
590 name = 'server-{tenant}-gen-1'.format(
591 tenant=new_tenant.creds.tenant_name
592 )
593 name = data_utils.rand_name(name)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200594 server = self._create_server(name, new_tenant,
595 [new_tenant.security_groups['default']])
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900596
597 access_point_ssh = self._connect_to_access_point(new_tenant)
598 server_id = server['id']
599 port_id = self._list_ports(device_id=server_id)[0]['id']
600
601 # Flip the port's port security and check connectivity
602 try:
John Warren49c0fe52015-10-22 12:35:54 -0400603 self.ports_client.update_port(port_id,
604 port_security_enabled=True,
605 security_groups=[])
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900606 self._check_connectivity(access_point=access_point_ssh,
607 ip=self._get_server_ip(server),
608 should_succeed=False)
609
John Warren49c0fe52015-10-22 12:35:54 -0400610 self.ports_client.update_port(port_id,
611 port_security_enabled=False,
612 security_groups=[])
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900613 self._check_connectivity(
614 access_point=access_point_ssh,
615 ip=self._get_server_ip(server))
616 except Exception:
617 for tenant in self.tenants.values():
618 self._log_console_output(servers=tenant.servers)
619 raise
Markus Zoeller156b5da2016-07-11 18:10:31 +0200620
621 @test.requires_ext(service='network', extension='port-security')
622 @test.idempotent_id('13ccf253-e5ad-424b-9c4a-97b88a026699')
623 @testtools.skipUnless(
624 CONF.compute_feature_enabled.allow_port_security_disabled,
625 'Port security must be enabled.')
Matt Riedemann039b2fe2016-09-15 16:12:24 -0400626 # TODO(mriedem): We shouldn't actually need to check this since neutron
627 # disables the port_security extension by default, but the problem is nova
628 # assumes port_security_enabled=True if it's not set on the network
629 # resource, which will mean nova may attempt to apply a security group on
630 # a port on that network which would fail. This is really a bug in nova.
631 @testtools.skipUnless(
632 CONF.network_feature_enabled.port_security,
633 'Port security must be enabled.')
Markus Zoeller156b5da2016-07-11 18:10:31 +0200634 @test.services('compute', 'network')
635 def test_boot_into_disabled_port_security_network_without_secgroup(self):
636 tenant = self.primary_tenant
637 self._create_tenant_network(tenant, port_security_enabled=False)
638 self.assertFalse(tenant.network['port_security_enabled'])
639 name = data_utils.rand_name('server-smoke')
640 sec_groups = []
641 server = self._create_server(name, tenant, sec_groups)
642 server_id = server['id']
643 ports = self._list_ports(device_id=server_id)
644 self.assertEqual(1, len(ports))
645 for port in ports:
646 self.assertEmpty(port['security_groups'],
647 "Neutron shouldn't even use it's default sec "
648 "group.")