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.utils import nova_utils
21 __author__ = 'spisarski'
23 logger = logging.getLogger('create_image')
25 MEM_PAGE_SIZE_ANY = {'hw:mem_page_size': 'any'}
26 MEM_PAGE_SIZE_LARGE = {'hw:mem_page_size': 'large'}
29 class OpenStackFlavor:
31 Class responsible for creating a user in OpenStack
34 def __init__(self, os_creds, flavor_settings):
37 :param os_creds: The OpenStack connection credentials
38 :param flavor_settings: The flavor settings
41 self.__os_creds = os_creds
42 self.flavor_settings = flavor_settings
44 self.__nova = nova_utils.nova_client(self.__os_creds)
46 def create(self, cleanup=False):
48 Creates the image in OpenStack if it does not already exist
49 :param cleanup: Denotes whether or not this is being called for cleanup or not
50 :return: The OpenStack flavor object
52 self.__flavor = nova_utils.get_flavor_by_name(self.__nova, self.flavor_settings.name)
54 logger.info('Found flavor with name - ' + self.flavor_settings.name)
56 self.__flavor = nova_utils.create_flavor(self.__nova, self.flavor_settings)
57 if self.flavor_settings.metadata:
58 self.__flavor.set_keys(self.flavor_settings.metadata)
59 self.__flavor = nova_utils.get_flavor_by_name(self.__nova, self.flavor_settings.name)
61 logger.info('Did not create flavor due to cleanup mode')
67 Cleanse environment of all artifacts
72 nova_utils.delete_flavor(self.__nova, self.__flavor)
80 Returns the OpenStack flavor object
88 Configuration settings for OpenStack flavor creation
91 def __init__(self, config=None, name=None, flavor_id='auto', ram=None, disk=None, vcpus=None, ephemeral=0, swap=0,
92 rxtx_factor=1.0, is_public=True, metadata=None):
95 :param config: dict() object containing the configuration settings using the attribute names below as each
96 member's the key and overrides any of the other parameters.
97 :param name: the flavor's name (required)
98 :param flavor_id: the string ID (default 'auto')
99 :param ram: the required RAM in MB (required)
100 :param disk: the size of the root disk in GB (required)
101 :param vcpus: the number of virtual CPUs (required)
102 :param ephemeral: the size of the ephemeral disk in GB (default 0)
103 :param swap: the size of the dedicated swap disk in GB (default 0)
104 :param rxtx_factor: the receive/transmit factor to be set on ports if backend supports
105 QoS extension (default 1.0)
106 :param is_public: denotes whether or not the flavor is public (default True)
107 :param metadata: freeform dict() for special metadata (default hw:mem_page_size=any)
111 self.name = config.get('name')
113 if config.get('flavor_id'):
114 self.flavor_id = config['flavor_id']
116 self.flavor_id = flavor_id
118 self.ram = config.get('ram')
119 self.disk = config.get('disk')
120 self.vcpus = config.get('vcpus')
122 if config.get('ephemeral'):
123 self.ephemeral = config['ephemeral']
125 self.ephemeral = ephemeral
127 if config.get('swap'):
128 self.swap = config['swap']
132 if config.get('rxtx_factor'):
133 self.rxtx_factor = config['rxtx_factor']
135 self.rxtx_factor = rxtx_factor
137 if config.get('is_public') is not None:
138 self.is_public = config['is_public']
140 self.is_public = is_public
142 if config.get('metadata'):
143 self.metadata = config['metadata']
145 self.metadata = metadata
148 self.flavor_id = flavor_id
152 self.ephemeral = ephemeral
154 self.rxtx_factor = rxtx_factor
155 self.is_public = is_public
156 self.metadata = metadata
158 if not self.name or not self.ram or not self.disk or not self.vcpus:
159 raise Exception('The attributes name, ram, disk, and vcpus are required for FlavorSettings')
161 if not isinstance(self.ram, int):
162 raise Exception('The ram attribute must be a integer')
164 if not isinstance(self.disk, int):
165 raise Exception('The ram attribute must be a integer')
167 if not isinstance(self.vcpus, int):
168 raise Exception('The vcpus attribute must be a integer')
170 if self.ephemeral and not isinstance(self.ephemeral, int):
171 raise Exception('The ephemeral attribute must be an integer')
173 if self.swap and not isinstance(self.swap, int):
174 raise Exception('The swap attribute must be an integer')
176 if self.rxtx_factor and not isinstance(self.rxtx_factor, (int, float)):
177 raise Exception('The is_public attribute must be an integer or float')
179 if self.is_public and not isinstance(self.is_public, bool):
180 raise Exception('The is_public attribute must be a boolean')