示例#1
0
    def delete_volume(self, volume):
        try:
            volume_name = self._get_3par_vol_name(volume['id'])
            # Try and delete the volume, it might fail here because
            # the volume is part of a volume set which will have the
            # volume set name in the error.
            try:
                self.client.deleteVolume(volume_name)
            except hpexceptions.HTTPBadRequest as ex:
                if ex.get_code() == 29:
                    if self.client.isOnlinePhysicalCopy(volume_name):
                        LOG.debug(_("Found an online copy for %(volume)s")
                                  % {'volume': volume_name})
                        # the volume is in process of being cloned.
                        # stopOnlinePhysicalCopy will also delete
                        # the volume once it stops the copy.
                        self.client.stopOnlinePhysicalCopy(volume_name)
                    else:
                        LOG.error(str(ex))
                        raise ex
                else:
                    LOG.error(str(ex))
                    raise ex
            except hpexceptions.HTTPConflict as ex:
                if ex.get_code() == 34:
                    # This is a special case which means the
                    # volume is part of a volume set.
                    vvset_name = self.client.findVolumeSet(volume_name)
                    LOG.debug("Returned vvset_name = %s" % vvset_name)
                    if vvset_name is not None and \
                       vvset_name.startswith('vvs-'):
                        # We have a single volume per volume set, so
                        # remove the volume set.
                        self.client.deleteVolumeSet(
                            self._get_3par_vvs_name(volume['id']))
                    elif vvset_name is not None:
                        # We have a pre-defined volume set just remove the
                        # volume and leave the volume set.
                        self.client.removeVolumeFromVolumeSet(vvset_name,
                                                              volume_name)
                    self.client.deleteVolume(volume_name)
                else:
                    LOG.error(str(ex))
                    raise ex

        except hpexceptions.HTTPNotFound as ex:
            # We'll let this act as if it worked
            # it helps clean up the cinder entries.
            msg = _("Delete volume id not found. Removing from cinder: "
                    "%(id)s Ex: %(msg)s") % {'id': volume['id'], 'msg': ex}
            LOG.warning(msg)
        except hpexceptions.HTTPForbidden as ex:
            LOG.error(str(ex))
            raise exception.NotAuthorized(ex.get_description())
        except hpexceptions.HTTPConflict as ex:
            LOG.error(str(ex))
            raise exception.VolumeIsBusy(ex.get_description())
        except Exception as ex:
            LOG.error(str(ex))
            raise exception.CinderException(ex)
示例#2
0
    def create_volume_from_snapshot(self, volume, snapshot, client):
        """
        Creates a volume from a snapshot.

        TODO: support using the size from the user.
        """
        LOG.debug("Create Volume from Snapshot\n%s\n%s" % (pprint.pformat(
            volume['display_name']), pprint.pformat(snapshot['display_name'])))

        if snapshot['volume_size'] != volume['size']:
            err = "You cannot change size of the volume.  It must "
            "be the same as the snapshot."
            LOG.error(err)
            raise exception.InvalidInput(reason=err)

        try:
            snap_name = self._get_3par_snap_name(snapshot['id'])
            vol_name = self._get_3par_vol_name(volume['id'])

            extra = {'volume_id': volume['id'], 'snapshot_id': snapshot['id']}
            name = snapshot.get('display_name', None)
            if name:
                extra['name'] = name

            description = snapshot.get('display_description', None)
            if description:
                extra['description'] = description

            optional = {'comment': json.dumps(extra), 'readOnly': False}

            client.createSnapshot(vol_name, snap_name, optional)
        except hpexceptions.HTTPForbidden:
            raise exception.NotAuthorized()
        except hpexceptions.HTTPNotFound:
            raise exception.NotFound()
示例#3
0
    def _get_barbican_client(self, ctxt):
        """Creates a client to connect to the Barbican service.

        :param ctxt: the user context for authentication
        :return: a Barbican Client object
        :throws NotAuthorized: if the ctxt is None
        :throws KeyManagerError: if ctxt is missing project_id
                                 or project_id is None
        """

        if not self._barbican_client:
            # Confirm context is provided, if not raise not authorized
            if not ctxt:
                msg = _("User is not authorized to use key manager.")
                LOG.error(msg)
                raise exception.NotAuthorized(msg)

            if not hasattr(ctxt, 'project_id') or ctxt.project_id is None:
                msg = _("Unable to create Barbican Client without project_id.")
                LOG.error(msg)
                raise exception.KeyManagerError(msg)

            try:
                auth = identity.v3.Token(
                    auth_url=CONF.keymgr.encryption_auth_url,
                    token=ctxt.auth_token,
                    project_id=ctxt.project_id)
                sess = session.Session(auth=auth)
                self._barbican_client = barbican_client.Client(
                    session=sess, endpoint=self._barbican_endpoint)
            except Exception:
                with excutils.save_and_reraise_exception():
                    LOG.exception(_LE("Error creating Barbican client."))

        return self._barbican_client
