Пример #1
0
    def __prepare_key_pair(self, key_name, private_key_path, public_key_path, password):
        if not key_name:
            log.warn('user_key_name has not been defined, assuming password-based authentication')
            return

        if key_name in [k.name for k in self.driver.list_key_pairs()]:
            log.info('Key pair `%s` already exists, skipping import.', key_name)
            return

        if public_key_path:
            log.debug("importing public key from file %s ...", public_key_path)
            if not self.driver.import_key_pair_from_file(
                    name=key_name,
                    key_file_path=os.path.expandvars(os.path.expanduser(public_key_path))):
                raise KeypairError(
                    'Could not upload public key {p}'
                    .format(p=public_key_path))
        elif private_key_path:
            if not private_key_path.endswith('.pem'):
                raise KeypairError(
                    'can only work with .pem private keys,'
                    ' derive public key and set user_key_public')
            log.debug("deriving and importing public key from private key")
            self.__import_pem(key_name, private_key_path, password)
        else:
            pem_file_path = os.path.join(self.storage_path, key_name + '.pem')
            if not os.path.exists(pem_file_path):
                with open(pem_file_path, 'w') as new_key_file:
                    new_key_file.write(
                        self.driver.create_key_pair(name=key_name))
            self.__import_pem(key_name, pem_file_path, password)
Пример #2
0
 def __import_pem(self, key_name, pem_file_path, password):
     """
     Import PEM certificate with provider
     :param key_name: name of the key to import
     :param pem_file_path: path to the pem file
     :param password: optional password for the pem file
     """
     key_import = self.__get_function_or_ex_function(
         'import_key_pair_from_file')
     pem_file = os.path.expandvars(os.path.expanduser(pem_file_path))
     try:
         pem = paramiko.RSAKey.from_private_key_file(pem_file, password)
     except SSHException:
         try:
             pem = paramiko.DSSKey.from_private_key_file(pem_file, password)
         except SSHException as e:
             raise KeypairError(
                 'could not import {f}, neither as RSA key nor as DSA key: {e}'
                 .format(f=pem_file_path, e=e))
     if not pem:
         raise KeypairError('could not import {f}'.format(f=pem_file_path))
     else:
         with NamedTemporaryFile('w+t') as f:
             f.write('{n} {p}'.format(n=pem.get_name(), p=pem.get_base64()))
             key_import(name=key_name, key_file_path=f.name)
Пример #3
0
    def _check_keypair(self, name, public_key_path, private_key_path):
        connection = self._connect()
        keypairs = connection.get_all_key_pairs()
        keypairs = dict((k.name, k) for k in keypairs)

        # decide if dsa or rsa key is provided
        pkey = None
        is_dsa_key = False
        try:
            pkey = DSSKey.from_private_key_file(private_key_path)
            is_dsa_key = True
        except PasswordRequiredException:
            log.warning(
                "Unable to check key file `%s` because it is encrypted with a "
                "password. Please, ensure that you added it to the SSH agent "
                "with `ssh-add %s`", private_key_path, private_key_path)
        except SSHException:
            try:
                pkey = RSAKey.from_private_key_file(private_key_path)
            except PasswordRequiredException:
                log.warning(
                    "Unable to check key file `%s` because it is encrypted with a "
                    "password. Please, ensure that you added it to the SSH agent "
                    "with `ssh-add %s`", private_key_path, private_key_path)
            except SSHException:
                raise KeypairError('File `%s` is neither a valid DSA key '
                                   'or RSA key.' % private_key_path)

        # create keys that don't exist yet
        if name not in keypairs:
            log.warning(
                "Keypair `%s` not found on resource `%s`, Creating a new one",
                name, self._url)
            with open(os.path.expanduser(public_key_path)) as f:
                key_material = f.read()
                try:
                    # check for DSA on amazon
                    if "amazon" in self._ec2host and is_dsa_key:
                        log.error(
                            "Apparently, amazon does not support DSA keys. "
                            "Please specify a valid RSA key.")
                        raise KeypairError(
                            "Apparently, amazon does not support DSA keys."
                            "Please specify a valid RSA key.")

                    connection.import_key_pair(name, key_material)
                except Exception, ex:
                    log.error(
                        "Could not import key `%s` with name `%s` to `%s`",
                        name, public_key_path, self._url)
                    raise KeypairError(
                        "could not create keypair `%s`: %s" % (name, ex))
