034989055fee9bc8d0c6e0138b487f9a6a9655b0
[snaps.git] / snaps / openstack / create_project.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 logging
16
17 from keystoneclient.exceptions import NotFound, Conflict
18
19 from snaps.config.project import ProjectConfig
20 from snaps.openstack.openstack_creator import OpenStackIdentityObject
21 from snaps.openstack.utils import keystone_utils, neutron_utils, nova_utils
22
23 __author__ = 'spisarski'
24
25 logger = logging.getLogger('create_image')
26
27
28 class OpenStackProject(OpenStackIdentityObject):
29     """
30     Class responsible for managing a project/project in OpenStack
31     """
32
33     def __init__(self, os_creds, project_settings):
34         """
35         Constructor
36         :param os_creds: The OpenStack connection credentials
37         :param project_settings: The project's settings
38         :return:
39         """
40         super(self.__class__, self).__init__(os_creds)
41
42         self.project_settings = project_settings
43         self.__project = None
44         self.__role = None
45         self.__role_name = self.project_settings.name + '-role'
46
47     def initialize(self):
48         """
49         Loads the existing Project object if it exists
50         :return: The Project domain object
51         """
52         super(self.__class__, self).initialize()
53
54         self.__project = keystone_utils.get_project(
55             keystone=self._keystone, project_settings=self.project_settings)
56         return self.__project
57
58     def create(self):
59         """
60         Creates a Project/Tenant in OpenStack if it does not already exist
61         :return: The Project domain object
62         """
63         self.initialize()
64
65         if not self.__project:
66             self.__project = keystone_utils.create_project(
67                 self._keystone, self.project_settings)
68             for username in self.project_settings.users:
69                 user = keystone_utils.get_user(self._keystone, username)
70                 if user:
71                     try:
72                         self.assoc_user(user)
73                     except Conflict as e:
74                         logger.warn('Unable to associate user %s due to %s',
75                                     user.name, e)
76
77         return self.__project
78
79     def clean(self):
80         """
81         Cleanse environment of all artifacts
82         :return: void
83         """
84         if self.__project:
85             # Delete security group 'default' if exists
86             neutron = neutron_utils.neutron_client(self._os_creds)
87             default_sec_grp = neutron_utils.get_security_group(
88                 neutron, sec_grp_name='default',
89                 project_id=self.__project.id)
90             if default_sec_grp:
91                 try:
92                     neutron_utils.delete_security_group(
93                         neutron, default_sec_grp)
94                 except:
95                     pass
96
97             # Delete Project
98             try:
99                 keystone_utils.delete_project(self._keystone, self.__project)
100             except NotFound:
101                 pass
102             self.__project = None
103
104         if self.__role:
105             try:
106                 keystone_utils.delete_role(self._keystone, self.__role)
107             except NotFound:
108                 pass
109             self.__project = None
110
111         # Final role check in case init was done from an existing instance
112         role = keystone_utils.get_role_by_name(
113             self._keystone, self.__role_name)
114         if role:
115             keystone_utils.delete_role(self._keystone, role)
116
117     def get_project(self):
118         """
119         Returns the OpenStack project object populated on create()
120         :return:
121         """
122         return self.__project
123
124     def assoc_user(self, user):
125         """
126         The user object to associate with the project
127         :param user: the OpenStack User domain object to associate with project
128         :return:
129         """
130         if not self.__role:
131             self.__role = keystone_utils.get_role_by_name(
132                 self._keystone, self.__role_name)
133             if not self.__role:
134                 self.__role = keystone_utils.create_role(
135                     self._keystone, self.__role_name)
136
137         keystone_utils.grant_user_role_to_project(self._keystone, self.__role,
138                                                   user, self.__project)
139
140     def get_compute_quotas(self):
141         """
142         Returns the compute quotas as an instance of the ComputeQuotas class
143         :return:
144         """
145         nova = nova_utils.nova_client(self._os_creds)
146         return nova_utils.get_compute_quotas(nova, self.__project.id)
147
148     def get_network_quotas(self):
149         """
150         Returns the network quotas as an instance of the NetworkQuotas class
151         :return:
152         """
153         neutron = neutron_utils.neutron_client(self._os_creds)
154         return neutron_utils.get_network_quotas(neutron, self.__project.id)
155
156     def update_compute_quotas(self, compute_quotas):
157         """
158         Updates the compute quotas for this project
159         :param compute_quotas: a ComputeQuotas object.
160         """
161         nova = nova_utils.nova_client(self._os_creds)
162         nova_utils.update_quotas(nova, self.__project.id, compute_quotas)
163
164     def update_network_quotas(self, network_quotas):
165         """
166         Updates the network quotas for this project
167         :param network_quotas: a NetworkQuotas object.
168         """
169         neutron = neutron_utils.neutron_client(self._os_creds)
170         neutron_utils.update_quotas(neutron, self.__project.id, network_quotas)
171
172
173 class ProjectSettings(ProjectConfig):
174     """
175     Class to hold the configuration settings required for creating OpenStack
176     project objects
177     deprecated
178     """
179
180     def __init__(self, **kwargs):
181         from warnings import warn
182         warn('Use snaps.config.project.ProjectConfig instead',
183              DeprecationWarning)
184         super(self.__class__, self).__init__(**kwargs)