blob: 1360b09e46f3c378775145197fdc6c7729a203a9 [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()
Yair Frieddb6c9e92014-08-06 08:53:13 +0300133 if CONF.baremetal.driver_enabled:
134 msg = ('Not currently supported by baremetal.')
Yair Frieddb6c9e92014-08-06 08:53:13 +0300135 raise cls.skipException(msg)
Itzik Brown06952672015-03-29 12:38:58 +0300136 if CONF.network.port_vnic_type in ['direct', 'macvtap']:
137 msg = ('Not currently supported when using vnic_type'
138 ' direct or macvtap')
139 raise cls.skipException(msg)
Sean Dagueed6e5862016-04-04 10:49:13 -0400140 if not (CONF.network.project_networks_reachable or
Matthew Treinish6c072292014-01-29 19:15:52 +0000141 CONF.network.public_network_id):
Sean Dagueed6e5862016-04-04 10:49:13 -0400142 msg = ('Either project_networks_reachable must be "true", or '
Yair Fried4d7efa62013-11-17 17:12:29 +0200143 'public_network_id must be defined.')
Yair Fried4d7efa62013-11-17 17:12:29 +0200144 raise cls.skipException(msg)
Bence Romsics41f3f852016-01-11 13:48:23 +0100145 if not test.is_extension_enabled('security-group', 'network'):
146 msg = "security-group extension not enabled."
147 raise cls.skipException(msg)
Yair Fried4d7efa62013-11-17 17:12:29 +0200148
149 @classmethod
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000150 def setup_credentials(cls):
Yair Fried764610a2014-04-07 12:17:05 +0300151 # Create no network resources for these tests.
152 cls.set_network_resources()
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000153 super(TestSecurityGroupsBasicOps, cls).setup_credentials()
Yair Fried79b0a912014-10-20 11:15:37 +0300154
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000155 @classmethod
156 def resource_setup(cls):
157 super(TestSecurityGroupsBasicOps, cls).resource_setup()
Yair Friedca5cfb52016-01-04 15:41:55 +0200158
159 cls.multi_node = CONF.compute.min_compute_nodes > 1 and \
Yair Fried95914122016-03-03 09:14:40 +0200160 test.is_scheduler_filter_enabled("DifferentHostFilter")
Yair Friedca5cfb52016-01-04 15:41:55 +0200161 if cls.multi_node:
162 LOG.info("Working in Multi Node mode")
163 else:
164 LOG.info("Working in Single Node mode")
165
Yair Fried4d7efa62013-11-17 17:12:29 +0200166 cls.floating_ips = {}
167 cls.tenants = {}
Andrea Frittoli73224672016-12-09 21:08:19 +0000168 cls.primary_tenant = cls.TenantProperties(cls.os)
169 cls.alt_tenant = cls.TenantProperties(cls.os_alt)
Yair Friedbf2e2c42014-01-28 12:06:38 +0200170 for tenant in [cls.primary_tenant, cls.alt_tenant]:
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000171 cls.tenants[tenant.creds.tenant_id] = tenant
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +0000172
Yair Friedbf2e2c42014-01-28 12:06:38 +0200173 cls.floating_ip_access = not CONF.network.public_router_id
Yair Fried4d7efa62013-11-17 17:12:29 +0200174
Yair Friedbf2e2c42014-01-28 12:06:38 +0200175 def setUp(self):
Yair Friedca5cfb52016-01-04 15:41:55 +0200176 """Set up a single tenant with an accessible server.
177
178 If multi-host is enabled, save created server uuids.
179 """
180 self.servers = []
181
Yair Friedbf2e2c42014-01-28 12:06:38 +0200182 super(TestSecurityGroupsBasicOps, self).setUp()
183 self._deploy_tenant(self.primary_tenant)
184 self._verify_network_details(self.primary_tenant)
185 self._verify_mac_addr(self.primary_tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200186
Yair Frieddb6c9e92014-08-06 08:53:13 +0300187 def _create_tenant_keypairs(self, tenant):
188 keypair = self.create_keypair(tenant.manager.keypairs_client)
189 tenant.keypair = keypair
Yair Fried4d7efa62013-11-17 17:12:29 +0200190
191 def _create_tenant_security_groups(self, tenant):
Yair Fried4d7efa62013-11-17 17:12:29 +0200192 access_sg = self._create_empty_security_group(
193 namestart='secgroup_access-',
Yair Frieddb6c9e92014-08-06 08:53:13 +0300194 tenant_id=tenant.creds.tenant_id,
John Warrenf9606e92015-12-10 12:12:42 -0500195 client=tenant.manager.security_groups_client
Yair Fried4d7efa62013-11-17 17:12:29 +0200196 )
Yair Friedbf2e2c42014-01-28 12:06:38 +0200197
Sean Dagueed6e5862016-04-04 10:49:13 -0400198 # don't use default secgroup since it allows in-project traffic
Yair Fried4d7efa62013-11-17 17:12:29 +0200199 def_sg = self._create_empty_security_group(
200 namestart='secgroup_general-',
Yair Frieddb6c9e92014-08-06 08:53:13 +0300201 tenant_id=tenant.creds.tenant_id,
John Warrenf9606e92015-12-10 12:12:42 -0500202 client=tenant.manager.security_groups_client
Yair Fried4d7efa62013-11-17 17:12:29 +0200203 )
204 tenant.security_groups.update(access=access_sg, default=def_sg)
205 ssh_rule = dict(
206 protocol='tcp',
207 port_range_min=22,
208 port_range_max=22,
209 direction='ingress',
210 )
John Warren456d9ae2016-01-12 15:36:33 -0500211 sec_group_rules_client = tenant.manager.security_group_rules_client
212 self._create_security_group_rule(
213 secgroup=access_sg,
214 sec_group_rules_client=sec_group_rules_client,
215 **ssh_rule)
Yair Fried4d7efa62013-11-17 17:12:29 +0200216
217 def _verify_network_details(self, tenant):
218 # Checks that we see the newly created network/subnet/router via
219 # checking the result of list_[networks,routers,subnets]
220 # Check that (router, subnet) couple exist in port_list
221 seen_nets = self._list_networks()
222 seen_names = [n['name'] for n in seen_nets]
223 seen_ids = [n['id'] for n in seen_nets]
224
Steve Heyman33735f22016-05-24 09:28:08 -0500225 self.assertIn(tenant.network['name'], seen_names)
226 self.assertIn(tenant.network['id'], seen_ids)
Yair Fried4d7efa62013-11-17 17:12:29 +0200227
228 seen_subnets = [(n['id'], n['cidr'], n['network_id'])
229 for n in self._list_subnets()]
Steve Heyman33735f22016-05-24 09:28:08 -0500230 mysubnet = (tenant.subnet['id'], tenant.subnet['cidr'],
231 tenant.network['id'])
Yair Fried4d7efa62013-11-17 17:12:29 +0200232 self.assertIn(mysubnet, seen_subnets)
233
234 seen_routers = self._list_routers()
235 seen_router_ids = [n['id'] for n in seen_routers]
236 seen_router_names = [n['name'] for n in seen_routers]
237
Steve Heyman33735f22016-05-24 09:28:08 -0500238 self.assertIn(tenant.router['name'], seen_router_names)
239 self.assertIn(tenant.router['id'], seen_router_ids)
Yair Fried4d7efa62013-11-17 17:12:29 +0200240
Steve Heyman33735f22016-05-24 09:28:08 -0500241 myport = (tenant.router['id'], tenant.subnet['id'])
Yair Fried4d7efa62013-11-17 17:12:29 +0200242 router_ports = [(i['device_id'], i['fixed_ips'][0]['subnet_id']) for i
Yair Frieddb6c9e92014-08-06 08:53:13 +0300243 in self._list_ports()
Attila Fazekasd7e08a62016-10-07 13:05:05 +0200244 if net_info.is_router_interface_port(i)]
Yair Fried4d7efa62013-11-17 17:12:29 +0200245
246 self.assertIn(myport, router_ports)
247
Markus Zoeller156b5da2016-07-11 18:10:31 +0200248 def _create_server(self, name, tenant, security_groups, **kwargs):
Yair Friedca5cfb52016-01-04 15:41:55 +0200249 """Creates a server and assigns it to security group.
250
251 If multi-host is enabled, Ensures servers are created on different
252 compute nodes, by storing created servers' ids and uses different_host
253 as scheduler_hints on creation.
254 Validates servers are created as requested, using admin client.
255 """
Ken'ichi Ohmichi1b3461e2014-12-02 03:41:07 +0000256 security_groups_names = [{'name': s['name']} for s in security_groups]
Yair Friedca5cfb52016-01-04 15:41:55 +0200257 if self.multi_node:
258 kwargs["scheduler_hints"] = {'different_host': self.servers}
Ken'ichi Ohmichif2d436e2015-09-03 01:13:16 +0000259 server = self.create_server(
260 name=name,
Steve Heyman33735f22016-05-24 09:28:08 -0500261 networks=[{'uuid': tenant.network["id"]}],
lanoux5fc14522015-09-21 08:17:35 +0000262 key_name=tenant.keypair['name'],
263 security_groups=security_groups_names,
264 wait_until='ACTIVE',
Yair Friedca5cfb52016-01-04 15:41:55 +0200265 clients=tenant.manager,
266 **kwargs)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200267 if 'security_groups' in server:
268 self.assertEqual(
269 sorted([s['name'] for s in security_groups]),
270 sorted([s['name'] for s in server['security_groups']]))
Yair Friedca5cfb52016-01-04 15:41:55 +0200271
272 # Verify servers are on different compute nodes
273 if self.multi_node:
274 adm_get_server = self.admin_manager.servers_client.show_server
275 new_host = adm_get_server(server["id"])["server"][
276 "OS-EXT-SRV-ATTR:host"]
277 host_list = [adm_get_server(s)["server"]["OS-EXT-SRV-ATTR:host"]
278 for s in self.servers]
279 self.assertNotIn(new_host, host_list,
280 message="Failed to boot servers on different "
281 "Compute nodes.")
282
283 self.servers.append(server["id"])
284
Claudiu Belufaa98912014-09-01 16:50:28 +0300285 return server
Yair Fried4d7efa62013-11-17 17:12:29 +0200286
287 def _create_tenant_servers(self, tenant, num=1):
288 for i in range(num):
Ken'ichi Ohmichi6ded8df2015-03-23 02:00:19 +0000289 name = 'server-{tenant}-gen-{num}'.format(
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000290 tenant=tenant.creds.tenant_name,
Yair Fried4d7efa62013-11-17 17:12:29 +0200291 num=i
292 )
293 name = data_utils.rand_name(name)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200294 server = self._create_server(name, tenant,
295 [tenant.security_groups['default']])
Yair Fried4d7efa62013-11-17 17:12:29 +0200296 tenant.servers.append(server)
297
298 def _set_access_point(self, tenant):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000299 # creates a server in a secgroup with rule allowing external ssh
Sean Dagueed6e5862016-04-04 10:49:13 -0400300 # in order to access project internal network
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000301 # workaround ip namespace
Yair Frieddb6c9e92014-08-06 08:53:13 +0300302 secgroups = tenant.security_groups.values()
Ken'ichi Ohmichi6ded8df2015-03-23 02:00:19 +0000303 name = 'server-{tenant}-access_point'.format(
Andrea Frittoli86ad28d2014-03-20 10:09:12 +0000304 tenant=tenant.creds.tenant_name)
Yair Fried4d7efa62013-11-17 17:12:29 +0200305 name = data_utils.rand_name(name)
306 server = self._create_server(name, tenant,
307 security_groups=secgroups)
Yair Fried4d7efa62013-11-17 17:12:29 +0200308 tenant.access_point = server
Yair Frieddb6c9e92014-08-06 08:53:13 +0300309 self._assign_floating_ips(tenant, server)
Yair Fried4d7efa62013-11-17 17:12:29 +0200310
Yair Frieddb6c9e92014-08-06 08:53:13 +0300311 def _assign_floating_ips(self, tenant, server):
Matthew Treinish6c072292014-01-29 19:15:52 +0000312 public_network_id = CONF.network.public_network_id
Yair Friedae0e73d2014-11-24 11:56:26 +0200313 floating_ip = self.create_floating_ip(
Yair Frieddb6c9e92014-08-06 08:53:13 +0300314 server, public_network_id,
John Warrenfbf2a892015-11-17 12:36:14 -0500315 client=tenant.manager.floating_ips_client)
Yair Frieddb6c9e92014-08-06 08:53:13 +0300316 self.floating_ips.setdefault(server['id'], floating_ip)
Yair Fried4d7efa62013-11-17 17:12:29 +0200317
Markus Zoeller156b5da2016-07-11 18:10:31 +0200318 def _create_tenant_network(self, tenant, port_security_enabled=True):
Yair Frieddb6c9e92014-08-06 08:53:13 +0300319 network, subnet, router = self.create_networks(
John Warren3961acd2015-10-02 14:38:53 -0400320 networks_client=tenant.manager.networks_client,
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000321 routers_client=tenant.manager.routers_client,
Markus Zoeller156b5da2016-07-11 18:10:31 +0200322 subnets_client=tenant.manager.subnets_client,
323 port_security_enabled=port_security_enabled)
Yair Friedbf2e2c42014-01-28 12:06:38 +0200324 tenant.set_network(network, subnet, router)
Yair Fried4d7efa62013-11-17 17:12:29 +0200325
Yair Fried4d7efa62013-11-17 17:12:29 +0200326 def _deploy_tenant(self, tenant_or_id):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000327 """creates:
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000328
Yair Fried4d7efa62013-11-17 17:12:29 +0200329 network
330 subnet
331 router (if public not defined)
332 access security group
333 access-point server
Yair Fried4d7efa62013-11-17 17:12:29 +0200334 """
335 if not isinstance(tenant_or_id, self.TenantProperties):
336 tenant = self.tenants[tenant_or_id]
Yair Fried4d7efa62013-11-17 17:12:29 +0200337 else:
338 tenant = tenant_or_id
Yair Frieddb6c9e92014-08-06 08:53:13 +0300339 self._create_tenant_keypairs(tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200340 self._create_tenant_network(tenant)
341 self._create_tenant_security_groups(tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200342 self._set_access_point(tenant)
343
344 def _get_server_ip(self, server, floating=False):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000345 """returns the ip (floating/internal) of a server"""
Yair Fried4d7efa62013-11-17 17:12:29 +0200346 if floating:
Steve Heyman33735f22016-05-24 09:28:08 -0500347 server_ip = self.floating_ips[server['id']]['floating_ip_address']
Yair Fried4d7efa62013-11-17 17:12:29 +0200348 else:
armando-migliacciod03f2642014-02-21 19:55:50 -0800349 server_ip = None
Steve Heyman33735f22016-05-24 09:28:08 -0500350 network_name = self.tenants[server['tenant_id']].network['name']
Yair Frieddb6c9e92014-08-06 08:53:13 +0300351 if network_name in server['addresses']:
352 server_ip = server['addresses'][network_name][0]['addr']
armando-migliacciod03f2642014-02-21 19:55:50 -0800353 return server_ip
Yair Fried4d7efa62013-11-17 17:12:29 +0200354
355 def _connect_to_access_point(self, tenant):
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +0000356 """create ssh connection to tenant access point"""
Yair Fried4d7efa62013-11-17 17:12:29 +0200357 access_point_ssh = \
Steve Heyman33735f22016-05-24 09:28:08 -0500358 self.floating_ips[tenant.access_point['id']]['floating_ip_address']
Yair Frieddb6c9e92014-08-06 08:53:13 +0300359 private_key = tenant.keypair['private_key']
Jordan Pittierbbb17122016-01-26 17:10:55 +0100360 access_point_ssh = self.get_remote_client(
361 access_point_ssh, private_key=private_key)
Yair Fried4d7efa62013-11-17 17:12:29 +0200362 return access_point_ssh
363
Yair Fried4d7efa62013-11-17 17:12:29 +0200364 def _check_connectivity(self, access_point, ip, should_succeed=True):
365 if should_succeed:
366 msg = "Timed out waiting for %s to become reachable" % ip
367 else:
Yair Fried4d7efa62013-11-17 17:12:29 +0200368 msg = "%s is reachable" % ip
Matthew Treinish53483132014-12-09 18:50:06 -0500369 self.assertTrue(self._check_remote_connectivity(access_point, ip,
370 should_succeed), msg)
Yair Fried4d7efa62013-11-17 17:12:29 +0200371
372 def _test_in_tenant_block(self, tenant):
373 access_point_ssh = self._connect_to_access_point(tenant)
374 for server in tenant.servers:
375 self._check_connectivity(access_point=access_point_ssh,
376 ip=self._get_server_ip(server),
377 should_succeed=False)
378
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:
392 self._check_connectivity(access_point=access_point_ssh,
393 ip=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)
401 self._check_connectivity(access_point=access_point_ssh, ip=ip,
402 should_succeed=False)
403
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)
423 self._check_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)
440 self._check_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.
Yair Frieddb6c9e92014-08-06 08:53:13 +0300450 port_list = self._list_ports(fields=['fixed_ips', 'mac_address'])
Yair Fried4d7efa62013-11-17 17:12:29 +0200451 port_detail_list = [
452 (port['fixed_ips'][0]['subnet_id'],
453 port['fixed_ips'][0]['ip_address'],
Henry Gessau78ab4b02014-03-31 15:10:13 -0400454 port['mac_address'].lower())
455 for port in port_list if port['fixed_ips']
Yair Fried4d7efa62013-11-17 17:12:29 +0200456 ]
457 server_ip = self._get_server_ip(tenant.access_point)
Steve Heyman33735f22016-05-24 09:28:08 -0500458 subnet_id = tenant.subnet['id']
Yair Fried4d7efa62013-11-17 17:12:29 +0200459 self.assertIn((subnet_id, server_ip, mac_addr), port_detail_list)
460
Chris Hoge7579c1a2015-02-26 14:12:15 -0800461 @test.idempotent_id('e79f879e-debb-440c-a7e4-efeda05b6848')
Masayuki Igawa4ded9f02014-02-17 15:05:59 +0900462 @test.services('compute', 'network')
Yair Fried4d7efa62013-11-17 17:12:29 +0200463 def test_cross_tenant_traffic(self):
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100464 if not self.credentials_provider.is_multi_tenant():
Yair Fried79b0a912014-10-20 11:15:37 +0300465 raise self.skipException("No secondary tenant defined")
Nachi Ueno26b4c972014-01-17 06:15:13 -0800466 try:
Sean Dagueed6e5862016-04-04 10:49:13 -0400467 # deploy new project
Yair Friedbf2e2c42014-01-28 12:06:38 +0200468 self._deploy_tenant(self.alt_tenant)
469 self._verify_network_details(self.alt_tenant)
470 self._verify_mac_addr(self.alt_tenant)
Yair Fried4d7efa62013-11-17 17:12:29 +0200471
Nachi Ueno26b4c972014-01-17 06:15:13 -0800472 # cross tenant check
Yair Friedbf2e2c42014-01-28 12:06:38 +0200473 source_tenant = self.primary_tenant
Nachi Ueno26b4c972014-01-17 06:15:13 -0800474 dest_tenant = self.alt_tenant
475 self._test_cross_tenant_block(source_tenant, dest_tenant)
476 self._test_cross_tenant_allow(source_tenant, dest_tenant)
477 except Exception:
Yair Friedbf2e2c42014-01-28 12:06:38 +0200478 for tenant in self.tenants.values():
479 self._log_console_output(servers=tenant.servers)
480 raise
481
Chris Hoge7579c1a2015-02-26 14:12:15 -0800482 @test.idempotent_id('63163892-bbf6-4249-aa12-d5ea1f8f421b')
Masayuki Igawa4ded9f02014-02-17 15:05:59 +0900483 @test.services('compute', 'network')
Yair Friedbf2e2c42014-01-28 12:06:38 +0200484 def test_in_tenant_traffic(self):
485 try:
486 self._create_tenant_servers(self.primary_tenant, num=1)
487
488 # in-tenant check
489 self._test_in_tenant_block(self.primary_tenant)
490 self._test_in_tenant_allow(self.primary_tenant)
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800491 except Exception:
492 for tenant in self.tenants.values():
493 self._log_console_output(servers=tenant.servers)
494 raise
Yair Friedbf2e2c42014-01-28 12:06:38 +0200495
Chris Hoge7579c1a2015-02-26 14:12:15 -0800496 @test.idempotent_id('f4d556d7-1526-42ad-bafb-6bebf48568f6')
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800497 @test.services('compute', 'network')
498 def test_port_update_new_security_group(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000499 """Verifies the traffic after updating the vm port
500
501 With new security group having appropriate rule.
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800502 """
503 new_tenant = self.primary_tenant
504
505 # Create empty security group and add icmp rule in it
506 new_sg = self._create_empty_security_group(
507 namestart='secgroup_new-',
508 tenant_id=new_tenant.creds.tenant_id,
John Warrenf9606e92015-12-10 12:12:42 -0500509 client=new_tenant.manager.security_groups_client)
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800510 icmp_rule = dict(
511 protocol='icmp',
512 direction='ingress',
513 )
John Warren456d9ae2016-01-12 15:36:33 -0500514 sec_group_rules_client = new_tenant.manager.security_group_rules_client
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800515 self._create_security_group_rule(
516 secgroup=new_sg,
John Warren456d9ae2016-01-12 15:36:33 -0500517 sec_group_rules_client=sec_group_rules_client,
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800518 **icmp_rule)
519 new_tenant.security_groups.update(new_sg=new_sg)
520
521 # Create server with default security group
Ken'ichi Ohmichi6ded8df2015-03-23 02:00:19 +0000522 name = 'server-{tenant}-gen-1'.format(
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800523 tenant=new_tenant.creds.tenant_name
524 )
525 name = data_utils.rand_name(name)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200526 server = self._create_server(name, new_tenant,
527 [new_tenant.security_groups['default']])
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800528
529 # Check connectivity failure with default security group
530 try:
531 access_point_ssh = self._connect_to_access_point(new_tenant)
532 self._check_connectivity(access_point=access_point_ssh,
533 ip=self._get_server_ip(server),
534 should_succeed=False)
535 server_id = server['id']
536 port_id = self._list_ports(device_id=server_id)[0]['id']
537
538 # update port with new security group and check connectivity
John Warren49c0fe52015-10-22 12:35:54 -0400539 self.ports_client.update_port(port_id, security_groups=[
Steve Heyman33735f22016-05-24 09:28:08 -0500540 new_tenant.security_groups['new_sg']['id']])
Rajkumar Thiyagarajand9e964a2014-12-17 01:55:52 -0800541 self._check_connectivity(
542 access_point=access_point_ssh,
543 ip=self._get_server_ip(server))
Yair Friedbf2e2c42014-01-28 12:06:38 +0200544 except Exception:
545 for tenant in self.tenants.values():
546 self._log_console_output(servers=tenant.servers)
Nachi Ueno26b4c972014-01-17 06:15:13 -0800547 raise
prdsilva8b733ad2014-12-09 02:54:49 -0800548
Chris Hoge7579c1a2015-02-26 14:12:15 -0800549 @test.idempotent_id('d2f77418-fcc4-439d-b935-72eca704e293')
prdsilva8b733ad2014-12-09 02:54:49 -0800550 @test.services('compute', 'network')
551 def test_multiple_security_groups(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000552 """Verify multiple security groups and checks that rules
553
prdsilva8b733ad2014-12-09 02:54:49 -0800554 provided in the both the groups is applied onto VM
555 """
556 tenant = self.primary_tenant
557 ip = self._get_server_ip(tenant.access_point,
558 floating=self.floating_ip_access)
lanoux283273b2015-12-04 03:01:54 -0800559 ssh_login = CONF.validation.image_ssh_user
prdsilva8b733ad2014-12-09 02:54:49 -0800560 private_key = tenant.keypair['private_key']
561 self.check_vm_connectivity(ip,
562 should_connect=False)
563 ruleset = dict(
564 protocol='icmp',
565 direction='ingress'
566 )
567 self._create_security_group_rule(
568 secgroup=tenant.security_groups['default'],
569 **ruleset
570 )
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000571 # NOTE: Vm now has 2 security groups one with ssh rule(
572 # already added in setUp() method),and other with icmp rule
573 # (added in the above step).The check_vm_connectivity tests
574 # -that vm ping test is successful
575 # -ssh to vm is successful
prdsilva8b733ad2014-12-09 02:54:49 -0800576 self.check_vm_connectivity(ip,
577 username=ssh_login,
578 private_key=private_key,
579 should_connect=True)
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900580
581 @test.requires_ext(service='network', extension='port-security')
582 @test.idempotent_id('7c811dcc-263b-49a3-92d2-1b4d8405f50c')
583 @test.services('compute', 'network')
584 def test_port_security_disable_security_group(self):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000585 """Verify the default security group rules is disabled."""
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900586 new_tenant = self.primary_tenant
587
588 # Create server
589 name = 'server-{tenant}-gen-1'.format(
590 tenant=new_tenant.creds.tenant_name
591 )
592 name = data_utils.rand_name(name)
Markus Zoeller156b5da2016-07-11 18:10:31 +0200593 server = self._create_server(name, new_tenant,
594 [new_tenant.security_groups['default']])
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900595
596 access_point_ssh = self._connect_to_access_point(new_tenant)
597 server_id = server['id']
598 port_id = self._list_ports(device_id=server_id)[0]['id']
599
600 # Flip the port's port security and check connectivity
601 try:
John Warren49c0fe52015-10-22 12:35:54 -0400602 self.ports_client.update_port(port_id,
603 port_security_enabled=True,
604 security_groups=[])
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900605 self._check_connectivity(access_point=access_point_ssh,
606 ip=self._get_server_ip(server),
607 should_succeed=False)
608
John Warren49c0fe52015-10-22 12:35:54 -0400609 self.ports_client.update_port(port_id,
610 port_security_enabled=False,
611 security_groups=[])
YAMAMOTO Takashi51e04082015-09-08 18:44:23 +0900612 self._check_connectivity(
613 access_point=access_point_ssh,
614 ip=self._get_server_ip(server))
615 except Exception:
616 for tenant in self.tenants.values():
617 self._log_console_output(servers=tenant.servers)
618 raise
Markus Zoeller156b5da2016-07-11 18:10:31 +0200619
620 @test.requires_ext(service='network', extension='port-security')
621 @test.idempotent_id('13ccf253-e5ad-424b-9c4a-97b88a026699')
622 @testtools.skipUnless(
623 CONF.compute_feature_enabled.allow_port_security_disabled,
624 'Port security must be enabled.')
Matt Riedemann039b2fe2016-09-15 16:12:24 -0400625 # TODO(mriedem): We shouldn't actually need to check this since neutron
626 # disables the port_security extension by default, but the problem is nova
627 # assumes port_security_enabled=True if it's not set on the network
628 # resource, which will mean nova may attempt to apply a security group on
629 # a port on that network which would fail. This is really a bug in nova.
630 @testtools.skipUnless(
631 CONF.network_feature_enabled.port_security,
632 'Port security must be enabled.')
Markus Zoeller156b5da2016-07-11 18:10:31 +0200633 @test.services('compute', 'network')
634 def test_boot_into_disabled_port_security_network_without_secgroup(self):
635 tenant = self.primary_tenant
636 self._create_tenant_network(tenant, port_security_enabled=False)
637 self.assertFalse(tenant.network['port_security_enabled'])
638 name = data_utils.rand_name('server-smoke')
639 sec_groups = []
640 server = self._create_server(name, tenant, sec_groups)
641 server_id = server['id']
642 ports = self._list_ports(device_id=server_id)
643 self.assertEqual(1, len(ports))
644 for port in ports:
645 self.assertEmpty(port['security_groups'],
646 "Neutron shouldn't even use it's default sec "
647 "group.")