1 # Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
2 # and others. All rights reserved.
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:
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
17 from keystoneclient.exceptions import NotFound, Conflict
19 from snaps.openstack.openstack_creator import OpenStackIdentityObject
20 from snaps.openstack.utils import keystone_utils, neutron_utils, nova_utils
22 __author__ = 'spisarski'
24 logger = logging.getLogger('create_image')
27 class OpenStackProject(OpenStackIdentityObject):
29 Class responsible for managing a project/project in OpenStack
32 def __init__(self, os_creds, project_settings):
35 :param os_creds: The OpenStack connection credentials
36 :param project_settings: The project's settings
39 super(self.__class__, self).__init__(os_creds)
41 self.project_settings = project_settings
44 self.__role_name = self.project_settings.name + '-role'
48 Loads the existing Project object if it exists
49 :return: The Project domain object
51 super(self.__class__, self).initialize()
53 self.__project = keystone_utils.get_project(
54 keystone=self._keystone, project_settings=self.project_settings)
59 Creates a Project/Tenant in OpenStack if it does not already exist
60 :return: The Project domain object
64 if not self.__project:
65 self.__project = keystone_utils.create_project(
66 self._keystone, self.project_settings)
67 for username in self.project_settings.users:
68 user = keystone_utils.get_user(self._keystone, username)
73 logger.warn('Unable to associate user %s due to %s',
80 Cleanse environment of all artifacts
84 # Delete security group 'default' if exists
85 neutron = neutron_utils.neutron_client(self._os_creds)
86 default_sec_grp = neutron_utils.get_security_group(
87 neutron, sec_grp_name='default',
88 project_id=self.__project.id)
91 neutron_utils.delete_security_group(
92 neutron, default_sec_grp)
98 keystone_utils.delete_project(self._keystone, self.__project)
101 self.__project = None
105 keystone_utils.delete_role(self._keystone, self.__role)
108 self.__project = None
110 # Final role check in case init was done from an existing instance
111 role = keystone_utils.get_role_by_name(
112 self._keystone, self.__role_name)
114 keystone_utils.delete_role(self._keystone, role)
116 def get_project(self):
118 Returns the OpenStack project object populated on create()
121 return self.__project
123 def assoc_user(self, user):
125 The user object to associate with the project
126 :param user: the OpenStack User domain object to associate with project
130 self.__role = keystone_utils.get_role_by_name(
131 self._keystone, self.__role_name)
133 self.__role = keystone_utils.create_role(
134 self._keystone, self.__role_name)
136 keystone_utils.grant_user_role_to_project(self._keystone, self.__role,
137 user, self.__project)
139 def get_compute_quotas(self):
141 Returns the compute quotas as an instance of the ComputeQuotas class
144 nova = nova_utils.nova_client(self._os_creds)
145 return nova_utils.get_compute_quotas(nova, self.__project.id)
147 def get_network_quotas(self):
149 Returns the network quotas as an instance of the NetworkQuotas class
152 neutron = neutron_utils.neutron_client(self._os_creds)
153 return neutron_utils.get_network_quotas(neutron, self.__project.id)
155 def update_compute_quotas(self, compute_quotas):
157 Updates the compute quotas for this project
158 :param compute_quotas: a ComputeQuotas object.
160 nova = nova_utils.nova_client(self._os_creds)
161 nova_utils.update_quotas(nova, self.__project.id, compute_quotas)
163 def update_network_quotas(self, network_quotas):
165 Updates the network quotas for this project
166 :param network_quotas: a NetworkQuotas object.
168 neutron = neutron_utils.neutron_client(self._os_creds)
169 neutron_utils.update_quotas(neutron, self.__project.id, network_quotas)
172 class ProjectSettings:
174 Class to hold the configuration settings required for creating OpenStack
178 def __init__(self, **kwargs):
182 :param name: the project's name (required)
183 :param domain or domain_name: the project's domain name
184 (default = 'Default').
185 Field is used for v3 clients
186 :param description: the description (optional)
187 :param users: list of users to associat project to (optional)
188 :param enabled: denotes whether or not the user is enabled
192 self.name = kwargs.get('name')
193 self.domain_name = kwargs.get(
194 'domain', kwargs.get('domain', 'Default'))
196 self.description = kwargs.get('description')
197 if kwargs.get('enabled') is not None:
198 self.enabled = kwargs['enabled']
202 self.users = kwargs.get('users', list())
205 raise ProjectSettingsError(
206 "The attribute name is required for ProjectSettings")
209 class ProjectSettingsError(Exception):
211 Exception to be thrown when project settings attributes are incorrect