Refactoring of ProjectSettings to extend ProjectConfig
[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.project import ProjectConfigError, ProjectConfig
21 from snaps.domain.project import ComputeQuotas, NetworkQuotas
22 from snaps.openstack.create_project import (
23     OpenStackProject, ProjectSettings)
24 from snaps.openstack.create_security_group import OpenStackSecurityGroup
25 from snaps.openstack.create_security_group import SecurityGroupSettings
26 from snaps.openstack.create_user import OpenStackUser
27 from snaps.openstack.create_user import UserSettings
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, UserSettings(
277                 name=self.guid + '-user',
278                 password=self.guid, roles={
279                     '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, SecurityGroupSettings(
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, UserSettings(
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, UserSettings(
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                 SecurityGroupSettings(name=self.guid + '-name',
331                                       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)