summaryrefslogtreecommitdiffstats
path: root/snaps/openstack/utils/nova_utils.py
diff options
context:
space:
mode:
authorspisarski <s.pisarski@cablelabs.com>2017-06-22 12:43:09 -0600
committerspisarski <s.pisarski@cablelabs.com>2017-06-22 14:28:08 -0600
commitc7ba89444d160cb81656a49cb93416ee5013aa8f (patch)
tree0f46d74f98e17e256c3e1eb9a592c3bcc29044e8 /snaps/openstack/utils/nova_utils.py
parentdbfb9c4e94e500592a8b93f42b7b87230d0af311 (diff)
Use neutron to create floating IPs.
This patch moves the floating IP creation out of nova and into neutron. Other changes include the use of domain objects for VM and Floating IP instances, addition of new nova_utils tests to exercise the create server functionality, and more PEP8 compliance. JIRA: SNAPS-92 Change-Id: I16c12b26b56008901633e90ae307586ad2045f9b Signed-off-by: spisarski <s.pisarski@cablelabs.com>
Diffstat (limited to 'snaps/openstack/utils/nova_utils.py')
-rw-r--r--snaps/openstack/utils/nova_utils.py192
1 files changed, 118 insertions, 74 deletions
diff --git a/snaps/openstack/utils/nova_utils.py b/snaps/openstack/utils/nova_utils.py
index a1b959a..90eec13 100644
--- a/snaps/openstack/utils/nova_utils.py
+++ b/snaps/openstack/utils/nova_utils.py
@@ -13,16 +13,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from cryptography.hazmat.primitives import serialization
-from cryptography.hazmat.primitives.asymmetric import rsa
-from cryptography.hazmat.backends import default_backend
-
-import os
import logging
-from snaps.openstack.utils import keystone_utils
+import os
+from cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives import serialization
+from cryptography.hazmat.primitives.asymmetric import rsa
from novaclient.client import Client
from novaclient.exceptions import NotFound
+from snaps.domain.vm_inst import VmInst
+from snaps.openstack.utils import keystone_utils, glance_utils, neutron_utils
__author__ = 'spisarski'
@@ -35,12 +35,69 @@ Utilities for basic OpenStack Nova API calls
def nova_client(os_creds):
"""
- Instantiates and returns a client for communications with OpenStack's Nova server
+ Instantiates and returns a client for communications with OpenStack's Nova
+ server
:param os_creds: The connection credentials to the OpenStack API
:return: the client object
"""
logger.debug('Retrieving Nova Client')
- return Client(os_creds.compute_api_version, session=keystone_utils.keystone_session(os_creds))
+ return Client(os_creds.compute_api_version,
+ session=keystone_utils.keystone_session(os_creds))
+
+
+def create_server(nova, neutron, glance, instance_settings, image_settings,
+ keypair_settings=None):
+ """
+ Creates a VM instance
+ :param nova: the nova client (required)
+ :param neutron: the neutron client for retrieving ports (required)
+ :param glance: the glance client (required)
+ :param instance_settings: the VM instance settings object (required)
+ :param image_settings: the VM's image settings object (required)
+ :param keypair_settings: the VM's keypair settings object (optional)
+ :return: a snaps.domain.VmInst object
+ """
+
+ ports = list()
+
+ for port_setting in instance_settings.port_settings:
+ ports.append(neutron_utils.get_port_by_name(
+ neutron, port_setting.name))
+ nics = []
+ for port in ports:
+ kv = dict()
+ kv['port-id'] = port['port']['id']
+ nics.append(kv)
+
+ logger.info('Creating VM with name - ' + instance_settings.name)
+ keypair_name = None
+ if keypair_settings:
+ keypair_name = keypair_settings.name
+
+ flavor = get_flavor_by_name(nova, instance_settings.flavor)
+ if not flavor:
+ raise Exception(
+ 'Flavor not found with name - %s',
+ instance_settings.flavor)
+
+ image = glance_utils.get_image(glance, image_settings.name)
+ if image:
+ args = {'name': instance_settings.name,
+ 'flavor': flavor,
+ 'image': image,
+ 'nics': nics,
+ 'key_name': keypair_name,
+ 'security_groups':
+ instance_settings.security_group_names,
+ 'userdata': instance_settings.userdata,
+ 'availability_zone':
+ instance_settings.availability_zone}
+ server = nova.servers.create(**args)
+ return VmInst(name=server.name, inst_id=server.id)
+ else:
+ raise Exception(
+ 'Cannot create instance, image cannot be located with name %s',
+ image_settings.name)
def get_servers_by_name(nova, name):
@@ -50,7 +107,21 @@ def get_servers_by_name(nova, name):
:param name: the server name
:return: the list of servers
"""
- return nova.servers.list(search_opts={'name': name})
+ out = list()
+ servers = nova.servers.list(search_opts={'name': name})
+ for server in servers:
+ out.append(VmInst(name=server.name, inst_id=server.id))
+ return out
+
+
+def get_latest_server_os_object(nova, server):
+ """
+ Returns a server with a given id
+ :param nova: the Nova client
+ :param server: the domain VmInst object
+ :return: the list of servers or None if not found
+ """
+ return nova.servers.get(server.id)
def get_latest_server_object(nova, server):
@@ -60,7 +131,8 @@ def get_latest_server_object(nova, server):
:param server: the old server object
:return: the list of servers or None if not found
"""
- return nova.servers.get(server)
+ server = get_latest_server_os_object(nova, server)
+ return VmInst(name=server.name, inst_id=server.id)
def create_keys(key_size=2048):
@@ -69,7 +141,8 @@ def create_keys(key_size=2048):
:param key_size: the number of bytes for the key size
:return: the cryptography keys
"""
- return rsa.generate_private_key(backend=default_backend(), public_exponent=65537,
+ return rsa.generate_private_key(backend=default_backend(),
+ public_exponent=65537,
key_size=key_size)
@@ -79,7 +152,8 @@ def public_key_openssh(keys):
:param keys: the keys generated by create_keys() from cryptography
:return: the OpenSSH public key
"""
- return keys.public_key().public_bytes(serialization.Encoding.OpenSSH, serialization.PublicFormat.OpenSSH)
+ return keys.public_key().public_bytes(serialization.Encoding.OpenSSH,
+ serialization.PublicFormat.OpenSSH)
def save_keys_to_files(keys=None, pub_file_path=None, priv_file_path=None):
@@ -97,7 +171,8 @@ def save_keys_to_files(keys=None, pub_file_path=None, priv_file_path=None):
os.mkdir(pub_dir)
public_handle = open(pub_file_path, 'wb')
public_bytes = keys.public_key().public_bytes(
- serialization.Encoding.OpenSSH, serialization.PublicFormat.OpenSSH)
+ serialization.Encoding.OpenSSH,
+ serialization.PublicFormat.OpenSSH)
public_handle.write(public_bytes)
public_handle.close()
os.chmod(pub_file_path, 0o400)
@@ -107,9 +182,11 @@ def save_keys_to_files(keys=None, pub_file_path=None, priv_file_path=None):
if not os.path.isdir(priv_dir):
os.mkdir(priv_dir)
private_handle = open(priv_file_path, 'wb')
- private_handle.write(keys.private_bytes(encoding=serialization.Encoding.PEM,
- format=serialization.PrivateFormat.TraditionalOpenSSL,
- encryption_algorithm=serialization.NoEncryption()))
+ private_handle.write(
+ keys.private_bytes(
+ encoding=serialization.Encoding.PEM,
+ format=serialization.PrivateFormat.TraditionalOpenSSL,
+ encryption_algorithm=serialization.NoEncryption()))
private_handle.close()
os.chmod(priv_file_path, 0o400)
logger.info("Saved private key to - " + priv_file_path)
@@ -179,57 +256,6 @@ def delete_keypair(nova, key):
nova.keypairs.delete(key)
-def get_floating_ip_pools(nova):
- """
- Returns all of the available floating IP pools
- :param nova: the Nova client
- :return: a list of pools
- """
- return nova.floating_ip_pools.list()
-
-
-def get_floating_ips(nova):
- """
- Returns all of the floating IPs
- :param nova: the Nova client
- :return: a list of floating IPs
- """
- return nova.floating_ips.list()
-
-
-def create_floating_ip(nova, ext_net_name):
- """
- Returns the floating IP object that was created with this call
- :param nova: the Nova client
- :param ext_net_name: the name of the external network on which to apply the floating IP address
- :return: the floating IP object
- """
- logger.info('Creating floating ip to external network - ' + ext_net_name)
- return nova.floating_ips.create(ext_net_name)
-
-
-def get_floating_ip(nova, floating_ip):
- """
- Returns a floating IP object that should be identical to the floating_ip parameter
- :param nova: the Nova client
- :param floating_ip: the floating IP object to lookup
- :return: hopefully the same floating IP object input
- """
- logger.debug('Attempting to retrieve existing floating ip with IP - ' + floating_ip.ip)
- return nova.floating_ips.get(floating_ip)
-
-
-def delete_floating_ip(nova, floating_ip):
- """
- Responsible for deleting a floating IP
- :param nova: the Nova client
- :param floating_ip: the floating IP object to delete
- :return:
- """
- logger.debug('Attempting to delete existing floating ip with IP - ' + floating_ip.ip)
- return nova.floating_ips.delete(floating_ip)
-
-
def get_nova_availability_zones(nova):
"""
Returns the names of all nova active compute servers
@@ -251,9 +277,9 @@ def delete_vm_instance(nova, vm_inst):
"""
Deletes a VM instance
:param nova: the nova client
- :param vm_inst: the OpenStack instance object to delete
+ :param vm_inst: the snaps.domain.VmInst object
"""
- nova.servers.delete(vm_inst)
+ nova.servers.delete(vm_inst.id)
def get_flavor_by_name(nova, name):
@@ -276,10 +302,15 @@ def create_flavor(nova, flavor_settings):
:param flavor_settings: the flavor settings
:return: the Flavor
"""
- return nova.flavors.create(name=flavor_settings.name, flavorid=flavor_settings.flavor_id, ram=flavor_settings.ram,
- vcpus=flavor_settings.vcpus, disk=flavor_settings.disk,
- ephemeral=flavor_settings.ephemeral, swap=flavor_settings.swap,
- rxtx_factor=flavor_settings.rxtx_factor, is_public=flavor_settings.is_public)
+ return nova.flavors.create(name=flavor_settings.name,
+ flavorid=flavor_settings.flavor_id,
+ ram=flavor_settings.ram,
+ vcpus=flavor_settings.vcpus,
+ disk=flavor_settings.disk,
+ ephemeral=flavor_settings.ephemeral,
+ swap=flavor_settings.swap,
+ rxtx_factor=flavor_settings.rxtx_factor,
+ is_public=flavor_settings.is_public)
def delete_flavor(nova, flavor):
@@ -308,4 +339,17 @@ def remove_security_group(nova, vm, security_group):
:param vm: the OpenStack server object (VM) to alter
:param security_group: the OpenStack security group object to add
"""
- nova.servers.remove_security_group(str(vm.id), security_group['security_group']['name'])
+ nova.servers.remove_security_group(
+ str(vm.id), security_group['security_group']['name'])
+
+
+def add_floating_ip_to_server(nova, vm, floating_ip, ip_addr):
+ """
+ Adds a floating IP to a server instance
+ :param nova: the nova client
+ :param vm: VmInst domain object
+ :param floating_ip: FloatingIp domain object
+ :param ip_addr: the IP to which to bind the floating IP to
+ """
+ vm = get_latest_server_os_object(nova, vm)
+ vm.add_floating_ip(floating_ip.ip, ip_addr)