Пример #4
0
    def __prepare_key_pair(self, key_name, private_key_path, public_key_path, password):
        if not key_name:
            log.warn('user_key_name has not been defined, assuming password based authentication')
            return

        try:
            list_key_pairs = self.__get_function_by_pattern('list_key_pairs')
        except AttributeError:
            raise UnsupportedError('key management not supported by provider')
        try:
            self.__get_function_or_ex_function('import_key_pair_from_file')
        except AttributeError:
            raise UnsupportedError('key import not supported by provider')
        try:
            self.__get_function_or_ex_function('create_key_pair')
        except AttributeError:
            raise UnsupportedError('key creation not supported by provider')

        if key_name in [k.name for k in list_key_pairs()]:
            log.info('Key pair (%s) already exists, skipping import.', key_name)
            return

        if public_key_path:
            log.debug("importing public key from path %s", public_key_path)
            key_import = self.__get_function_or_ex_function('import_key_pair_from_file')
            if not key_import(name=key_name, key_file_path=os.path.expandvars(os.path.expanduser(public_key_path))):
                raise KeypairError('failure during import of public key {p}'.format(p=public_key_path))
        elif private_key_path:
            if not private_key_path.endswith('.pem'):
                raise KeypairError('can only work with .pem private keys, derive public key and set user_key_public')
            log.debug("deriving and importing public key from private key")
            self.__import_pem(key_name, private_key_path, password)
        elif os.path.exists(os.path.join(self.storage_path, '{p}.pem'.format(p=key_name))):
            self.__import_pem(key_name, os.path.join(self.storage_path, '{}.pem'.format(key_name)), password)
        else:
            with open(os.path.join(self.storage_path, '{p}.pem'.format(p=key_name)), 'w') as new_key_file:
                new_key_file.write(self.__get_function_or_ex_function('create_key_pair')(name=key_name))
            self.__import_pem(key_name, os.path.join(self.storage_path, '{p}.pem'.format(p=key_name)), password)
Пример #5
0
    def _check_keypair(self, name, public_key_path, private_key_path):
        """First checks if the keypair is valid, then checks if the keypair
        is registered with on the cloud. If not the keypair is added to the
        users ssh keys.

        :param str name: name of the ssh key
        :param str public_key_path: path to the ssh public key file
        :param str private_key_path: path to the ssh private key file

        :raises: `KeypairError` if key is not a valid RSA or DSA key,
                 the key could not be uploaded or the fingerprint does not
                 match to the one uploaded to the cloud.
        """
        self._init_os_api()
        # Read key. We do it as first thing because we need it either
        # way, to check the fingerprint of the remote keypair if it
        # exists already, or to create a new keypair.
        pkey = None
        try:
            pkey = DSSKey.from_private_key_file(private_key_path)
        except PasswordRequiredException:
            warn(
                "Unable to check key file `{0}` because it is encrypted with a "
                "password. Please, ensure that you added it to the SSH agent "
                "with `ssh-add {1}`".format(private_key_path,
                                            private_key_path))
        except SSHException:
            try:
                pkey = RSAKey.from_private_key_file(private_key_path)
            except PasswordRequiredException:
                warn(
                    "Unable to check key file `{0}` because it is encrypted with a "
                    "password. Please, ensure that you added it to the SSH agent "
                    "with `ssh-add {1}`".format(private_key_path,
                                                private_key_path))
            except SSHException:
                raise KeypairError('File `%s` is neither a valid DSA key '
                                   'or RSA key.' % private_key_path)

        try:
            # Check if a keypair `name` exists on the cloud.
            keypair = self.nova_client.keypairs.get(name)

            # Check if it has the correct keypair, but only if we can read the local key
            if pkey:
                fingerprint = str.join(':', (i.encode('hex')
                                             for i in pkey.get_fingerprint()))
                if fingerprint != keypair.fingerprint:
                    raise KeypairError("Keypair `%s` is present but has "
                                       "different fingerprint. Aborting!" %
                                       name)
            else:
                warn(
                    "Unable to check if the keypair is using the correct key.")
        except NotFound:
            log.warning(
                "Keypair `%s` not found on resource `%s`, Creating a new one",
                name, self._os_auth_url)

            # Create a new keypair
            with open(os.path.expanduser(public_key_path)) as f:
                key_material = f.read()
                try:
                    self.nova_client.keypairs.create(name, key_material)
                except Exception as ex:
                    log.error(
                        "Could not import key `%s` with name `%s` to `%s`",
                        name, public_key_path, self._os_auth_url)
                    raise KeypairError("could not create keypair `%s`: %s" %
                                       (name, ex))