示例#4
0
    def _create_connection(self, ctxt):
        """Creates a connection to the Barbican service.

        :param ctxt: the user context for authentication
        :return: a Barbican Connection object
        :throws NotAuthorized: if the ctxt is None
        """

        # Confirm context is provided, if not raise not authorized
        if not ctxt:
            msg = _("User is not authorized to use key manager.")
            LOG.error(msg)
            raise exception.NotAuthorized(msg)

        try:
            endpoint = CONF.keymgr.encryption_auth_url
            keystone = keystone_client.Client(token=ctxt.auth_token,
                                              endpoint=endpoint)
            keystone_auth = auth.KeystoneAuthV2(keystone=keystone)
            keystone_auth._barbican_url = CONF.keymgr.encryption_api_url
            connection = barbican_client.Client(auth_plugin=keystone_auth)
            return connection
        except Exception as e:
            with excutils.save_and_reraise_exception():
                LOG.error(_("Error creating Barbican client: %s"), (e))
示例#5
0
    def _get_barbican_client(self, ctxt):
        """Creates a client to connect to the Barbican service.

        :param ctxt: the user context for authentication
        :return: a Barbican Client object
        :throws NotAuthorized: if the ctxt is None
        """

        if not self._barbican_client:
            # Confirm context is provided, if not raise not authorized
            if not ctxt:
                msg = _("User is not authorized to use key manager.")
                LOG.error(msg)
                raise exception.NotAuthorized(msg)

            try:
                auth = identity.v3.Token(
                    auth_url=CONF.keymgr.encryption_auth_url,
                    token=ctxt.auth_token)
                sess = session.Session(auth=auth)
                self._barbican_client = barbican_client.Client(
                    session=sess, endpoint=self._barbican_endpoint)
            except Exception as e:
                with excutils.save_and_reraise_exception():
                    LOG.error(_("Error creating Barbican client: %s"), (e))

        return self._barbican_client
示例#6
0
    def copy_key(self, ctxt, key_id, **kwargs):
        if ctxt is None:
            raise exception.NotAuthorized()

        copied_key_id = self._generate_key_id()
        self.keys[copied_key_id] = self.keys[key_id]

        return copied_key_id
示例#7
0
def _translate_plain_exception(exc_value):
    if isinstance(exc_value, (glanceclient.exc.Forbidden,
                              glanceclient.exc.Unauthorized)):
        return exception.NotAuthorized(exc_value)
    if isinstance(exc_value, glanceclient.exc.NotFound):
        return exception.NotFound(exc_value)
    if isinstance(exc_value, glanceclient.exc.BadRequest):
        return exception.Invalid(exc_value)
    return exc_value
示例#8
0
    def delete_key(self, ctxt, key_id, **kwargs):
        if ctxt is None:
            raise exception.NotAuthorized()

        if key_id != self.key_id:
            raise exception.KeyManagerError(
                reason="cannot delete non-existent key")

        LOG.warn(_("Not deleting key %s"), key_id)
示例#9
0
    def store_key(self, ctxt, key, **kwargs):
        """Stores (i.e., registers) a key with the key manager."""
        if ctxt is None:
            raise exception.NotAuthorized()

        key_id = self._generate_key_id()
        self.keys[key_id] = key

        return key_id
示例#10
0
    def store(self, context, managed_object, **kwargs):
        """Stores (i.e., registers) a key with the key manager."""
        if context is None:
            raise exception.NotAuthorized()

        if managed_object != self._get_key():
            raise exception.KeyManagerError(
                reason="cannot store arbitrary keys")

        return self.key_id
示例#11
0
    def store_key(self, ctxt, key, **kwargs):
        """Stores (i.e., registers) a key with the key manager."""
        if ctxt is None:
            raise exception.NotAuthorized()

        if key != self._generate_key():
            raise exception.KeyManagerError(
                reason="cannot store arbitrary keys")

        return self.key_id
示例#12
0
    def create_key(self, ctxt, **kwargs):
        """Creates a key.

        This implementation returns a UUID for the created key. A
        NotAuthorized exception is raised if the specified context is None.
        """
        if ctxt is None:
            raise exception.NotAuthorized()

        return self.key_id
