Added feature to update the quotas on a project/tenant.
[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
18
19 from snaps.openstack.utils import keystone_utils, neutron_utils, nova_utils
20
21 __author__ = 'spisarski'
22
23 logger = logging.getLogger('create_image')
24
25
26 class OpenStackProject:
27     """
28     Class responsible for creating a project/project in OpenStack
29     """
30
31     def __init__(self, os_creds, project_settings):
32         """
33         Constructor
34         :param os_creds: The OpenStack connection credentials
35         :param project_settings: The project's settings
36         :return:
37         """
38         self.__os_creds = os_creds
39         self.project_settings = project_settings
40         self.__project = None
41         self.__role = None
42         self.__keystone = None
43
44     def create(self, cleanup=False):
45         """
46         Creates the image in OpenStack if it does not already exist
47         :param cleanup: Denotes whether or not this is being called for cleanup
48         :return: The OpenStack Image object
49         """
50         self.__keystone = keystone_utils.keystone_client(self.__os_creds)
51         self.__project = keystone_utils.get_project(
52             keystone=self.__keystone, project_settings=self.project_settings)
53         if self.__project:
54             logger.info(
55                 'Found project with name - ' + self.project_settings.name)
56         elif not cleanup:
57             self.__project = keystone_utils.create_project(
58                 self.__keystone, self.project_settings)
59         else:
60             logger.info('Did not create image due to cleanup mode')
61
62         return self.__project
63
64     def clean(self):
65         """
66         Cleanse environment of all artifacts
67         :return: void
68         """
69         if self.__project:
70             # Delete security group 'default' if exists
71             neutron = neutron_utils.neutron_client(self.__os_creds)
72             default_sec_grp = neutron_utils.get_security_group(
73                 neutron, sec_grp_name='default',
74                 project_id=self.__project.id)
75             if default_sec_grp:
76                 try:
77                     neutron_utils.delete_security_group(
78                         neutron, default_sec_grp)
79                 except:
80                     pass
81
82             # Delete Project
83             try:
84                 keystone_utils.delete_project(self.__keystone, self.__project)
85             except NotFound:
86                 pass
87             self.__project = None
88
89         if self.__role:
90             try:
91                 keystone_utils.delete_role(self.__keystone, self.__role)
92             except NotFound:
93                 pass
94             self.__project = None
95
96     def get_project(self):
97         """
98         Returns the OpenStack project object populated on create()
99         :return:
100         """
101         return self.__project
102
103     def assoc_user(self, user):
104         """
105         The user object to associate with the project
106         :param user: the OpenStack User domain object to associate with project
107         :return:
108         """
109         if not self.__role:
110             self.__role = keystone_utils.create_role(
111                 self.__keystone, self.project_settings.name + '-role')
112
113         keystone_utils.grant_user_role_to_project(self.__keystone, self.__role,
114                                                   user, self.__project)
115
116     def get_compute_quotas(self):
117         """
118         Returns the compute quotas as an instance of the ComputeQuotas class
119         :return:
120         """
121         nova = nova_utils.nova_client(self.__os_creds)
122         return nova_utils.get_compute_quotas(nova, self.__project.id)
123
124     def get_network_quotas(self):
125         """
126         Returns the network quotas as an instance of the NetworkQuotas class
127         :return:
128         """
129         neutron = neutron_utils.neutron_client(self.__os_creds)
130         return neutron_utils.get_network_quotas(neutron, self.__project.id)
131
132     def update_compute_quotas(self, compute_quotas):
133         """
134         Updates the compute quotas for this project
135         :param compute_quotas: a ComputeQuotas object.
136         """
137         nova = nova_utils.nova_client(self.__os_creds)
138         nova_utils.update_quotas(nova, self.__project.id, compute_quotas)
139
140     def update_network_quotas(self, network_quotas):
141         """
142         Updates the network quotas for this project
143         :param network_quotas: a NetworkQuotas object.
144         """
145         neutron = neutron_utils.neutron_client(self.__os_creds)
146         neutron_utils.update_quotas(neutron, self.__project.id, network_quotas)
147
148
149 class ProjectSettings:
150     """
151     Class to hold the configuration settings required for creating OpenStack
152     project objects
153     """
154
155     def __init__(self, **kwargs):
156
157         """
158         Constructor
159         :param name: the project's name (required)
160         :param domain or domain_name: the project's domain name
161                                       (default = 'Default').
162                                       Field is used for v3 clients
163         :param description: the description (optional)
164         :param enabled: denotes whether or not the user is enabled
165                         (default True)
166         """
167
168         self.name = kwargs.get('name')
169         self.domain_name = kwargs.get(
170             'domain', kwargs.get('domain', 'Default'))
171
172         self.description = kwargs.get('description')
173         if kwargs.get('enabled') is not None:
174             self.enabled = kwargs['enabled']
175         else:
176             self.enabled = True
177
178         if not self.name:
179             raise ProjectSettingsError(
180                 "The attribute name is required for ProjectSettings")
181
182
183 class ProjectSettingsError(Exception):
184     """
185     Exception to be thrown when project settings attributes are incorrect
186     """