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.config.project import ProjectConfig
20 from snaps.openstack.openstack_creator import OpenStackIdentityObject
21 from snaps.openstack.utils import keystone_utils, neutron_utils, nova_utils
23 __author__ = 'spisarski'
25 logger = logging.getLogger('create_image')
28 class OpenStackProject(OpenStackIdentityObject):
30 Class responsible for managing a project/project in OpenStack
33 def __init__(self, os_creds, project_settings):
36 :param os_creds: The OpenStack connection credentials
37 :param project_settings: The project's settings
40 super(self.__class__, self).__init__(os_creds)
42 self.project_settings = project_settings
45 self.__role_name = self.project_settings.name + '-role'
49 Loads the existing Project object if it exists
50 :return: The Project domain object
52 super(self.__class__, self).initialize()
54 self.__project = keystone_utils.get_project(
55 keystone=self._keystone, project_settings=self.project_settings)
60 Creates a Project/Tenant in OpenStack if it does not already exist
61 :return: The Project domain object
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)
74 logger.warn('Unable to associate user %s due to %s',
77 if self.project_settings.quotas:
78 quota_dict = self.project_settings.quotas
79 nova = nova_utils.nova_client(self._os_creds, self._os_session)
80 quotas = nova_utils.get_compute_quotas(nova, self.__project.id)
82 if 'cores' in quota_dict:
83 quotas.cores = quota_dict['cores']
84 if 'instances' in quota_dict:
85 quotas.instances = quota_dict['instances']
86 if 'injected_files' in quota_dict:
87 quotas.injected_files = quota_dict['injected_files']
88 if 'injected_file_content_bytes' in quota_dict:
89 quotas.injected_file_content_bytes = \
90 quota_dict['injected_file_content_bytes']
91 if 'ram' in quota_dict:
92 quotas.ram = quota_dict['ram']
93 if 'fixed_ips' in quota_dict:
94 quotas.fixed_ips = quota_dict['fixed_ips']
95 if 'key_pairs' in quota_dict:
96 quotas.key_pairs = quota_dict['key_pairs']
98 nova_utils.update_quotas(nova, self.__project.id, quotas)
100 return self.__project
104 Cleanse environment of all artifacts
108 # Delete security group 'default' if exists
109 neutron = neutron_utils.neutron_client(
110 self._os_creds, self._os_session)
112 default_sec_grp = neutron_utils.get_security_group(
113 neutron, self._keystone, sec_grp_name='default',
114 project_name=self.__project.name)
117 neutron_utils.delete_security_group(
118 neutron, default_sec_grp)
122 neutron.httpclient.session.session.close()
126 keystone_utils.delete_project(self._keystone, self.__project)
129 self.__project = None
133 keystone_utils.delete_role(self._keystone, self.__role)
136 self.__project = None
138 # Final role check in case init was done from an existing instance
139 role = keystone_utils.get_role_by_name(
140 self._keystone, self.__role_name)
142 keystone_utils.delete_role(self._keystone, role)
144 super(self.__class__, self).clean()
146 def get_project(self):
148 Returns the OpenStack project object populated on create()
151 return self.__project
153 def assoc_user(self, user):
155 The user object to associate with the project
156 :param user: the OpenStack User domain object to associate with project
160 self.__role = keystone_utils.get_role_by_name(
161 self._keystone, self.__role_name)
163 self.__role = keystone_utils.create_role(
164 self._keystone, self.__role_name)
166 keystone_utils.grant_user_role_to_project(self._keystone, self.__role,
167 user, self.__project)
169 def get_compute_quotas(self):
171 Returns the compute quotas as an instance of the ComputeQuotas class
174 nova = nova_utils.nova_client(self._os_creds, self._os_session)
177 return nova_utils.get_compute_quotas(nova, self.__project.id)
179 nova.client.session.session.close()
181 def get_network_quotas(self):
183 Returns the network quotas as an instance of the NetworkQuotas class
186 neutron = neutron_utils.neutron_client(
187 self._os_creds, self._os_session)
189 return neutron_utils.get_network_quotas(neutron, self.__project.id)
191 neutron.httpclient.session.session.close()
193 def update_compute_quotas(self, compute_quotas):
195 Updates the compute quotas for this project
196 :param compute_quotas: a ComputeQuotas object.
198 nova = nova_utils.nova_client(self._os_creds, self._os_session)
200 nova_utils.update_quotas(nova, self.__project.id, compute_quotas)
202 nova.client.session.session.close()
204 def update_network_quotas(self, network_quotas):
206 Updates the network quotas for this project
207 :param network_quotas: a NetworkQuotas object.
209 neutron = neutron_utils.neutron_client(
210 self._os_creds, self._os_session)
212 neutron_utils.update_quotas(
213 neutron, self.__project.id, network_quotas)
215 neutron.httpclient.session.session.close()
218 class ProjectSettings(ProjectConfig):
220 Class to hold the configuration settings required for creating OpenStack
225 def __init__(self, **kwargs):
226 from warnings import warn
227 warn('Use snaps.config.project.ProjectConfig instead',
229 super(self.__class__, self).__init__(**kwargs)