示例#13
0
    def delete_key(self, ctxt, key_id, **kwargs):
        """Deletes the key identified by the specified id.

        A NotAuthorized exception is raised if the context is None and a
        KeyError is raised if the UUID is invalid.
        """
        if ctxt is None:
            raise exception.NotAuthorized()

        del self.keys[key_id]
示例#14
0
    def delete_snapshot(self, snapshot, client):
        LOG.debug("Delete Snapshot\n%s" % pprint.pformat(snapshot))

        try:
            snap_name = self._get_3par_snap_name(snapshot['id'])
            client.deleteVolume(snap_name)
        except hpexceptions.HTTPForbidden:
            raise exception.NotAuthorized()
        except hpexceptions.HTTPNotFound as ex:
            LOG.error(str(ex))
示例#15
0
    def get_key(self, ctxt, key_id, **kwargs):
        """Retrieves the key identified by the specified id.

        This implementation returns the key that is associated with the
        specified UUID. A NotAuthorized exception is raised if the specified
        context is None; a KeyError is raised if the UUID is invalid.
        """
        if ctxt is None:
            raise exception.NotAuthorized()

        return self.keys[key_id]
示例#16
0
    def create_key(self, context, **kwargs):
        """Creates a symmetric key.

        This implementation returns a UUID for the key read from the
        configuration file. A NotAuthorized exception is raised if the
        specified context is None.
        """
        if context is None:
            raise exception.NotAuthorized()

        return self.key_id
示例#17
0
    def get(self, context, managed_object_id):
        """Retrieves the key identified by the specified id.

        This implementation returns the key that is associated with the
        specified UUID. A NotAuthorized exception is raised if the specified
        context is None; a KeyError is raised if the UUID is invalid.
        """
        if context is None:
            raise exception.NotAuthorized()

        if managed_object_id != self.key_id:
            raise KeyError(str(managed_object_id) + " != " + str(self.key_id))

        return self._get_key()
示例#18
0
    def store_key(self, ctxt, key, **kwargs):
        """Stores (i.e., registers) a key with the key manager.
        """
        if ctxt is None:
            raise exception.NotAuthorized()

        # generate UUID and ensure that it isn't in use
        key_id = uuidutils.generate_uuid()
        while key_id in self.keys:
            key_id = uuidutils.generate_uuid()

        self.keys[key_id] = key

        return key_id
示例#19
0
 def delete_volume(self, volume, client):
     try:
         volume_name = self._get_3par_vol_name(volume['id'])
         client.deleteVolume(volume_name)
     except hpexceptions.HTTPNotFound as ex:
         # We'll let this act as if it worked
         # it helps clean up the cinder entries.
         LOG.error(str(ex))
     except hpexceptions.HTTPForbidden as ex:
         LOG.error(str(ex))
         raise exception.NotAuthorized(ex.get_description())
     except Exception as ex:
         LOG.error(str(ex))
         raise exception.CinderException(ex.get_description())
示例#20
0
    def list(self, context, object_type=None, metadata_only=False):
        """Retrieves a list of managed objects that match the criteria.

        Note: Required abstract method starting with Castellan 0.13.0

        :param context: Contains information of the user and the environment
                        for the request.
        :param object_type: The type of object to retrieve.
        :param metadata_only: Whether secret data should be included.
        :raises NotAuthorized: If no user context.
        """
        if context is None:
            raise exception.NotAuthorized()

        return []
示例#21
0
    def delete(self, context, managed_object_id):
        """Represents deleting the key.

        Because the ConfKeyManager has only one key, which is read from the
        configuration file, the key is not actually deleted when this is
        called.
        """
        if context is None:
            raise exception.NotAuthorized()

        if managed_object_id != self.key_id:
            raise exception.KeyManagerError(
                reason="cannot delete non-existent key")

        LOG.warning("Not deleting key %s", managed_object_id)
示例#22
0
    def create_key(self, ctxt, **kwargs):
        """Creates a key.

        This implementation returns a UUID for the created key. A
        NotAuthorized exception is raised if the specified context is None.
        """
        if ctxt is None:
            raise exception.NotAuthorized()

        # generate the key
        key_length = kwargs.get('key_length', 256)
        # hex digit => 4 bits
        hex_string = utils.generate_password(length=key_length / 4,
                                             symbolgroups='0123456789ABCDEF')

        _bytes = array.array('B', hex_string.decode('hex')).tolist()
        _key = key.SymmetricKey('AES', _bytes)

        return self.store_key(ctxt, _key)
