Modified code to support both Python 2.7 and 3.x
[snaps.git] / snaps / openstack / utils / nova_utils.py
index e7428ed..419f451 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2016 Cable Television Laboratories, Inc. ("CableLabs")
+# Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
 #                    and others.  All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # 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
-import keystone_utils
+from snaps.openstack.utils import keystone_utils
 
 from novaclient.client import Client
 from novaclient.exceptions import NotFound
@@ -58,10 +63,29 @@ def get_latest_server_object(nova, server):
     return nova.servers.get(server)
 
 
+def create_keys(key_size=2048):
+    """
+    Generates public and private keys
+    :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,
+                                    key_size=key_size)
+
+
+def public_key_openssh(keys):
+    """
+    Returns the public key for OpenSSH
+    :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)
+
+
 def save_keys_to_files(keys=None, pub_file_path=None, priv_file_path=None):
     """
     Saves the generated RSA generated keys to the filesystem
-    :param keys: the keys to save
+    :param keys: the keys to save generated by cryptography
     :param pub_file_path: the path to the public keys
     :param priv_file_path: the path to the private keys
     :return: None
@@ -72,7 +96,9 @@ def save_keys_to_files(keys=None, pub_file_path=None, priv_file_path=None):
             if not os.path.isdir(pub_dir):
                 os.mkdir(pub_dir)
             public_handle = open(pub_file_path, 'wb')
-            public_handle.write(keys.publickey().exportKey('OpenSSH'))
+            public_bytes = keys.public_key().public_bytes(
+                serialization.Encoding.OpenSSH, serialization.PublicFormat.OpenSSH)
+            public_handle.write(public_bytes)
             public_handle.close()
             os.chmod(pub_file_path, 0o400)
             logger.info("Saved public key to - " + pub_file_path)
@@ -81,7 +107,9 @@ 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.exportKey())
+            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)
@@ -95,7 +123,7 @@ def upload_keypair_file(nova, name, file_path):
     :param file_path: the path to the public key file
     :return: the keypair object
     """
-    with open(os.path.expanduser(file_path)) as fpubkey:
+    with open(os.path.expanduser(file_path), 'rb') as fpubkey:
         logger.info('Saving keypair to - ' + file_path)
         return upload_keypair(nova, name, fpubkey.read())
 
@@ -109,7 +137,7 @@ def upload_keypair(nova, name, key):
     :return: the keypair object
     """
     logger.info('Creating keypair with name - ' + name)
-    return nova.keypairs.create(name=name, public_key=key)
+    return nova.keypairs.create(name=name, public_key=key.decode('utf-8'))
 
 
 def keypair_exists(nova, keypair_obj):
@@ -212,7 +240,7 @@ def get_nova_availability_zones(nova):
     zones = nova.availability_zones.list()
     for zone in zones:
         if zone.zoneName == 'nova':
-            for key, host in zone.hosts.iteritems():
+            for key, host in zone.hosts.items():
                 out.append(zone.zoneName + ':' + key)
 
     return out