blob: 86185c8590c7f849e6bfc5dc7354a6d4dead3475 [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
Yair Fried4d7efa62013-11-17 17:12:29 +020016
Andrea Frittolif9cde7e2014-02-18 09:57:04 +000017from tempest import clients
Fei Long Wangd39431f2015-05-14 11:30:48 +120018from tempest.common.utils import data_utils
Matthew Treinish6c072292014-01-29 19:15:52 +000019from tempest import config
Yair Fried4d7efa62013-11-17 17:12:29 +020020from tempest.scenario import manager
Masayuki Igawa4ded9f02014-02-17 15:05:59 +090021from tempest import test
Yair Fried4d7efa62013-11-17 17:12:29 +020022
Matthew Treinish6c072292014-01-29 19:15:52 +000023CONF = config.CONF
Yair Friedca5cfb52016-01-04 15:41:55 +020024LOG = log.getLogger(__name__)
Matthew Treinish6c072292014-01-29 19:15:52 +000025
Yair Fried4d7efa62013-11-17 17:12:29 +020026
Andrea Frittoli4971fc82014-09-25 10:22:20 +010027class TestSecurityGroupsBasicOps(manager.NetworkScenarioTest):
Yair Fried4d7efa62013-11-17 17:12:29 +020028
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +000029 """The test suite for security groups
30
Yair Fried4d7efa62013-11-17 17:12:29 +020031 This test suite assumes that Nova has been configured to
32 boot VM's with Neutron-managed networking, and attempts to
33 verify cross tenant connectivity as follows
34
35 ssh:
36 in order to overcome "ip namespace", each tenant has an "access point"
37 VM with floating-ip open to incoming ssh connection allowing network
38 commands (ping/ssh) to be executed from within the
39 tenant-network-namespace
40 Tempest host performs key-based authentication to the ssh server via
41 floating IP address
42
43 connectivity test is done by pinging destination server via source server
44 ssh connection.
45 success - ping returns
46 failure - ping_timeout reached
47
Eran Kurisb5f69782016-04-10 11:48:28 +030048 multi-node:
49 Multi-Node mode is enabled when CONF.compute.min_compute_nodes > 1.
50 Tests connectivity between servers on different compute nodes.
51 When enabled, test will boot each new server to different
52 compute nodes.
53
Yair Fried4d7efa62013-11-17 17:12:29 +020054 setup:
Yair Friedbf2e2c42014-01-28 12:06:38 +020055 for primary tenant:
Yair Fried4d7efa62013-11-17 17:12:29 +020056 1. create a network&subnet
57 2. create a router (if public router isn't configured)
58 3. connect tenant network to public network via router
59 4. create an access point:
60 a. a security group open to incoming ssh connection
61 b. a VM with a floating ip
62 5. create a general empty security group (same as "default", but
63 without rules allowing in-tenant traffic)
Yair Fried4d7efa62013-11-17 17:12:29 +020064
65 tests:
66 1. _verify_network_details
67 2. _verify_mac_addr: for each access point verify that
68 (subnet, fix_ip, mac address) are as defined in the port list
69 3. _test_in_tenant_block: test that in-tenant traffic is disabled
70 without rules allowing it
71 4. _test_in_tenant_allow: test that in-tenant traffic is enabled
72 once an appropriate rule has been created
73 5. _test_cross_tenant_block: test that cross-tenant traffic is disabled
74 without a rule allowing it on destination tenant
75 6. _test_cross_tenant_allow:
76 * test that cross-tenant traffic is enabled once an appropriate
77 rule has been created on destination tenant.
78 * test that reverse traffic is still blocked
Fei Long Wang50131ee2015-02-02 16:58:24 +130079 * test than reverse traffic is enabled once an appropriate rule has
Yair Fried4d7efa62013-11-17 17:12:29 +020080 been created on source tenant
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -080081 7._test_port_update_new_security_group:
82 * test that traffic is blocked with default security group
83 * test that traffic is enabled after updating port with new security
84 group having appropriate rule
prdsilva8b733ad2014-12-09 02:54:49 -080085 8. _test_multiple_security_groups: test multiple security groups can be
86 associated with the vm
Yair Fried4d7efa62013-11-17 17:12:29 +020087
88 assumptions:
Yair Friedbf2e2c42014-01-28 12:06:38 +020089 1. alt_tenant/user existed and is different from primary_tenant/user
Yair Fried4d7efa62013-11-17 17:12:29 +020090 2. Public network is defined and reachable from the Tempest host
91 3. Public router can either be:
92 * defined, in which case all tenants networks can connect directly
93 to it, and cross tenant check will be done on the private IP of the
94 destination tenant
95 or
Fei Long Wang50131ee2015-02-02 16:58:24 +130096 * not defined (empty string), in which case each tenant will have
Yair Fried4d7efa62013-11-17 17:12:29 +020097 its own router connected to the public network
98 """
99
Andrea Frittolib21de6c2015-02-06 20:12:38 +0000100 credentials = ['primary', 'alt', 'admin']
101
Joe Gordon28788b42015-02-25 12:42:37 -0800102 class TenantProperties(object):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000103 """helper class to save tenant details
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000104
Yair Fried4d7efa62013-11-17 17:12:29 +0200105 id
106 credentials
107 network
108 subnet
109 security groups
110 servers
111 access point
Yair Friedbf2e2c42014-01-28 12:06:38 +0200112 """
Yair Fried4d7efa62013-11-17 17:12:29 +0200113
Andrea Frittoli422fbdf2014-03-20 10:05:18 +0000114 def __init__(self, credentials):
Yair Frieddb6c9e92014-08-06 08:53:13 +0300115 self.manager = clients.Manager(credentials)
Andrea Frittoli422fbdf2014-03-20 10:05:18 +0000116 # Credentials from manager are filled with both names and IDs
117 self.creds = self.manager.credentials
Yair Fried4d7efa62013-11-17 17:12:29 +0200118 self.network = None
119 self.subnet = None
120 self.router = None
121 self.security_groups = {}
122 self.servers = list()
123
Yair Friedbf2e2c42014-01-28 12:06:38 +0200124 def set_network(self, network, subnet, router):
Yair Fried4d7efa62013-11-17 17:12:29 +0200125 self.network = network
126 self.subnet = subnet
127 self.router = router
128
Yair Fried4d7efa62013-11-17 17:12:29 +0200129 @classmethod
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000130 def skip_checks(cls):
131 super(TestSecurityGroupsBasicOps, cls).skip_checks()
Yair Frieddb6c9e92014-08-06 08:53:13 +0300132 if CONF.baremetal.driver_enabled:
133 msg = ('Not currently supported by baremetal.')
Yair Frieddb6c9e92014-08-06 08:53:13 +0300134 raise cls.skipException(msg)
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)
Yair Fried4d7efa62013-11-17 17:12:29 +0200147
148 @classmethod
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000149 def setup_credentials(cls):
Yair Fried764610a2014-04-07 12:17:05 +0300150 # Create no network resources for these tests.
151 cls.set_network_resources()
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000152 super(TestSecurityGroupsBasicOps, cls).setup_credentials()
Yair Fried4d7efa62013-11-17 17:12:29 +0200153 # TODO(mnewby) Consider looking up entities as needed instead
154 # of storing them as collections on the class.
Yair Fried79b0a912014-10-20 11:15:37 +0300155
Yair Fried79b0a912014-10-20 11:15:37 +0300156 # Credentials from the manager are filled with both IDs and Names
157 cls.alt_creds = cls.alt_manager.credentials
158
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000159 @classmethod
160 def resource_setup(cls):
161 super(TestSecurityGroupsBasicOps, cls).resource_setup()
Yair Friedca5cfb52016-01-04 15:41:55 +0200162
163 cls.multi_node = CONF.compute.min_compute_nodes > 1 and \
Yair Fried95914122016-03-03 09:14:40 +0200164 test.is_scheduler_filter_enabled("DifferentHostFilter")
Yair Friedca5cfb52016-01-04 15:41:55 +0200165 if cls.multi_node:
166 LOG.info("Working in Multi Node mode")
167 else:
168 LOG.info("Working in Single Node mode")
169
Yair Fried4d7efa62013-11-17 17:12:29 +0200170 cls.floating_ips = {}
171 cls.tenants = {}
Andrea Frittolib21de6c2015-02-06 20:12:38 +0000172 creds = cls.manager.credentials
Andrea Frittoli422fbdf2014-03-20 10:05:18 +0000173 cls.primary_tenant = cls.TenantProperties(creds)
174 cls.alt_tenant = cls.TenantProperties(cls.alt_creds)
Yair Friedbf2e2c42014-01-28 12:06:38 +0200175 for tenant in [cls.primary_tenant, cls.alt_tenant]:
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000176 cls.tenants[tenant.creds.tenant_id] = tenant
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000177
Yair Friedbf2e2c42014-01-28 12:06:38 +0200178 cls.floating_ip_access = not CONF.network.public_router_id
Yair Fried4d7efa62013-11-17 17:12:29 +0200179
Yair Friedbf2e2c42014-01-28 12:06:38 +0200180 def setUp(self):
Yair Friedca5cfb52016-01-04 15:41:55 +0200181 """Set up a single tenant with an accessible server.
182
183 If multi-host is enabled, save created server uuids.
184 """
185 self.servers = []
186
Yair Friedbf2e2c42014-01-28 12:06:38 +0200187 super(TestSecurityGroupsBasicOps, self).setUp()
188 self._deploy_tenant(self.primary_tenant)
189 self._verify_network_details(self.primary_tenant)
190 self._verify_mac_addr(self.primary_tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200191
Yair Frieddb6c9e92014-08-06 08:53:13 +0300192 def _create_tenant_keypairs(self, tenant):
193 keypair = self.create_keypair(tenant.manager.keypairs_client)
194 tenant.keypair = keypair
Yair Fried4d7efa62013-11-17 17:12:29 +0200195
196 def _create_tenant_security_groups(self, tenant):
Yair Fried4d7efa62013-11-17 17:12:29 +0200197 access_sg = self._create_empty_security_group(
198 namestart='secgroup_access-',
Yair Frieddb6c9e92014-08-06 08:53:13 +0300199 tenant_id=tenant.creds.tenant_id,
John Warrenf9606e92015-12-10 12:12:42 -0500200 client=tenant.manager.security_groups_client
Yair Fried4d7efa62013-11-17 17:12:29 +0200201 )
Yair Friedbf2e2c42014-01-28 12:06:38 +0200202
Sean Dagueed6e5862016-04-04 10:49:13 -0400203 # don't use default secgroup since it allows in-project traffic
Yair Fried4d7efa62013-11-17 17:12:29 +0200204 def_sg = self._create_empty_security_group(
205 namestart='secgroup_general-',
Yair Frieddb6c9e92014-08-06 08:53:13 +0300206 tenant_id=tenant.creds.tenant_id,
John Warrenf9606e92015-12-10 12:12:42 -0500207 client=tenant.manager.security_groups_client
Yair Fried4d7efa62013-11-17 17:12:29 +0200208 )
209 tenant.security_groups.update(access=access_sg, default=def_sg)
210 ssh_rule = dict(
211 protocol='tcp',
212 port_range_min=22,
213 port_range_max=22,
214 direction='ingress',
215 )
John Warren456d9ae2016-01-12 15:36:33 -0500216 sec_group_rules_client = tenant.manager.security_group_rules_client
217 self._create_security_group_rule(
218 secgroup=access_sg,
219 sec_group_rules_client=sec_group_rules_client,
220 **ssh_rule)
Yair Fried4d7efa62013-11-17 17:12:29 +0200221
222 def _verify_network_details(self, tenant):
223 # Checks that we see the newly created network/subnet/router via
224 # checking the result of list_[networks,routers,subnets]
225 # Check that (router, subnet) couple exist in port_list
226 seen_nets = self._list_networks()
227 seen_names = [n['name'] for n in seen_nets]
228 seen_ids = [n['id'] for n in seen_nets]
229
Steve Heyman33735f22016-05-24 09:28:08 -0500230 self.assertIn(tenant.network['name'], seen_names)
231 self.assertIn(tenant.network['id'], seen_ids)
Yair Fried4d7efa62013-11-17 17:12:29 +0200232
233 seen_subnets = [(n['id'], n['cidr'], n['network_id'])
234 for n in self._list_subnets()]
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
239 seen_routers = self._list_routers()
240 seen_router_ids = [n['id'] for n in seen_routers]
241 seen_router_names = [n['name'] for n in seen_routers]
242
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'])
Yair Fried4d7efa62013-11-17 17:12:29 +0200247 router_ports = [(i['device_id'], i['fixed_ips'][0]['subnet_id']) for i
Yair Frieddb6c9e92014-08-06 08:53:13 +0300248 in self._list_ports()
armando-migliacciobcfbbeb2014-08-11 18:33:47 -0700249 if self._is_router_port(i)]
Yair Fried4d7efa62013-11-17 17:12:29 +0200250
251 self.assertIn(myport, router_ports)
252
armando-migliacciobcfbbeb2014-08-11 18:33:47 -0700253 def _is_router_port(self, port):
254 """Return True if port is a router interface."""
255 # NOTE(armando-migliaccio): match device owner for both centralized
256 # and distributed routers; 'device_owner' is "" by default.
257 return port['device_owner'].startswith('network:router_interface')
258
Yair Friedca5cfb52016-01-04 15:41:55 +0200259 def _create_server(self, name, tenant, security_groups=None, **kwargs):
260 """Creates a server and assigns it to security group.
261
262 If multi-host is enabled, Ensures servers are created on different
263 compute nodes, by storing created servers' ids and uses different_host
264 as scheduler_hints on creation.
265 Validates servers are created as requested, using admin client.
266 """
Yair Fried4d7efa62013-11-17 17:12:29 +0200267 if security_groups is None:
Yair Frieddb6c9e92014-08-06 08:53:13 +0300268 security_groups = [tenant.security_groups['default']]
Ken'ichi Ohmichi1b3461e2014-12-02 03:41:07 +0000269 security_groups_names = [{'name': s['name']} for s in security_groups]
Yair Friedca5cfb52016-01-04 15:41:55 +0200270 if self.multi_node:
271 kwargs["scheduler_hints"] = {'different_host': self.servers}
Ken'ichi Ohmichif2d436e2015-09-03 01:13:16 +0000272 server = self.create_server(
273 name=name,
Steve Heyman33735f22016-05-24 09:28:08 -0500274 networks=[{'uuid': tenant.network["id"]}],
lanoux5fc14522015-09-21 08:17:35 +0000275 key_name=tenant.keypair['name'],
276 security_groups=security_groups_names,
277 wait_until='ACTIVE',
Yair Friedca5cfb52016-01-04 15:41:55 +0200278 clients=tenant.manager,
279 **kwargs)
Claudiu Belufaa98912014-09-01 16:50:28 +0300280 self.assertEqual(
281 sorted([s['name'] for s in security_groups]),
282 sorted([s['name'] for s in server['security_groups']]))
Yair Friedca5cfb52016-01-04 15:41:55 +0200283
284 # Verify servers are on different compute nodes
285 if self.multi_node:
286 adm_get_server = self.admin_manager.servers_client.show_server
287 new_host = adm_get_server(server["id"])["server"][
288 "OS-EXT-SRV-ATTR:host"]
289 host_list = [adm_get_server(s)["server"]["OS-EXT-SRV-ATTR:host"]
290 for s in self.servers]
291 self.assertNotIn(new_host, host_list,
292 message="Failed to boot servers on different "
293 "Compute nodes.")
294
295 self.servers.append(server["id"])
296
Claudiu Belufaa98912014-09-01 16:50:28 +0300297 return server
Yair Fried4d7efa62013-11-17 17:12:29 +0200298
299 def _create_tenant_servers(self, tenant, num=1):
300 for i in range(num):
Ken'ichi Ohmichi6ded8df2015-03-23 02:00:19 +0000301 name = 'server-{tenant}-gen-{num}'.format(
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000302 tenant=tenant.creds.tenant_name,
Yair Fried4d7efa62013-11-17 17:12:29 +0200303 num=i
304 )
305 name = data_utils.rand_name(name)
306 server = self._create_server(name, tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200307 tenant.servers.append(server)
308
309 def _set_access_point(self, tenant):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000310 # creates a server in a secgroup with rule allowing external ssh
Sean Dagueed6e5862016-04-04 10:49:13 -0400311 # in order to access project internal network
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000312 # workaround ip namespace
Yair Frieddb6c9e92014-08-06 08:53:13 +0300313 secgroups = tenant.security_groups.values()
Ken'ichi Ohmichi6ded8df2015-03-23 02:00:19 +0000314 name = 'server-{tenant}-access_point'.format(
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000315 tenant=tenant.creds.tenant_name)
Yair Fried4d7efa62013-11-17 17:12:29 +0200316 name = data_utils.rand_name(name)
317 server = self._create_server(name, tenant,
318 security_groups=secgroups)
Yair Fried4d7efa62013-11-17 17:12:29 +0200319 tenant.access_point = server
Yair Frieddb6c9e92014-08-06 08:53:13 +0300320 self._assign_floating_ips(tenant, server)
Yair Fried4d7efa62013-11-17 17:12:29 +0200321
Yair Frieddb6c9e92014-08-06 08:53:13 +0300322 def _assign_floating_ips(self, tenant, server):
Matthew Treinish6c072292014-01-29 19:15:52 +0000323 public_network_id = CONF.network.public_network_id
Yair Friedae0e73d2014-11-24 11:56:26 +0200324 floating_ip = self.create_floating_ip(
Yair Frieddb6c9e92014-08-06 08:53:13 +0300325 server, public_network_id,
John Warrenfbf2a892015-11-17 12:36:14 -0500326 client=tenant.manager.floating_ips_client)
Yair Frieddb6c9e92014-08-06 08:53:13 +0300327 self.floating_ips.setdefault(server['id'], floating_ip)
Yair Fried4d7efa62013-11-17 17:12:29 +0200328
329 def _create_tenant_network(self, tenant):
Yair Frieddb6c9e92014-08-06 08:53:13 +0300330 network, subnet, router = self.create_networks(
John Warren3961acd2015-10-02 14:38:53 -0400331 networks_client=tenant.manager.networks_client,
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000332 routers_client=tenant.manager.routers_client,
John Warren3961acd2015-10-02 14:38:53 -0400333 subnets_client=tenant.manager.subnets_client)
Yair Friedbf2e2c42014-01-28 12:06:38 +0200334 tenant.set_network(network, subnet, router)
Yair Fried4d7efa62013-11-17 17:12:29 +0200335
Yair Fried4d7efa62013-11-17 17:12:29 +0200336 def _deploy_tenant(self, tenant_or_id):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000337 """creates:
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000338
Yair Fried4d7efa62013-11-17 17:12:29 +0200339 network
340 subnet
341 router (if public not defined)
342 access security group
343 access-point server
Yair Fried4d7efa62013-11-17 17:12:29 +0200344 """
345 if not isinstance(tenant_or_id, self.TenantProperties):
346 tenant = self.tenants[tenant_or_id]
Yair Fried4d7efa62013-11-17 17:12:29 +0200347 else:
348 tenant = tenant_or_id
Yair Frieddb6c9e92014-08-06 08:53:13 +0300349 self._create_tenant_keypairs(tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200350 self._create_tenant_network(tenant)
351 self._create_tenant_security_groups(tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200352 self._set_access_point(tenant)
353
354 def _get_server_ip(self, server, floating=False):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000355 """returns the ip (floating/internal) of a server"""
Yair Fried4d7efa62013-11-17 17:12:29 +0200356 if floating:
Steve Heyman33735f22016-05-24 09:28:08 -0500357 server_ip = self.floating_ips[server['id']]['floating_ip_address']
Yair Fried4d7efa62013-11-17 17:12:29 +0200358 else:
armando-migliacciod03f2642014-02-21 19:55:50 -0800359 server_ip = None
Steve Heyman33735f22016-05-24 09:28:08 -0500360 network_name = self.tenants[server['tenant_id']].network['name']
Yair Frieddb6c9e92014-08-06 08:53:13 +0300361 if network_name in server['addresses']:
362 server_ip = server['addresses'][network_name][0]['addr']
armando-migliacciod03f2642014-02-21 19:55:50 -0800363 return server_ip
Yair Fried4d7efa62013-11-17 17:12:29 +0200364
365 def _connect_to_access_point(self, tenant):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000366 """create ssh connection to tenant access point"""
Yair Fried4d7efa62013-11-17 17:12:29 +0200367 access_point_ssh = \
Steve Heyman33735f22016-05-24 09:28:08 -0500368 self.floating_ips[tenant.access_point['id']]['floating_ip_address']
Yair Frieddb6c9e92014-08-06 08:53:13 +0300369 private_key = tenant.keypair['private_key']
Jordan Pittierbbb17122016-01-26 17:10:55 +0100370 access_point_ssh = self.get_remote_client(
371 access_point_ssh, private_key=private_key)
Yair Fried4d7efa62013-11-17 17:12:29 +0200372 return access_point_ssh
373
Yair Fried4d7efa62013-11-17 17:12:29 +0200374 def _check_connectivity(self, access_point, ip, should_succeed=True):
375 if should_succeed:
376 msg = "Timed out waiting for %s to become reachable" % ip
377 else:
Yair Fried4d7efa62013-11-17 17:12:29 +0200378 msg = "%s is reachable" % ip
Matthew Treinish53483132014-12-09 18:50:06 -0500379 self.assertTrue(self._check_remote_connectivity(access_point, ip,
380 should_succeed), msg)
Yair Fried4d7efa62013-11-17 17:12:29 +0200381
382 def _test_in_tenant_block(self, tenant):
383 access_point_ssh = self._connect_to_access_point(tenant)
384 for server in tenant.servers:
385 self._check_connectivity(access_point=access_point_ssh,
386 ip=self._get_server_ip(server),
387 should_succeed=False)
388
389 def _test_in_tenant_allow(self, tenant):
390 ruleset = dict(
391 protocol='icmp',
Steve Heyman33735f22016-05-24 09:28:08 -0500392 remote_group_id=tenant.security_groups['default']['id'],
Yair Fried4d7efa62013-11-17 17:12:29 +0200393 direction='ingress'
394 )
Matthew Treinishb7144eb2013-12-13 22:57:35 +0000395 self._create_security_group_rule(
Yair Fried4d7efa62013-11-17 17:12:29 +0200396 secgroup=tenant.security_groups['default'],
Yair Friedca5cfb52016-01-04 15:41:55 +0200397 security_groups_client=tenant.manager.security_groups_client,
Yair Fried4d7efa62013-11-17 17:12:29 +0200398 **ruleset
399 )
400 access_point_ssh = self._connect_to_access_point(tenant)
401 for server in tenant.servers:
402 self._check_connectivity(access_point=access_point_ssh,
403 ip=self._get_server_ip(server))
Yair Fried4d7efa62013-11-17 17:12:29 +0200404
405 def _test_cross_tenant_block(self, source_tenant, dest_tenant):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000406 # if public router isn't defined, then dest_tenant access is via
407 # floating-ip
Yair Fried4d7efa62013-11-17 17:12:29 +0200408 access_point_ssh = self._connect_to_access_point(source_tenant)
409 ip = self._get_server_ip(dest_tenant.access_point,
410 floating=self.floating_ip_access)
411 self._check_connectivity(access_point=access_point_ssh, ip=ip,
412 should_succeed=False)
413
414 def _test_cross_tenant_allow(self, source_tenant, dest_tenant):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000415 """check for each direction:
416
Yair Fried4d7efa62013-11-17 17:12:29 +0200417 creating rule for tenant incoming traffic enables only 1way traffic
Yair Friedbf2e2c42014-01-28 12:06:38 +0200418 """
Yair Fried4d7efa62013-11-17 17:12:29 +0200419 ruleset = dict(
420 protocol='icmp',
421 direction='ingress'
422 )
John Warren456d9ae2016-01-12 15:36:33 -0500423 sec_group_rules_client = (
424 dest_tenant.manager.security_group_rules_client)
Matthew Treinishb7144eb2013-12-13 22:57:35 +0000425 self._create_security_group_rule(
Yair Fried4d7efa62013-11-17 17:12:29 +0200426 secgroup=dest_tenant.security_groups['default'],
John Warren456d9ae2016-01-12 15:36:33 -0500427 sec_group_rules_client=sec_group_rules_client,
Yair Fried4d7efa62013-11-17 17:12:29 +0200428 **ruleset
429 )
Yair Friedbf2e2c42014-01-28 12:06:38 +0200430 access_point_ssh = self._connect_to_access_point(source_tenant)
431 ip = self._get_server_ip(dest_tenant.access_point,
432 floating=self.floating_ip_access)
433 self._check_connectivity(access_point_ssh, ip)
Yair Fried4d7efa62013-11-17 17:12:29 +0200434
Yair Friedbf2e2c42014-01-28 12:06:38 +0200435 # test that reverse traffic is still blocked
436 self._test_cross_tenant_block(dest_tenant, source_tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200437
Yair Friedbf2e2c42014-01-28 12:06:38 +0200438 # allow reverse traffic and check
John Warren456d9ae2016-01-12 15:36:33 -0500439 sec_group_rules_client = (
440 source_tenant.manager.security_group_rules_client)
Matthew Treinishb7144eb2013-12-13 22:57:35 +0000441 self._create_security_group_rule(
Yair Friedbf2e2c42014-01-28 12:06:38 +0200442 secgroup=source_tenant.security_groups['default'],
John Warren456d9ae2016-01-12 15:36:33 -0500443 sec_group_rules_client=sec_group_rules_client,
Yair Friedbf2e2c42014-01-28 12:06:38 +0200444 **ruleset
445 )
Yair Fried4d7efa62013-11-17 17:12:29 +0200446
Yair Friedbf2e2c42014-01-28 12:06:38 +0200447 access_point_ssh_2 = self._connect_to_access_point(dest_tenant)
448 ip = self._get_server_ip(source_tenant.access_point,
449 floating=self.floating_ip_access)
450 self._check_connectivity(access_point_ssh_2, ip)
Yair Fried4d7efa62013-11-17 17:12:29 +0200451
452 def _verify_mac_addr(self, tenant):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000453 """Verify that VM has the same ip, mac as listed in port"""
454
Yair Fried4d7efa62013-11-17 17:12:29 +0200455 access_point_ssh = self._connect_to_access_point(tenant)
456 mac_addr = access_point_ssh.get_mac_address()
457 mac_addr = mac_addr.strip().lower()
Henry Gessau78ab4b02014-03-31 15:10:13 -0400458 # Get the fixed_ips and mac_address fields of all ports. Select
459 # only those two columns to reduce the size of the response.
Yair Frieddb6c9e92014-08-06 08:53:13 +0300460 port_list = self._list_ports(fields=['fixed_ips', 'mac_address'])
Yair Fried4d7efa62013-11-17 17:12:29 +0200461 port_detail_list = [
462 (port['fixed_ips'][0]['subnet_id'],
463 port['fixed_ips'][0]['ip_address'],
Henry Gessau78ab4b02014-03-31 15:10:13 -0400464 port['mac_address'].lower())
465 for port in port_list if port['fixed_ips']
Yair Fried4d7efa62013-11-17 17:12:29 +0200466 ]
467 server_ip = self._get_server_ip(tenant.access_point)
Steve Heyman33735f22016-05-24 09:28:08 -0500468 subnet_id = tenant.subnet['id']
Yair Fried4d7efa62013-11-17 17:12:29 +0200469 self.assertIn((subnet_id, server_ip, mac_addr), port_detail_list)
470
Chris Hoge7579c1a2015-02-26 14:12:15 -0800471 @test.idempotent_id('e79f879e-debb-440c-a7e4-efeda05b6848')
Masayuki Igawa4ded9f02014-02-17 15:05:59 +0900472 @test.services('compute', 'network')
Yair Fried4d7efa62013-11-17 17:12:29 +0200473 def test_cross_tenant_traffic(self):
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100474 if not self.credentials_provider.is_multi_tenant():
Yair Fried79b0a912014-10-20 11:15:37 +0300475 raise self.skipException("No secondary tenant defined")
Nachi Ueno26b4c972014-01-17 06:15:13 -0800476 try:
Sean Dagueed6e5862016-04-04 10:49:13 -0400477 # deploy new project
Yair Friedbf2e2c42014-01-28 12:06:38 +0200478 self._deploy_tenant(self.alt_tenant)
479 self._verify_network_details(self.alt_tenant)
480 self._verify_mac_addr(self.alt_tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200481
Nachi Ueno26b4c972014-01-17 06:15:13 -0800482 # cross tenant check
Yair Friedbf2e2c42014-01-28 12:06:38 +0200483 source_tenant = self.primary_tenant
Nachi Ueno26b4c972014-01-17 06:15:13 -0800484 dest_tenant = self.alt_tenant
485 self._test_cross_tenant_block(source_tenant, dest_tenant)
486 self._test_cross_tenant_allow(source_tenant, dest_tenant)
487 except Exception:
Yair Friedbf2e2c42014-01-28 12:06:38 +0200488 for tenant in self.tenants.values():
489 self._log_console_output(servers=tenant.servers)
490 raise
491
Chris Hoge7579c1a2015-02-26 14:12:15 -0800492 @test.idempotent_id('63163892-bbf6-4249-aa12-d5ea1f8f421b')
Masayuki Igawa4ded9f02014-02-17 15:05:59 +0900493 @test.services('compute', 'network')
Yair Friedbf2e2c42014-01-28 12:06:38 +0200494 def test_in_tenant_traffic(self):
495 try:
496 self._create_tenant_servers(self.primary_tenant, num=1)
497
498 # in-tenant check
499 self._test_in_tenant_block(self.primary_tenant)
500 self._test_in_tenant_allow(self.primary_tenant)
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800501 except Exception:
502 for tenant in self.tenants.values():
503 self._log_console_output(servers=tenant.servers)
504 raise
Yair Friedbf2e2c42014-01-28 12:06:38 +0200505
Chris Hoge7579c1a2015-02-26 14:12:15 -0800506 @test.idempotent_id('f4d556d7-1526-42ad-bafb-6bebf48568f6')
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800507 @test.services('compute', 'network')
508 def test_port_update_new_security_group(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000509 """Verifies the traffic after updating the vm port
510
511 With new security group having appropriate rule.
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800512 """
513 new_tenant = self.primary_tenant
514
515 # Create empty security group and add icmp rule in it
516 new_sg = self._create_empty_security_group(
517 namestart='secgroup_new-',
518 tenant_id=new_tenant.creds.tenant_id,
John Warrenf9606e92015-12-10 12:12:42 -0500519 client=new_tenant.manager.security_groups_client)
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800520 icmp_rule = dict(
521 protocol='icmp',
522 direction='ingress',
523 )
John Warren456d9ae2016-01-12 15:36:33 -0500524 sec_group_rules_client = new_tenant.manager.security_group_rules_client
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800525 self._create_security_group_rule(
526 secgroup=new_sg,
John Warren456d9ae2016-01-12 15:36:33 -0500527 sec_group_rules_client=sec_group_rules_client,
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800528 **icmp_rule)
529 new_tenant.security_groups.update(new_sg=new_sg)
530
531 # Create server with default security group
Ken'ichi Ohmichi6ded8df2015-03-23 02:00:19 +0000532 name = 'server-{tenant}-gen-1'.format(
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800533 tenant=new_tenant.creds.tenant_name
534 )
535 name = data_utils.rand_name(name)
536 server = self._create_server(name, new_tenant)
537
538 # Check connectivity failure with default security group
539 try:
540 access_point_ssh = self._connect_to_access_point(new_tenant)
541 self._check_connectivity(access_point=access_point_ssh,
542 ip=self._get_server_ip(server),
543 should_succeed=False)
544 server_id = server['id']
545 port_id = self._list_ports(device_id=server_id)[0]['id']
546
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']])
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800550 self._check_connectivity(
551 access_point=access_point_ssh,
552 ip=self._get_server_ip(server))
Yair Friedbf2e2c42014-01-28 12:06:38 +0200553 except Exception:
554 for tenant in self.tenants.values():
555 self._log_console_output(servers=tenant.servers)
Nachi Ueno26b4c972014-01-17 06:15:13 -0800556 raise
prdsilva8b733ad2014-12-09 02:54:49 -0800557
Chris Hoge7579c1a2015-02-26 14:12:15 -0800558 @test.idempotent_id('d2f77418-fcc4-439d-b935-72eca704e293')
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
590 @test.requires_ext(service='network', extension='port-security')
591 @test.idempotent_id('7c811dcc-263b-49a3-92d2-1b4d8405f50c')
592 @test.services('compute', 'network')
593 def test_port_security_disable_security_group(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000594 """Verify the default security group rules is disabled."""
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900595 new_tenant = self.primary_tenant
596
597 # Create server
598 name = 'server-{tenant}-gen-1'.format(
599 tenant=new_tenant.creds.tenant_name
600 )
601 name = data_utils.rand_name(name)
602 server = self._create_server(name, new_tenant)
603
604 access_point_ssh = self._connect_to_access_point(new_tenant)
605 server_id = server['id']
606 port_id = self._list_ports(device_id=server_id)[0]['id']
607
608 # Flip the port's port security and check connectivity
609 try:
John Warren49c0fe52015-10-22 12:35:54 -0400610 self.ports_client.update_port(port_id,
611 port_security_enabled=True,
612 security_groups=[])
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900613 self._check_connectivity(access_point=access_point_ssh,
614 ip=self._get_server_ip(server),
615 should_succeed=False)
616
John Warren49c0fe52015-10-22 12:35:54 -0400617 self.ports_client.update_port(port_id,
618 port_security_enabled=False,
619 security_groups=[])
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900620 self._check_connectivity(
621 access_point=access_point_ssh,
622 ip=self._get_server_ip(server))
623 except Exception:
624 for tenant in self.tenants.values():
625 self._log_console_output(servers=tenant.servers)
626 raise