示例#23
0
    def delete_snapshot(self, snapshot):
        LOG.debug("Delete Snapshot id %s %s" % (snapshot['id'],
                                                pprint.pformat(snapshot)))

        try:
            snap_name = self._get_3par_snap_name(snapshot['id'])
            self.client.deleteVolume(snap_name)
        except hpexceptions.HTTPForbidden as ex:
            LOG.error(str(ex))
            raise exception.NotAuthorized()
        except hpexceptions.HTTPNotFound as ex:
            # We'll let this act as if it worked
            # it helps clean up the cinder entries.
            msg = _("Delete Snapshot id not found. Removing from cinder: "
                    "%(id)s Ex: %(msg)s") % {'id': snapshot['id'], 'msg': ex}
            LOG.warning(msg)
        except hpexceptions.HTTPConflict as ex:
            LOG.error(str(ex))
            raise exception.SnapshotIsBusy(snapshot_name=snapshot['id'])
示例#24
0
 def _handle_bad_status(self,
                        response,
                        connection_string,
                        method,
                        payload,
                        header,
                        cert_data,
                        sensitive=False,
                        conflict_ok=False):
     if (response.status_code == http_client.BAD_REQUEST
             and connection_string.endswith("api_versions")):
         # Raise the exception, but don't log any error.  We'll just fall
         # back to the old style of determining API version.  We make this
         # request a lot, so logging it is just noise
         raise exception.DateraAPIException
     if not sensitive:
         LOG.debug(("Datera Response URL: %s\n"
                    "Datera Response Payload: %s\n"
                    "Response Object: %s\n"), response.url, payload,
                   vars(response))
     if response.status_code == http_client.NOT_FOUND:
         raise exception.NotFound(response.json()['message'])
     elif response.status_code in [
             http_client.FORBIDDEN, http_client.UNAUTHORIZED
     ]:
         raise exception.NotAuthorized()
     elif response.status_code == http_client.CONFLICT and conflict_ok:
         # Don't raise, because we're expecting a conflict
         pass
     elif response.status_code == http_client.SERVICE_UNAVAILABLE:
         current_retry = 0
         while current_retry <= self.retry_attempts:
             LOG.debug("Datera 503 response, trying request again")
             eventlet.sleep(self.interval)
             resp = self._request(connection_string, method, payload,
                                  header, cert_data)
             if resp.ok:
                 return response.json()
             elif resp.status_code != http_client.SERVICE_UNAVAILABLE:
                 self._raise_response(resp)
     else:
         self._raise_response(response)
示例#25
0
    def _authenticate_access(self, address, username, password):
        session = requests.session()
        session.verify = self.verify
        session.auth = NoAuth()

        # Here 'address' will be only IPv4.
        response = session.post('https://%s:%s/api/rest/authenticate'
                                % (address, self._port),
                                data={'username': username,
                                      'password': password})
        if response.status_code != http_client.OK:
            LOG.error('Failed to authenticate to remote cluster at %s as %s.',
                      address, username)
            raise exception.NotAuthorized(_('Authentication failure.'))
        result = response.json()
        session.headers.update({'Authorization': 'Bearer {}'
                                .format(result['token'])})
        session.headers.update({'Content-Type': 'application/json'})

        return session
示例#26
0
    def create_cloned_volume(self, volume, src_vref):
        try:
            orig_name = self._get_3par_vol_name(volume['source_volid'])
            vol_name = self._get_3par_vol_name(volume['id'])

            type_info = self.get_volume_settings_from_type(volume)

            # make the 3PAR copy the contents.
            # can't delete the original until the copy is done.
            self._copy_volume(orig_name, vol_name, cpg=type_info['cpg'],
                              snap_cpg=type_info['snap_cpg'],
                              tpvv=type_info['tpvv'])
            return None
        except hpexceptions.HTTPForbidden:
            raise exception.NotAuthorized()
        except hpexceptions.HTTPNotFound:
            raise exception.NotFound()
        except Exception as ex:
            LOG.error(str(ex))
            raise exception.CinderException(ex)