Пример #6
0
    def _check_keypair(self, name, public_key_path, private_key_path):
        """First checks if the keypair is valid, then checks if the keypair
        is registered with on the cloud. If not the keypair is added to the
        users ssh keys.

        :param str name: name of the ssh key
        :param str public_key_path: path to the ssh public key file
        :param str private_key_path: path to the ssh private key file

        :raises: `KeypairError` if key is not a valid RSA or DSA key,
                 the key could not be uploaded or the fingerprint does not
                 match to the one uploaded to the cloud.
        """
        connection = self._connect()
        keypairs = connection.get_all_key_pairs()
        keypairs = dict((k.name, k) for k in keypairs)

        # decide if dsa or rsa key is provided
        pkey = None
        is_dsa_key = False
        try:
            pkey = DSSKey.from_private_key_file(private_key_path)
            is_dsa_key = True
        except PasswordRequiredException:
            warn(
                "Unable to check key file `{0}` because it is encrypted with a "
                "password. Please, ensure that you added it to the SSH agent "
                "with `ssh-add {1}`".format(private_key_path,
                                            private_key_path))
        except SSHException:
            try:
                pkey = RSAKey.from_private_key_file(private_key_path)
            except PasswordRequiredException:
                warn(
                    "Unable to check key file `{0}` because it is encrypted with a "
                    "password. Please, ensure that you added it to the SSH agent "
                    "with `ssh-add {1}`".format(private_key_path,
                                                private_key_path))
            except SSHException:
                raise KeypairError('File `%s` is neither a valid DSA key '
                                   'or RSA key.' % private_key_path)

        # create keys that don't exist yet
        if name not in keypairs:
            log.warning(
                "Keypair `%s` not found on resource `%s`, Creating a new one",
                name, self._url)
            with open(os.path.expanduser(public_key_path)) as f:
                key_material = f.read()
                try:
                    # check for DSA on amazon
                    if "amazon" in self._ec2host and is_dsa_key:
                        log.error(
                            "Apparently, amazon does not support DSA keys. "
                            "Please specify a valid RSA key.")
                        raise KeypairError(
                            "Apparently, amazon does not support DSA keys."
                            "Please specify a valid RSA key.")

                    connection.import_key_pair(name, key_material)
                except Exception as ex:
                    log.error(
                        "Could not import key `%s` with name `%s` to `%s`",
                        name, public_key_path, self._url)
                    raise KeypairError("could not create keypair `%s`: %s" %
                                       (name, ex))
        else:
            # check fingerprint
            cloud_keypair = keypairs[name]

            if pkey:
                fingerprint = str.join(':', (i.encode('hex')
                                             for i in pkey.get_fingerprint()))

                if fingerprint != cloud_keypair.fingerprint:
                    if "amazon" in self._ec2host:
                        log.error(
                            "Apparently, Amazon does not compute the RSA key "
                            "fingerprint as we do! We cannot check if the "
                            "uploaded keypair is correct!")
                    else:
                        raise KeypairError("Keypair `%s` is present but has "
                                           "different fingerprint. Aborting!" %
                                           name)
Пример #7
0
            # check fingerprint
            cloud_keypair = keypairs[name]

            if pkey:
                fingerprint = str.join(':', (i.encode('hex')
                                             for i in pkey.get_fingerprint()))

                if fingerprint != cloud_keypair.fingerprint:
                    if "amazon" in self._ec2host:
                        log.error(
                            "Apparently, Amazon does not compute the RSA key "
                            "fingerprint as we do! We cannot check if the "
                            "uploaded keypair is correct!")
                    else:
                        raise KeypairError("Keypair `%s` is present but has "
                                           "different fingerprint. Aborting!" %
                                           name)

    def _check_security_group(self, name):
        """Checks if the security group exists.

        :param str name: name of the security group
        :return: str - security group id of the security group
        :raises: `SecurityGroupError` if group does not exist
        """
        connection = self._connect()

        filters = {}
        if self._vpc:
            filters = {'vpc-id': self._vpc_id}