Refactoring of SecurityGroupSettings to extend SecurityGroupConfig
[snaps.git] / snaps / openstack / tests / create_project_tests.py
1 # Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
2 #                    and others.  All rights reserved.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain 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,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 import unittest
16 import uuid
17
18 from keystoneclient.exceptions import BadRequest
19
20 from snaps.config.security_group import SecurityGroupConfig
21 from snaps.config.user import UserConfig
22 from snaps.config.project import ProjectConfigError, ProjectConfig
23 from snaps.domain.project import ComputeQuotas, NetworkQuotas
24 from snaps.openstack.create_project import (
25     OpenStackProject, ProjectSettings)
26 from snaps.openstack.create_security_group import OpenStackSecurityGroup
27 from snaps.openstack.create_user import OpenStackUser
28 from snaps.openstack.tests.os_source_file_test import OSComponentTestCase
29 from snaps.openstack.utils import keystone_utils, nova_utils, neutron_utils
30
31 __author__ = 'spisarski'
32
33
34 class ProjectSettingsUnitTests(unittest.TestCase):
35     """
36     Tests the construction of the ProjectSettings class
37     """
38
39     def test_no_params(self):
40         with self.assertRaises(ProjectConfigError):
41             ProjectSettings()
42
43     def test_empty_config(self):
44         with self.assertRaises(ProjectConfigError):
45             ProjectSettings(**dict())
46
47     def test_name_only(self):
48         settings = ProjectSettings(name='foo')
49         self.assertEqual('foo', settings.name)
50         self.assertEqual('Default', settings.domain_name)
51         self.assertIsNone(settings.description)
52         self.assertTrue(settings.enabled)
53         self.assertEqual(list(), settings.users)
54
55     def test_config_with_name_only(self):
56         settings = ProjectSettings(**{'name': 'foo'})
57         self.assertEqual('foo', settings.name)
58         self.assertEqual('Default', settings.domain_name)
59         self.assertIsNone(settings.description)
60         self.assertTrue(settings.enabled)
61         self.assertEqual(list(), settings.users)
62
63     def test_all(self):
64         users = ['test1', 'test2']
65         settings = ProjectSettings(
66             name='foo', domain='bar', description='foobar', enabled=False,
67             users=users)
68         self.assertEqual('foo', settings.name)
69         self.assertEqual('bar', settings.domain_name)
70         self.assertEqual('foobar', settings.description)
71         self.assertFalse(settings.enabled)
72         self.assertEqual(users, settings.users)
73
74     def test_config_all(self):
75         users = ['test1', 'test2']
76         settings = ProjectSettings(
77             **{'name': 'foo', 'domain': 'bar', 'description': 'foobar',
78                'enabled': False, 'users': users})
79         self.assertEqual('foo', settings.name)
80         self.assertEqual('bar', settings.domain_name)
81         self.assertEqual('foobar', settings.description)
82         self.assertFalse(settings.enabled)
83         self.assertEqual(users, settings.users)
84
85
86 class CreateProjectSuccessTests(OSComponentTestCase):
87     """
88     Test for the CreateImage class defined in create_image.py
89     """
90
91     def setUp(self):
92         """
93         Instantiates the CreateImage object that is responsible for downloading
94         and creating an OS image file within OpenStack
95         """
96         guid = str(uuid.uuid4())[:-19]
97         guid = self.__class__.__name__ + '-' + guid
98         self.project_settings = ProjectConfig(
99             name=guid + '-name',
100             domain=self.os_creds.project_domain_name)
101
102         self.keystone = keystone_utils.keystone_client(self.os_creds)
103
104         # Initialize for cleanup
105         self.project_creator = None
106
107     def tearDown(self):
108         """
109         Cleans the image and downloaded image file
110         """
111         if self.project_creator:
112             self.project_creator.clean()
113
114     def test_create_project_bad_domain(self):
115         """
116         Tests the creation of an OpenStack project with an invalid domain
117         value. This test will not do anything with a keystone v2.0 client.
118         """
119         if self.keystone.version != keystone_utils.V2_VERSION_STR:
120             self.project_settings.domain_name = 'foo'
121             self.project_creator = OpenStackProject(self.os_creds,
122                                                     self.project_settings)
123
124             with self.assertRaises(BadRequest):
125                 self.project_creator.create()
126
127     def test_create_project(self):
128         """
129         Tests the creation of an OpenStack project.
130         """
131         self.project_creator = OpenStackProject(self.os_creds,
132                                                 self.project_settings)
133         created_project = self.project_creator.create()
134         self.assertIsNotNone(created_project)
135
136         retrieved_project = keystone_utils.get_project(
137             keystone=self.keystone, project_settings=self.project_settings)
138         self.assertIsNotNone(retrieved_project)
139         self.assertEqual(created_project, retrieved_project)
140         self.assertTrue(validate_project(self.keystone, self.project_settings,
141                                          created_project))
142
143     def test_create_project_2x(self):
144         """
145         Tests the creation of an OpenStack project twice to ensure it only
146         creates one.
147         """
148         self.project_creator = OpenStackProject(self.os_creds,
149                                                 self.project_settings)
150         created_project = self.project_creator.create()
151         self.assertIsNotNone(created_project)
152
153         retrieved_project = keystone_utils.get_project(
154             keystone=self.keystone, project_settings=self.project_settings)
155         self.assertIsNotNone(retrieved_project)
156         self.assertEqual(created_project, retrieved_project)
157
158         project2 = OpenStackProject(self.os_creds,
159                                     self.project_settings).create()
160         self.assertEqual(retrieved_project, project2)
161         self.assertTrue(validate_project(self.keystone, self.project_settings,
162                                          created_project))
163
164     def test_create_delete_project(self):
165         """
166         Tests the creation of an OpenStack project, it's deletion, then cleanup
167         """
168         # Create Image
169         self.project_creator = OpenStackProject(self.os_creds,
170                                                 self.project_settings)
171         created_project = self.project_creator.create()
172         self.assertIsNotNone(created_project)
173
174         keystone_utils.delete_project(self.keystone, created_project)
175
176         self.project_creator.clean()
177
178         self.assertIsNone(self.project_creator.get_project())
179
180         self.assertTrue(validate_project(self.keystone, self.project_settings,
181                                          created_project))
182
183     def test_update_quotas(self):
184         """
185         Tests the creation of an OpenStack project where the quotas get
186         updated.
187         """
188         self.project_creator = OpenStackProject(self.os_creds,
189                                                 self.project_settings)
190         created_project = self.project_creator.create()
191         self.assertIsNotNone(created_project)
192
193         retrieved_project = keystone_utils.get_project(
194             keystone=self.keystone, project_settings=self.project_settings)
195         self.assertIsNotNone(retrieved_project)
196         self.assertEqual(created_project, retrieved_project)
197         self.assertTrue(validate_project(self.keystone, self.project_settings,
198                                          created_project))
199
200         update_compute_quotas = ComputeQuotas(
201             **{'metadata_items': 64, 'cores': 5, 'instances': 5,
202                'injected_files': 3, 'injected_file_content_bytes': 5120,
203                'ram': 25600, 'fixed_ips': 100, 'key_pairs': 50})
204         self.project_creator.update_compute_quotas(update_compute_quotas)
205
206         update_network_quotas = NetworkQuotas(
207             **{'security_group': 5, 'security_group_rule': 50,
208                'floatingip': 25, 'network': 5, 'port': 25, 'router': 6,
209                'subnet': 7})
210         self.project_creator.update_network_quotas(update_network_quotas)
211
212         self.assertEqual(update_compute_quotas,
213                          self.project_creator.get_compute_quotas())
214         self.assertEqual(update_network_quotas,
215                          self.project_creator.get_network_quotas())
216
217         nova = nova_utils.nova_client(self.os_creds)
218         new_compute_quotas = nova_utils.get_compute_quotas(
219             nova, self.project_creator.get_project().id)
220         self.assertEqual(update_compute_quotas, new_compute_quotas)
221
222         neutron = neutron_utils.neutron_client(self.os_creds)
223         new_network_quotas = neutron_utils.get_network_quotas(
224             neutron, self.project_creator.get_project().id)
225         self.assertEqual(update_network_quotas, new_network_quotas)
226
227
228 class CreateProjectUserTests(OSComponentTestCase):
229     """
230     Test for the CreateImage class defined in create_image.py
231     """
232
233     def setUp(self):
234         """
235         Instantiates the CreateImage object that is responsible for downloading
236         and creating an OS image file within OpenStack
237         """
238         guid = str(uuid.uuid4())[:-19]
239         self.guid = self.__class__.__name__ + '-' + guid
240         self.project_settings = ProjectConfig(
241             name=self.guid + '-name',
242             domain=self.os_creds.project_domain_name)
243
244         self.keystone = keystone_utils.keystone_client(self.os_creds)
245
246         # Initialize for cleanup
247         self.project_creator = None
248         self.user_creators = list()
249
250         self.sec_grp_creators = list()
251
252     def tearDown(self):
253         """
254         Cleans the image and downloaded image file
255         """
256         for sec_grp_creator in self.sec_grp_creators:
257             sec_grp_creator.clean()
258
259         for user_creator in self.user_creators:
260             user_creator.clean()
261
262         if self.project_creator:
263             self.project_creator.clean()
264
265     def test_create_project_sec_grp_one_user(self):
266         """
267         Tests the creation of an OpenStack object to a project with a new users
268         and to create a security group
269         """
270         self.project_creator = OpenStackProject(self.os_creds,
271                                                 self.project_settings)
272         created_project = self.project_creator.create()
273         self.assertIsNotNone(created_project)
274
275         user_creator = OpenStackUser(
276             self.os_creds, UserConfig(
277                 name=self.guid + '-user',
278                 password=self.guid,
279                 roles={'admin':  self.project_settings.name},
280                 domain_name=self.os_creds.user_domain_name))
281         self.project_creator.assoc_user(user_creator.create())
282         self.user_creators.append(user_creator)
283
284         sec_grp_os_creds = user_creator.get_os_creds(
285             self.project_creator.get_project().name)
286         sec_grp_creator = OpenStackSecurityGroup(
287             sec_grp_os_creds, SecurityGroupConfig(
288                 name=self.guid + '-name', description='hello group'))
289         sec_grp = sec_grp_creator.create()
290         self.assertIsNotNone(sec_grp)
291         self.sec_grp_creators.append(sec_grp_creator)
292
293         self.assertEqual(self.project_creator.get_project().id,
294                          sec_grp.project_id)
295
296     def test_create_project_sec_grp_two_users(self):
297         """
298         Tests the creation of an OpenStack object to a project with two new
299         users and use each user to create a security group
300         """
301         self.project_creator = OpenStackProject(self.os_creds,
302                                                 self.project_settings)
303         created_project = self.project_creator.create()
304         self.assertIsNotNone(created_project)
305
306         user_creator_1 = OpenStackUser(
307             self.os_creds, UserConfig(
308                 name=self.guid + '-user1', password=self.guid,
309                 roles={'admin': self.project_settings.name},
310                 domain_name=self.os_creds.user_domain_name))
311         self.project_creator.assoc_user(user_creator_1.create())
312         self.user_creators.append(user_creator_1)
313
314         user_creator_2 = OpenStackUser(
315             self.os_creds, UserConfig(
316                 name=self.guid + '-user2', password=self.guid,
317                 roles={'admin': self.project_settings.name},
318                 domain_name=self.os_creds.user_domain_name))
319         self.project_creator.assoc_user(user_creator_2.create())
320         self.user_creators.append(user_creator_2)
321
322         ctr = 0
323         for user_creator in self.user_creators:
324             ctr += 1
325             sec_grp_os_creds = user_creator.get_os_creds(
326                 self.project_creator.get_project().name)
327
328             sec_grp_creator = OpenStackSecurityGroup(
329                 sec_grp_os_creds,
330                 SecurityGroupConfig(
331                     name=self.guid + '-name', description='hello group'))
332             sec_grp = sec_grp_creator.create()
333             self.assertIsNotNone(sec_grp)
334             self.sec_grp_creators.append(sec_grp_creator)
335
336             self.assertEqual(self.project_creator.get_project().id,
337                              sec_grp.project_id)
338
339
340 def validate_project(keystone, project_settings, project):
341     """
342     Validates that the project_settings used to create the project have been
343     properly set
344     :param keystone: the keystone client for version checking
345     :param project_settings: the settings used to create the project
346     :param project: the SNAPS-OO Project domain object
347     :return: T/F
348     """
349     if keystone.version == keystone_utils.V2_VERSION_STR:
350         return project_settings.name == project.name
351     else:
352         domain = keystone_utils.get_domain_by_id(keystone, project.domain_id)
353         return (project_settings.name == project.name and
354                 project_settings.domain_name == domain.name)