Expanded project creation tests and validation.
[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.openstack.create_project import (
21     OpenStackProject, ProjectSettings, ProjectSettingsError)
22 from snaps.openstack.create_security_group import OpenStackSecurityGroup
23 from snaps.openstack.create_security_group import SecurityGroupSettings
24 from snaps.openstack.create_user import OpenStackUser
25 from snaps.openstack.create_user import UserSettings
26 from snaps.openstack.tests.os_source_file_test import OSComponentTestCase
27 from snaps.openstack.utils import keystone_utils
28
29 __author__ = 'spisarski'
30
31
32 class ProjectSettingsUnitTests(unittest.TestCase):
33     """
34     Tests the construction of the ProjectSettings class
35     """
36
37     def test_no_params(self):
38         with self.assertRaises(ProjectSettingsError):
39             ProjectSettings()
40
41     def test_empty_config(self):
42         with self.assertRaises(ProjectSettingsError):
43             ProjectSettings(**dict())
44
45     def test_name_only(self):
46         settings = ProjectSettings(name='foo')
47         self.assertEqual('foo', settings.name)
48         self.assertEqual('default', settings.domain)
49         self.assertIsNone(settings.description)
50         self.assertTrue(settings.enabled)
51
52     def test_config_with_name_only(self):
53         settings = ProjectSettings(**{'name': 'foo'})
54         self.assertEqual('foo', settings.name)
55         self.assertEqual('default', settings.domain)
56         self.assertIsNone(settings.description)
57         self.assertTrue(settings.enabled)
58
59     def test_all(self):
60         settings = ProjectSettings(name='foo', domain='bar',
61                                    description='foobar', enabled=False)
62         self.assertEqual('foo', settings.name)
63         self.assertEqual('bar', settings.domain)
64         self.assertEqual('foobar', settings.description)
65         self.assertFalse(settings.enabled)
66
67     def test_config_all(self):
68         settings = ProjectSettings(
69             **{'name': 'foo', 'domain': 'bar', 'description': 'foobar',
70                'enabled': False})
71         self.assertEqual('foo', settings.name)
72         self.assertEqual('bar', settings.domain)
73         self.assertEqual('foobar', settings.description)
74         self.assertFalse(settings.enabled)
75
76
77 class CreateProjectSuccessTests(OSComponentTestCase):
78     """
79     Test for the CreateImage class defined in create_image.py
80     """
81
82     def setUp(self):
83         """
84         Instantiates the CreateImage object that is responsible for downloading
85         and creating an OS image file within OpenStack
86         """
87         guid = str(uuid.uuid4())[:-19]
88         guid = self.__class__.__name__ + '-' + guid
89         self.project_settings = ProjectSettings(name=guid + '-name')
90
91         self.keystone = keystone_utils.keystone_client(self.os_creds)
92
93         # Initialize for cleanup
94         self.project_creator = None
95
96     def tearDown(self):
97         """
98         Cleans the image and downloaded image file
99         """
100         if self.project_creator:
101             self.project_creator.clean()
102
103     def test_create_project_bad_domain(self):
104         """
105         Tests the creation of an OpenStack project with an invalid domain
106         value. This test will not do anything with a keystone v2.0 client.
107         """
108         if self.keystone.version != keystone_utils.V2_VERSION_STR:
109             self.project_settings.domain = 'foo'
110             self.project_creator = OpenStackProject(self.os_creds,
111                                                     self.project_settings)
112
113             with self.assertRaises(BadRequest):
114                 self.project_creator.create()
115
116     def test_create_project(self):
117         """
118         Tests the creation of an OpenStack project.
119         """
120         self.project_creator = OpenStackProject(self.os_creds,
121                                                 self.project_settings)
122         created_project = self.project_creator.create()
123         self.assertIsNotNone(created_project)
124
125         retrieved_project = keystone_utils.get_project(
126             keystone=self.keystone, project_name=self.project_settings.name)
127         self.assertIsNotNone(retrieved_project)
128         self.assertEqual(created_project, retrieved_project)
129         self.assertTrue(validate_project(self.keystone, self.project_settings,
130                                          created_project))
131
132     def test_create_project_2x(self):
133         """
134         Tests the creation of an OpenStack project twice to ensure it only
135         creates one.
136         """
137         self.project_creator = OpenStackProject(self.os_creds,
138                                                 self.project_settings)
139         created_project = self.project_creator.create()
140         self.assertIsNotNone(created_project)
141
142         retrieved_project = keystone_utils.get_project(
143             keystone=self.keystone, project_name=self.project_settings.name)
144         self.assertIsNotNone(retrieved_project)
145         self.assertEqual(created_project, retrieved_project)
146
147         project2 = OpenStackProject(self.os_creds,
148                                     self.project_settings).create()
149         self.assertEqual(retrieved_project, project2)
150         self.assertTrue(validate_project(self.keystone, self.project_settings,
151                                          created_project))
152
153     def test_create_delete_project(self):
154         """
155         Tests the creation of an OpenStack project, it's deletion, then cleanup
156         """
157         # Create Image
158         self.project_creator = OpenStackProject(self.os_creds,
159                                                 self.project_settings)
160         created_project = self.project_creator.create()
161         self.assertIsNotNone(created_project)
162
163         keystone_utils.delete_project(self.keystone, created_project)
164
165         self.project_creator.clean()
166
167         self.assertIsNone(self.project_creator.get_project())
168
169         self.assertTrue(validate_project(self.keystone, self.project_settings,
170                                          created_project))
171
172
173 class CreateProjectUserTests(OSComponentTestCase):
174     """
175     Test for the CreateImage class defined in create_image.py
176     """
177
178     def setUp(self):
179         """
180         Instantiates the CreateImage object that is responsible for downloading
181         and creating an OS image file within OpenStack
182         """
183         guid = str(uuid.uuid4())[:-19]
184         self.guid = self.__class__.__name__ + '-' + guid
185         self.project_settings = ProjectSettings(name=self.guid + '-name')
186
187         self.keystone = keystone_utils.keystone_client(self.os_creds)
188
189         # Initialize for cleanup
190         self.project_creator = None
191         self.user_creators = list()
192
193         self.sec_grp_creators = list()
194
195     def tearDown(self):
196         """
197         Cleans the image and downloaded image file
198         """
199         for sec_grp_creator in self.sec_grp_creators:
200             sec_grp_creator.clean()
201
202         for user_creator in self.user_creators:
203             user_creator.clean()
204
205         if self.project_creator:
206             self.project_creator.clean()
207
208     def test_create_project_sec_grp_one_user(self):
209         """
210         Tests the creation of an OpenStack object to a project with a new users
211         and to create a security group
212         """
213         self.project_creator = OpenStackProject(self.os_creds,
214                                                 self.project_settings)
215         created_project = self.project_creator.create()
216         self.assertIsNotNone(created_project)
217
218         user_creator = OpenStackUser(
219             self.os_creds, UserSettings(
220                 name=self.guid + '-user',
221                 password=self.guid, roles={'admin': 'admin'}))
222         self.project_creator.assoc_user(user_creator.create())
223         self.user_creators.append(user_creator)
224
225         sec_grp_os_creds = user_creator.get_os_creds(
226             self.project_creator.get_project().name)
227         sec_grp_creator = OpenStackSecurityGroup(
228             sec_grp_os_creds, SecurityGroupSettings(name=self.guid + '-name',
229                                                     description='hello group'))
230         sec_grp = sec_grp_creator.create()
231         self.assertIsNotNone(sec_grp)
232         self.sec_grp_creators.append(sec_grp_creator)
233
234         self.assertEqual(self.project_creator.get_project().id,
235                          sec_grp.project_id)
236
237     def test_create_project_sec_grp_two_users(self):
238         """
239         Tests the creation of an OpenStack object to a project with two new
240         users and use each user to create a security group
241         """
242         self.project_creator = OpenStackProject(self.os_creds,
243                                                 self.project_settings)
244         created_project = self.project_creator.create()
245         self.assertIsNotNone(created_project)
246
247         user_creator_1 = OpenStackUser(
248             self.os_creds, UserSettings(
249                 name=self.guid + '-user1', password=self.guid,
250                 roles={'admin': 'admin'}))
251         self.project_creator.assoc_user(user_creator_1.create())
252         self.user_creators.append(user_creator_1)
253
254         user_creator_2 = OpenStackUser(
255             self.os_creds, UserSettings(
256                 name=self.guid + '-user2', password=self.guid,
257                 roles={'admin': 'admin'}))
258         self.project_creator.assoc_user(user_creator_2.create())
259         self.user_creators.append(user_creator_2)
260
261         ctr = 0
262         for user_creator in self.user_creators:
263             ctr += 1
264             sec_grp_os_creds = user_creator.get_os_creds(
265                 self.project_creator.get_project().name)
266
267             sec_grp_creator = OpenStackSecurityGroup(
268                 sec_grp_os_creds,
269                 SecurityGroupSettings(name=self.guid + '-name',
270                                       description='hello group'))
271             sec_grp = sec_grp_creator.create()
272             self.assertIsNotNone(sec_grp)
273             self.sec_grp_creators.append(sec_grp_creator)
274
275             self.assertEqual(self.project_creator.get_project().id,
276                              sec_grp.project_id)
277
278
279 def validate_project(keystone, project_settings, project):
280     """
281     Validates that the project_settings used to create the project have been
282     properly set
283     :param keystone: the keystone client for version checking
284     :param project_settings: the settings used to create the project
285     :param project: the SNAPS-OO Project domain object
286     :return: T/F
287     """
288     if keystone.version == keystone_utils.V2_VERSION_STR:
289         return project_settings.name == project.name
290     else:
291         return (project_settings.name == project.name and
292                 project_settings.domain == project.domain_id)