Closing keystone sessions after done with them.
[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(
87                 self._os_creds, self._os_session)
88             try:
89                 default_sec_grp = neutron_utils.get_security_group(
90                     neutron, self._keystone, sec_grp_name='default',
91                     project_name=self.__project.name)
92                 if default_sec_grp:
93                     try:
94                         neutron_utils.delete_security_group(
95                             neutron, default_sec_grp)
96                     except:
97                         pass
98             finally:
99                 neutron.httpclient.session.session.close()
100
101             # Delete Project
102             try:
103                 keystone_utils.delete_project(self._keystone, self.__project)
104             except NotFound:
105                 pass
106             self.__project = None
107
108         if self.__role:
109             try:
110                 keystone_utils.delete_role(self._keystone, self.__role)
111             except NotFound:
112                 pass
113             self.__project = None
114
115         # Final role check in case init was done from an existing instance
116         role = keystone_utils.get_role_by_name(
117             self._keystone, self.__role_name)
118         if role:
119             keystone_utils.delete_role(self._keystone, role)
120
121         super(self.__class__, self).clean()
122
123     def get_project(self):
124         """
125         Returns the OpenStack project object populated on create()
126         :return:
127         """
128         return self.__project
129
130     def assoc_user(self, user):
131         """
132         The user object to associate with the project
133         :param user: the OpenStack User domain object to associate with project
134         :return:
135         """
136         if not self.__role:
137             self.__role = keystone_utils.get_role_by_name(
138                 self._keystone, self.__role_name)
139             if not self.__role:
140                 self.__role = keystone_utils.create_role(
141                     self._keystone, self.__role_name)
142
143         keystone_utils.grant_user_role_to_project(self._keystone, self.__role,
144                                                   user, self.__project)
145
146     def get_compute_quotas(self):
147         """
148         Returns the compute quotas as an instance of the ComputeQuotas class
149         :return:
150         """
151         nova = nova_utils.nova_client(self._os_creds, self._os_session)
152
153         try:
154             return nova_utils.get_compute_quotas(nova, self.__project.id)
155         finally:
156             nova.client.session.session.close()
157
158     def get_network_quotas(self):
159         """
160         Returns the network quotas as an instance of the NetworkQuotas class
161         :return:
162         """
163         neutron = neutron_utils.neutron_client(
164             self._os_creds, self._os_session)
165         try:
166             return neutron_utils.get_network_quotas(neutron, self.__project.id)
167         finally:
168             neutron.httpclient.session.session.close()
169
170     def update_compute_quotas(self, compute_quotas):
171         """
172         Updates the compute quotas for this project
173         :param compute_quotas: a ComputeQuotas object.
174         """
175         nova = nova_utils.nova_client(self._os_creds, self._os_session)
176         try:
177             nova_utils.update_quotas(nova, self.__project.id, compute_quotas)
178         finally:
179             nova.client.session.session.close()
180
181     def update_network_quotas(self, network_quotas):
182         """
183         Updates the network quotas for this project
184         :param network_quotas: a NetworkQuotas object.
185         """
186         neutron = neutron_utils.neutron_client(
187             self._os_creds, self._os_session)
188         try:
189             neutron_utils.update_quotas(
190                 neutron, self.__project.id, network_quotas)
191         finally:
192             neutron.httpclient.session.session.close()
193
194
195 class ProjectSettings(ProjectConfig):
196     """
197     Class to hold the configuration settings required for creating OpenStack
198     project objects
199     deprecated
200     """
201
202     def __init__(self, **kwargs):
203         from warnings import warn
204         warn('Use snaps.config.project.ProjectConfig instead',
205              DeprecationWarning)
206         super(self.__class__, self).__init__(**kwargs)