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.
19 from novaclient.client import Client
20 from novaclient.exceptions import NotFound
22 __author__ = 'spisarski'
24 logger = logging.getLogger('nova_utils')
27 Utilities for basic OpenStack Nova API calls
31 def nova_client(os_creds):
33 Instantiates and returns a client for communications with OpenStack's Nova server
34 :param os_creds: The connection credentials to the OpenStack API
35 :return: the client object
37 logger.debug('Retrieving Nova Client')
38 return Client(os_creds.compute_api_version, session=keystone_utils.keystone_session(os_creds))
41 def get_servers_by_name(nova, name):
43 Returns a list of servers with a given name
44 :param nova: the Nova client
45 :param name: the server name
46 :return: the list of servers
48 return nova.servers.list(search_opts={'name': name})
51 def get_latest_server_object(nova, server):
53 Returns a server with a given id
54 :param nova: the Nova client
55 :param server: the old server object
56 :return: the list of servers or None if not found
58 return nova.servers.get(server)
61 def save_keys_to_files(keys=None, pub_file_path=None, priv_file_path=None):
63 Saves the generated RSA generated keys to the filesystem
64 :param keys: the keys to save
65 :param pub_file_path: the path to the public keys
66 :param priv_file_path: the path to the private keys
71 pub_dir = os.path.dirname(pub_file_path)
72 if not os.path.isdir(pub_dir):
74 public_handle = open(pub_file_path, 'wb')
75 public_handle.write(keys.publickey().exportKey('OpenSSH'))
77 os.chmod(pub_file_path, 0o400)
78 logger.info("Saved public key to - " + pub_file_path)
80 priv_dir = os.path.dirname(priv_file_path)
81 if not os.path.isdir(priv_dir):
83 private_handle = open(priv_file_path, 'wb')
84 private_handle.write(keys.exportKey())
85 private_handle.close()
86 os.chmod(priv_file_path, 0o400)
87 logger.info("Saved private key to - " + priv_file_path)
90 def upload_keypair_file(nova, name, file_path):
92 Uploads a public key from a file
93 :param nova: the Nova client
94 :param name: the keypair name
95 :param file_path: the path to the public key file
96 :return: the keypair object
98 with open(os.path.expanduser(file_path)) as fpubkey:
99 logger.info('Saving keypair to - ' + file_path)
100 return upload_keypair(nova, name, fpubkey.read())
103 def upload_keypair(nova, name, key):
105 Uploads a public key from a file
106 :param nova: the Nova client
107 :param name: the keypair name
108 :param key: the public key object
109 :return: the keypair object
111 logger.info('Creating keypair with name - ' + name)
112 return nova.keypairs.create(name=name, public_key=key)
115 def keypair_exists(nova, keypair_obj):
117 Returns a copy of the keypair object if found
118 :param nova: the Nova client
119 :param keypair_obj: the keypair object
120 :return: the keypair object or None if not found
123 return nova.keypairs.get(keypair_obj)
128 def get_keypair_by_name(nova, name):
130 Returns a list of all available keypairs
131 :param nova: the Nova client
132 :param name: the name of the keypair to lookup
133 :return: the keypair object or None if not found
135 keypairs = nova.keypairs.list()
137 for keypair in keypairs:
138 if keypair.name == name:
144 def delete_keypair(nova, key):
146 Deletes a keypair object from OpenStack
147 :param nova: the Nova client
148 :param key: the keypair object to delete
150 logger.debug('Deleting keypair - ' + key.name)
151 nova.keypairs.delete(key)
154 def get_floating_ip_pools(nova):
156 Returns all of the available floating IP pools
157 :param nova: the Nova client
158 :return: a list of pools
160 return nova.floating_ip_pools.list()
163 def get_floating_ips(nova):
165 Returns all of the floating IPs
166 :param nova: the Nova client
167 :return: a list of floating IPs
169 return nova.floating_ips.list()
172 def create_floating_ip(nova, ext_net_name):
174 Returns the floating IP object that was created with this call
175 :param nova: the Nova client
176 :param ext_net_name: the name of the external network on which to apply the floating IP address
177 :return: the floating IP object
179 logger.info('Creating floating ip to external network - ' + ext_net_name)
180 return nova.floating_ips.create(ext_net_name)
183 def get_floating_ip(nova, floating_ip):
185 Returns a floating IP object that should be identical to the floating_ip parameter
186 :param nova: the Nova client
187 :param floating_ip: the floating IP object to lookup
188 :return: hopefully the same floating IP object input
190 logger.debug('Attempting to retrieve existing floating ip with IP - ' + floating_ip.ip)
191 return nova.floating_ips.get(floating_ip)
194 def delete_floating_ip(nova, floating_ip):
196 Responsible for deleting a floating IP
197 :param nova: the Nova client
198 :param floating_ip: the floating IP object to delete
201 logger.debug('Attempting to delete existing floating ip with IP - ' + floating_ip.ip)
202 return nova.floating_ips.delete(floating_ip)
205 def get_nova_availability_zones(nova):
207 Returns the names of all nova compute servers
208 :param nova: the Nova client
209 :return: a list of compute server names
212 zones = nova.availability_zones.list()
214 if zone.zoneName == 'nova':
215 for key, host in zone.hosts.iteritems():
216 out.append(zone.zoneName + ':' + key)
221 def delete_vm_instance(nova, vm_inst):
223 Deletes a VM instance
224 :param nova: the nova client
225 :param vm_inst: the OpenStack instance object to delete
227 nova.servers.delete(vm_inst)
230 def get_flavor_by_name(nova, name):
232 Returns a flavor by name
233 :param nova: the Nova client
234 :param name: the flavor name to return
235 :return: the OpenStack flavor object or None if not exists
238 return nova.flavors.find(name=name)
243 def create_flavor(nova, flavor_settings):
245 Creates and returns and OpenStack flavor object
246 :param nova: the Nova client
247 :param flavor_settings: the flavor settings
250 return nova.flavors.create(name=flavor_settings.name, flavorid=flavor_settings.flavor_id, ram=flavor_settings.ram,
251 vcpus=flavor_settings.vcpus, disk=flavor_settings.disk,
252 ephemeral=flavor_settings.ephemeral, swap=flavor_settings.swap,
253 rxtx_factor=flavor_settings.rxtx_factor, is_public=flavor_settings.is_public)
256 def delete_flavor(nova, flavor):
259 :param nova: the Nova client
260 :param flavor: the OpenStack flavor object
262 nova.flavors.delete(flavor)
265 def add_security_group(nova, vm, security_group_name):
267 Adds a security group to an existing VM
268 :param nova: the nova client
269 :param vm: the OpenStack server object (VM) to alter
270 :param security_group_name: the name of the security group to add
272 nova.servers.add_security_group(str(vm.id), security_group_name)
275 def remove_security_group(nova, vm, security_group):
277 Removes a security group from an existing VM
278 :param nova: the nova client
279 :param vm: the OpenStack server object (VM) to alter
280 :param security_group: the OpenStack security group object to add
282 nova.servers.remove_security_group(str(vm.id), security_group['security_group']['name'])