1 # Copyright (c) 2016 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 novaclient.exceptions import NotFound
19 from snaps.openstack.openstack_creator import OpenStackComputeObject
20 from snaps.openstack.utils import nova_utils
22 __author__ = 'spisarski'
24 logger = logging.getLogger('create_flavor')
26 MEM_PAGE_SIZE_ANY = {'hw:mem_page_size': 'any'}
27 MEM_PAGE_SIZE_LARGE = {'hw:mem_page_size': 'large'}
30 class OpenStackFlavor(OpenStackComputeObject):
32 Class responsible for creating a user in OpenStack
35 def __init__(self, os_creds, flavor_settings):
38 :param os_creds: The OpenStack connection credentials
39 :param flavor_settings: The flavor settings
42 super(self.__class__, self).__init__(os_creds)
44 self.flavor_settings = flavor_settings
49 Loads the existing OpenStack flavor
50 :return: The Flavor domain object or None
52 super(self.__class__, self).initialize()
54 self.__flavor = nova_utils.get_flavor_by_name(
55 self._nova, self.flavor_settings.name)
57 logger.info('Found flavor with name - %s',
58 self.flavor_settings.name)
63 Creates the image in OpenStack if it does not already exist
64 :return: The OpenStack flavor object
68 self.__flavor = nova_utils.create_flavor(
69 self._nova, self.flavor_settings)
70 if self.flavor_settings.metadata:
71 nova_utils.set_flavor_keys(self._nova, self.__flavor,
72 self.flavor_settings.metadata)
74 logger.info('Did not create flavor due to cleanup mode')
80 Cleanse environment of all artifacts
85 nova_utils.delete_flavor(self._nova, self.__flavor)
93 Returns the OpenStack flavor object
101 Configuration settings for OpenStack flavor creation
104 def __init__(self, **kwargs):
107 :param name: the flavor's name (required)
108 :param flavor_id: the string ID (default 'auto')
109 :param ram: the required RAM in MB (required)
110 :param disk: the size of the root disk in GB (required)
111 :param vcpus: the number of virtual CPUs (required)
112 :param ephemeral: the size of the ephemeral disk in GB (default 0)
113 :param swap: the size of the dedicated swap disk in GB (default 0)
114 :param rxtx_factor: the receive/transmit factor to be set on ports if
115 backend supports QoS extension (default 1.0)
116 :param is_public: denotes whether or not the flavor is public
118 :param metadata: freeform dict() for special metadata
120 self.name = kwargs.get('name')
122 if kwargs.get('flavor_id'):
123 self.flavor_id = kwargs['flavor_id']
125 self.flavor_id = 'auto'
127 self.ram = kwargs.get('ram')
128 self.disk = kwargs.get('disk')
129 self.vcpus = kwargs.get('vcpus')
131 if kwargs.get('ephemeral'):
132 self.ephemeral = kwargs['ephemeral']
136 if kwargs.get('swap'):
137 self.swap = kwargs['swap']
141 if kwargs.get('rxtx_factor'):
142 self.rxtx_factor = kwargs['rxtx_factor']
144 self.rxtx_factor = 1.0
146 if kwargs.get('is_public') is not None:
147 self.is_public = kwargs['is_public']
149 self.is_public = True
151 if kwargs.get('metadata'):
152 self.metadata = kwargs['metadata']
156 if not self.name or not self.ram or not self.disk or not self.vcpus:
157 raise FlavorSettingsError(
158 'The attributes name, ram, disk, and vcpus are required for'
161 if not isinstance(self.ram, int):
162 raise FlavorSettingsError('The ram attribute must be a integer')
164 if not isinstance(self.disk, int):
165 raise FlavorSettingsError('The ram attribute must be a integer')
167 if not isinstance(self.vcpus, int):
168 raise FlavorSettingsError('The vcpus attribute must be a integer')
170 if self.ephemeral and not isinstance(self.ephemeral, int):
171 raise FlavorSettingsError(
172 'The ephemeral attribute must be an integer')
174 if self.swap and not isinstance(self.swap, int):
175 raise FlavorSettingsError('The swap attribute must be an integer')
177 if self.rxtx_factor and not isinstance(self.rxtx_factor, (int, float)):
178 raise FlavorSettingsError(
179 'The is_public attribute must be an integer or float')
181 if self.is_public and not isinstance(self.is_public, bool):
182 raise FlavorSettingsError(
183 'The is_public attribute must be a boolean')
186 class FlavorSettingsError(Exception):
188 Exception to be thrown when an flavor settings are incorrect