示例#27
0
    def create_cloned_volume(self, volume, src_vref, client):

        try:
            orig_name = self._get_3par_vol_name(volume['source_volid'])
            vol_name = self._get_3par_vol_name(volume['id'])
            # We need to create a new volume first.  Otherwise you
            # can't delete the original
            new_vol = self.create_volume(volume, client)

            # make the 3PAR copy the contents.
            # can't delete the original until the copy is done.
            self._copy_volume(orig_name, vol_name)

            # this can take a long time to complete
            done = False
            while not done:
                status = self._get_volume_state(vol_name)
                if status == 'normal':
                    done = True
                elif status == 'copy_target':
                    LOG.debug("3Par still copying %s => %s" %
                              (orig_name, vol_name))
                else:
                    msg = _("Unexpected state while cloning %s") % status
                    LOG.warn(msg)
                    raise exception.CinderException(msg)

                if not done:
                    # wait 5 seconds between tests
                    time.sleep(5)

            return new_vol
        except hpexceptions.HTTPForbidden:
            raise exception.NotAuthorized()
        except hpexceptions.HTTPNotFound:
            raise exception.NotFound()
        except Exception as ex:
            LOG.error(str(ex))
            raise exception.CinderException(ex)

        return None
示例#28
0
 def delete_volume(self, volume):
     try:
         volume_name = self._get_3par_vol_name(volume['id'])
         vol_comment = self._get_3par_vol_comment(volume_name)
         qos = self._get_3par_vol_comment_value(vol_comment, 'qos')
         vvs_name = self._get_3par_vol_comment_value(vol_comment, 'vvs')
         if vvs_name is not None:
             self._remove_volume_from_volume_set(volume_name, vvs_name)
         elif qos is not None:
             self._remove_volume_set(self._get_3par_vvs_name(volume['id']))
         self.client.deleteVolume(volume_name)
     except hpexceptions.HTTPNotFound as ex:
         # We'll let this act as if it worked
         # it helps clean up the cinder entries.
         LOG.error(str(ex))
     except hpexceptions.HTTPForbidden as ex:
         LOG.error(str(ex))
         raise exception.NotAuthorized(ex.get_description())
     except Exception as ex:
         LOG.error(str(ex))
         raise exception.CinderException(ex.get_description())
    def delete_volume(self, volume):
        try:
            volume_name = self._get_3par_vol_name(volume['id'])
            # Try and delete the volume, it might fail here because
            # the volume is part of a volume set which will have the
            # volume set name in the error.
            try:
                self.client.deleteVolume(volume_name)
            except hpexceptions.HTTPConflict as ex:
                if ex.get_code() == 34:
                    # This is a special case which means the
                    # volume is part of a volume set.
                    vvset_name = self._get_vvset_from_3par(volume_name)
                    LOG.debug("Returned vvset_name = %s" % vvset_name)
                    if vvset_name is not None and \
                       vvset_name.startswith('vvs-'):
                        # We have a single volume per volume set, so
                        # remove the volume set.
                        self._remove_volume_set(
                            self._get_3par_vvs_name(volume['id']))
                    elif vvset_name is not None:
                        # We have a pre-defined volume set just remove the
                        # volume and leave the volume set.
                        self._remove_volume_from_volume_set(
                            volume_name, vvset_name)
                    self.client.deleteVolume(volume_name)
                else:
                    LOG.error(str(ex))
                    raise ex

        except hpexceptions.HTTPNotFound as ex:
            # We'll let this act as if it worked
            # it helps clean up the cinder entries.
            LOG.error(str(ex))
        except hpexceptions.HTTPForbidden as ex:
            LOG.error(str(ex))
            raise exception.NotAuthorized(ex.get_description())
        except Exception as ex:
            LOG.error(str(ex))
            raise exception.CinderException(ex)
示例#30
0
    def create_snapshot(self, snapshot):
        LOG.debug("Create Snapshot\n%s" % pprint.pformat(snapshot))

        try:
            snap_name = self._get_3par_snap_name(snapshot['id'])
            vol_name = self._get_3par_vol_name(snapshot['volume_id'])

            extra = {'volume_name': snapshot['volume_name']}
            vol_id = snapshot.get('volume_id', None)
            if vol_id:
                extra['volume_id'] = vol_id

            try:
                extra['display_name'] = snapshot['display_name']
            except AttributeError:
                pass

            try:
                extra['description'] = snapshot['display_description']
            except AttributeError:
                pass

            optional = {'comment': json.dumps(extra),
                        'readOnly': True}
            if self.config.hp3par_snapshot_expiration:
                optional['expirationHours'] = (
                    self.config.hp3par_snapshot_expiration)

            if self.config.hp3par_snapshot_retention:
                optional['retentionHours'] = (
                    self.config.hp3par_snapshot_retention)

            self.client.createSnapshot(snap_name, vol_name, optional)
        except hpexceptions.HTTPForbidden as ex:
            LOG.error(str(ex))
            raise exception.NotAuthorized()
        except hpexceptions.HTTPNotFound as ex:
            LOG.error(str(ex))
            raise exception.NotFound()