示例#1
0
    def create(self, req, body):
        """Instruct Cinder to manage a storage object.

        Manages an existing backend storage object (e.g. a Linux logical
        volume or a SAN disk) by creating the Cinder objects required to manage
        it, and possibly renaming the backend storage object
        (driver dependent)

        From an API perspective, this operation behaves very much like a
        volume creation operation, except that properties such as image,
        snapshot and volume references don't make sense, because we are taking
        an existing storage object into Cinder management.

        Required HTTP Body:

        {
         'volume':
          {
           'host': <Cinder host on which the existing storage resides>,
           'ref':  <Driver-specific reference to the existing storage object>,
          }
        }

        See the appropriate Cinder drivers' implementations of the
        manage_volume method to find out the accepted format of 'ref'.

        This API call will return with an error if any of the above elements
        are missing from the request, or if the 'host' element refers to a
        cinder host that is not registered.

        The volume will later enter the error state if it is discovered that
        'ref' is bad.

        Optional elements to 'volume' are:
            name               A name for the new volume.
            description        A description for the new volume.
            volume_type        ID or name of a volume type to associate with
                               the new Cinder volume.  Does not necessarily
                               guarantee that the managed volume will have the
                               properties described in the volume_type.  The
                               driver may choose to fail if it identifies that
                               the specified volume_type is not compatible with
                               the backend storage object.
            metadata           Key/value pairs to be associated with the new
                               volume.
            availability_zone  The availability zone to associate with the new
                               volume.
        """
        context = req.environ['cinder.context']
        authorize(context)

        if not self.is_valid_body(body, 'volume'):
            msg = _("Missing required element '%s' in request body") % 'volume'
            raise exc.HTTPBadRequest(explanation=msg)

        volume = body['volume']

        # Check that the required keys are present, return an error if they
        # are not.
        required_keys = set(['ref', 'host'])
        missing_keys = list(required_keys - set(volume.keys()))

        if missing_keys:
            msg = _("The following elements are required: %s") % \
                ', '.join(missing_keys)
            raise exc.HTTPBadRequest(explanation=msg)

        LOG.debug('Manage volume request body: %s', body)

        kwargs = {}
        req_volume_type = volume.get('volume_type', None)
        if req_volume_type:
            try:
                if not uuidutils.is_uuid_like(req_volume_type):
                    kwargs['volume_type'] = \
                        volume_types.get_volume_type_by_name(
                            context, req_volume_type)
                else:
                    kwargs['volume_type'] = volume_types.get_volume_type(
                        context, req_volume_type)
            except exception.VolumeTypeNotFound:
                msg = _("Volume type not found.")
                raise exc.HTTPNotFound(explanation=msg)
        else:
            kwargs['volume_type'] = {}

        kwargs['name'] = volume.get('name', None)
        kwargs['description'] = volume.get('description', None)
        kwargs['metadata'] = volume.get('metadata', None)
        kwargs['availability_zone'] = volume.get('availability_zone', None)

        try:
            new_volume = self.volume_api.manage_existing(
                context, volume['host'], volume['ref'], **kwargs)
        except exception.ServiceNotFound:
            msg = _("Service not found.")
            raise exc.HTTPNotFound(explanation=msg)

        new_volume = dict(new_volume.iteritems())
        utils.add_visible_admin_metadata(context, new_volume, self.volume_api)

        return self._view_builder.detail(req, new_volume)
示例#2
0
文件: rest.py 项目: mausvt/allura
def nbhd_lookup_first_path(nbhd, name, current_user, remainder, api=False):
    """
    Resolve first part of a neighborhood url.  May raise 404, redirect, or do other side effects.

    Shared between NeighborhoodController and NeighborhoodRestController

    :param nbhd: neighborhood
    :param name: project or tool name (next part of url)
    :param current_user: a User
    :param remainder: remainder of url
    :param bool api: whether this is handling a /rest/ request or not

    :return: project (to be set as c.project)
    :return: remainder (possibly modified)
    """

    prefix = nbhd.shortname_prefix
    pname = unquote(name)
    pname = six.ensure_text(
        pname
    )  # we don't support unicode names, but in case a url comes in with one
    try:
        pname.encode('ascii')
    except UnicodeError:
        raise exc.HTTPNotFound
    provider = plugin.ProjectRegistrationProvider.get()
    try:
        provider.shortname_validator.to_python(pname,
                                               check_allowed=False,
                                               neighborhood=nbhd)
    except Invalid:
        project = None
    else:
        project = M.Project.query.get(shortname=prefix + pname,
                                      neighborhood_id=nbhd._id)
    if project is None and prefix == 'u/':
        # create user-project if it is missing
        user = M.User.query.get(username=pname, disabled=False, pending=False)
        if user:
            project = user.private_project()
    if project is None:
        # look for neighborhood tools matching the URL
        project = nbhd.neighborhood_project
        return project, (
            pname,
        ) + remainder  # include pname in new remainder, it is actually the nbhd tool path
    if project and prefix == 'u/':
        # make sure user-projects are associated with an enabled user
        user = project.user_project_of
        if not user or user.disabled or user.pending:
            raise exc.HTTPNotFound
        if not api and user.url() != '/{}{}/'.format(prefix, pname):
            # might be different URL than the URL requested
            # e.g. if username isn't valid project name and user_project_shortname() converts the name
            new_url = user.url()
            new_url += '/'.join(remainder)
            if request.query_string:
                new_url += '?' + request.query_string
            redirect(new_url)
    if project.database_configured is False:
        if remainder == ('user_icon', ):
            redirect(g.forge_static('images/user.png'))
        elif current_user.username == pname:
            log.info('Configuring %s database for access to %r', pname,
                     remainder)
            project.configure_project(is_user_project=True)
        else:
            raise exc.HTTPNotFound(pname)
    if project is None or (project.deleted
                           and not has_access(project, 'update')()):
        raise exc.HTTPNotFound(pname)
    return project, remainder
示例#3
0
 def default(self, req, **args):
     raise exc.HTTPNotFound()
    def create(self, req, body):
        context = req.environ['nova.context']
        authorize(context)

        if not body:
            raise exc.HTTPUnprocessableEntity()

        if not 'security_group_rule' in body:
            raise exc.HTTPUnprocessableEntity()

        self.compute_api.ensure_default_security_group(context)

        sg_rule = body['security_group_rule']
        parent_group_id = sg_rule.get('parent_group_id', None)
        try:
            parent_group_id = int(parent_group_id)
            security_group = db.security_group_get(context, parent_group_id)
        except ValueError:
            msg = _("Parent group id is not integer")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.NotFound as exp:
            msg = _("Security group (%s) not found") % parent_group_id
            raise exc.HTTPNotFound(explanation=msg)

        msg = _("Authorize security group ingress %s")
        LOG.audit(msg, security_group['name'], context=context)

        try:
            values = self._rule_args_to_dict(context,
                              to_port=sg_rule.get('to_port'),
                              from_port=sg_rule.get('from_port'),
                              parent_group_id=sg_rule.get('parent_group_id'),
                              ip_protocol=sg_rule.get('ip_protocol'),
                              cidr=sg_rule.get('cidr'),
                              group_id=sg_rule.get('group_id'))
        except Exception as exp:
            raise exc.HTTPBadRequest(explanation=unicode(exp))

        if values is None:
            msg = _("Not enough parameters to build a "
                                       "valid rule.")
            raise exc.HTTPBadRequest(explanation=msg)

        values['parent_group_id'] = security_group.id

        if self._security_group_rule_exists(security_group, values):
            msg = _('This rule already exists in group %s') % parent_group_id
            raise exc.HTTPBadRequest(explanation=msg)

        allowed = quota.allowed_security_group_rules(context,
                                                   parent_group_id,
                                                   1)
        if allowed < 1:
            msg = _("Quota exceeded, too many security group rules.")
            raise exc.HTTPBadRequest(explanation=msg)

        security_group_rule = db.security_group_rule_create(context, values)
        self.sgh.trigger_security_group_rule_create_refresh(
            context, [security_group_rule['id']])
        self.compute_api.trigger_security_group_rules_refresh(context,
                                    security_group_id=security_group['id'])

        return {"security_group_rule": self._format_security_group_rule(
                                                        context,
                                                        security_group_rule)}
示例#5
0
    def create(self, req, body):
        """Creates a new volume."""
        if not self.is_valid_body(body, 'volume'):
            msg = _("Missing required element '%s' in request body") % 'volume'
            raise exc.HTTPBadRequest(explanation=msg)

        LOG.debug('Create volume request body: %s', body)
        context = req.environ['cinder.context']
        volume = body['volume']

        kwargs = {}

        # NOTE(thingee): v2 API allows name instead of display_name
        if volume.get('name'):
            volume['display_name'] = volume.get('name')
            del volume['name']

        # NOTE(thingee): v2 API allows description instead of
        #                display_description
        if volume.get('description'):
            volume['display_description'] = volume.get('description')
            del volume['description']

        if 'image_id' in volume:
            volume['imageRef'] = volume.get('image_id')
            del volume['image_id']

        req_volume_type = volume.get('volume_type', None)
        if req_volume_type:
            try:
                if not uuidutils.is_uuid_like(req_volume_type):
                    kwargs['volume_type'] = \
                        volume_types.get_volume_type_by_name(
                            context, req_volume_type)
                else:
                    kwargs['volume_type'] = volume_types.get_volume_type(
                        context, req_volume_type)
            except exception.VolumeTypeNotFound:
                msg = _("Volume type not found.")
                raise exc.HTTPNotFound(explanation=msg)

        kwargs['metadata'] = volume.get('metadata', None)

        snapshot_id = volume.get('snapshot_id')
        if snapshot_id is not None:
            try:
                kwargs['snapshot'] = self.volume_api.get_snapshot(
                    context, snapshot_id)
            except exception.NotFound:
                explanation = _('snapshot id:%s not found') % snapshot_id
                raise exc.HTTPNotFound(explanation=explanation)
        else:
            kwargs['snapshot'] = None

        source_volid = volume.get('source_volid')
        if source_volid is not None:
            try:
                kwargs['source_volume'] = \
                    self.volume_api.get_volume(context,
                                               source_volid)
            except exception.NotFound:
                explanation = _('source volume id:%s not found') % source_volid
                raise exc.HTTPNotFound(explanation=explanation)
        else:
            kwargs['source_volume'] = None

        source_replica = volume.get('source_replica')
        if source_replica is not None:
            try:
                src_vol = self.volume_api.get_volume(context, source_replica)
                if src_vol['replication_status'] == 'disabled':
                    explanation = _('source volume id:%s is not'
                                    ' replicated') % source_volid
                    raise exc.HTTPNotFound(explanation=explanation)
                kwargs['source_replica'] = src_vol
            except exception.NotFound:
                explanation = (_('replica source volume id:%s not found') %
                               source_replica)
                raise exc.HTTPNotFound(explanation=explanation)
        else:
            kwargs['source_replica'] = None

        consistencygroup_id = volume.get('consistencygroup_id')
        if consistencygroup_id is not None:
            try:
                kwargs['consistencygroup'] = \
                    self.consistencygroup_api.get(context,
                                                  consistencygroup_id)
            except exception.NotFound:
                explanation = _('Consistency group id:%s not found') % \
                    consistencygroup_id
                raise exc.HTTPNotFound(explanation=explanation)
        else:
            kwargs['consistencygroup'] = None

        size = volume.get('size', None)
        if size is None and kwargs['snapshot'] is not None:
            size = kwargs['snapshot']['volume_size']
        elif size is None and kwargs['source_volume'] is not None:
            size = kwargs['source_volume']['size']
        elif size is None and kwargs['source_replica'] is not None:
            size = kwargs['source_replica']['size']

        LOG.info(_LI("Create volume of %s GB"), size, context=context)

        if self.ext_mgr.is_loaded('os-image-create'):
            image_ref = volume.get('imageRef')
            if image_ref is not None:
                image_uuid = self._image_uuid_from_ref(image_ref, context)
                kwargs['image_id'] = image_uuid

        kwargs['availability_zone'] = volume.get('availability_zone', None)
        kwargs['scheduler_hints'] = volume.get('scheduler_hints', None)

        new_volume = self.volume_api.create(context, size,
                                            volume.get('display_name'),
                                            volume.get('display_description'),
                                            **kwargs)

        # TODO(vish): Instance should be None at db layer instead of
        #             trying to lazy load, but for now we turn it into
        #             a dict to avoid an error.
        new_volume = dict(new_volume.iteritems())
        retval = self._view_builder.detail(req, new_volume)

        return retval
示例#6
0
文件: common.py 项目: todd911/nova
def get_flavor(context, flavor_id):
    try:
        return objects.Flavor.get_by_flavor_id(context, flavor_id)
    except exception.FlavorNotFound as error:
        raise exc.HTTPNotFound(explanation=error.format_message())
 def _verify_share(self, context, share_id):
     try:
         db_api.share_get(context, share_id)
     except exception.NotFound:
         msg = _("Share '%s' not found.") % share_id
         raise exc.HTTPNotFound(explanation=msg)
示例#8
0
    def update(self, req, id, body):
        """Update specified share network."""
        context = req.environ['manila.context']
        policy.check_policy(context, RESOURCE_NAME, 'update')

        if not body or RESOURCE_NAME not in body:
            raise exc.HTTPUnprocessableEntity()

        try:
            share_network = db_api.share_network_get(context, id)
        except exception.ShareNetworkNotFound as e:
            raise exc.HTTPNotFound(explanation=e.msg)

        update_values = body[RESOURCE_NAME]

        if 'nova_net_id' in update_values:
            msg = _("nova networking is not supported starting in Ocata.")
            raise exc.HTTPBadRequest(explanation=msg)

        if self._share_network_subnets_contain_share_servers(share_network):
            for value in update_values:
                if value not in ['name', 'description']:
                    msg = (_("Cannot update share network %s. It is used by "
                             "share servers. Only 'name' and 'description' "
                             "fields are available for update") %
                           share_network['id'])
                    raise exc.HTTPForbidden(explanation=msg)
        try:
            if ('neutron_net_id' in update_values or
                    'neutron_subnet_id' in update_values):
                subnet = db_api.share_network_subnet_get_default_subnet(
                    context, id)
                if not subnet:
                    msg = _("The share network %(id)s does not have a "
                            "'default' subnet that serves all availability "
                            "zones, so subnet details "
                            "('neutron_net_id', 'neutron_subnet_id') cannot "
                            "be updated.") % {'id': id}
                    raise exc.HTTPBadRequest(explanation=msg)

                # NOTE(silvacarlose): If the default share network subnet have
                # the fields neutron_net_id and neutron_subnet_id set as None,
                # we need to make sure that in the update request the user is
                # passing both parameter since a share network subnet must
                # have both fields filled or empty.
                subnet_neutron_net_and_subnet_id_are_empty = (
                    subnet['neutron_net_id'] is None
                    and subnet['neutron_subnet_id'] is None)
                update_values_without_neutron_net_or_subnet = (
                    update_values.get('neutron_net_id') is None or
                    update_values.get('neutron_subnet_id') is None)
                if (subnet_neutron_net_and_subnet_id_are_empty
                        and update_values_without_neutron_net_or_subnet):
                    msg = _(
                        "To update the share network %(id)s you need to "
                        "specify both 'neutron_net_id' and "
                        "'neutron_subnet_id'.") % {'id': id}
                    raise webob.exc.HTTPBadRequest(explanation=msg)
                db_api.share_network_subnet_update(context,
                                                   subnet['id'],
                                                   update_values)
            share_network = db_api.share_network_update(context,
                                                        id,
                                                        update_values)
        except db_exception.DBError:
            msg = "Could not save supplied data due to database error"
            raise exc.HTTPBadRequest(explanation=msg)

        return self._view_builder.build_share_network(req, share_network)
示例#9
0
    def delete(self, req, id):
        """Delete specified share network."""
        context = req.environ['manila.context']
        policy.check_policy(context, RESOURCE_NAME, 'delete')

        try:
            share_network = db_api.share_network_get(context, id)
        except exception.ShareNetworkNotFound as e:
            raise exc.HTTPNotFound(explanation=e.msg)

        share_instances = (
            db_api.share_instances_get_all_by_share_network(context, id)
        )
        if share_instances:
            msg = _("Can not delete share network %(id)s, it has "
                    "%(len)s share(s).") % {'id': id,
                                            'len': len(share_instances)}
            LOG.error(msg)
            raise exc.HTTPConflict(explanation=msg)

        # NOTE(ameade): Do not allow deletion of share network used by share
        # group
        sg_count = db_api.count_share_groups_in_share_network(context, id)
        if sg_count:
            msg = _("Can not delete share network %(id)s, it has %(len)s "
                    "share group(s).") % {'id': id, 'len': sg_count}
            LOG.error(msg)
            raise exc.HTTPConflict(explanation=msg)

        # NOTE(silvacarlose): Do not allow the deletion of share networks
        # if it still contains two or more subnets
        if self._share_network_contains_subnets(share_network):
            msg = _("The share network %(id)s has more than one subnet "
                    "attached. Please remove the subnets untill you have one "
                    "or no subnets remaining.") % {'id': id}
            LOG.error(msg)
            raise exc.HTTPConflict(explanation=msg)

        for subnet in share_network['share_network_subnets']:
            if not self._all_share_servers_are_auto_deletable(subnet):
                msg = _("The service cannot determine if there are any "
                        "non-managed shares on the share network subnet "
                        "%(id)s, so it cannot be deleted. Please contact the "
                        "cloud administrator to rectify.") % {
                    'id': subnet['id']}
                LOG.error(msg)
                raise exc.HTTPConflict(explanation=msg)

        for subnet in share_network['share_network_subnets']:
            for share_server in subnet['share_servers']:
                self.share_rpcapi.delete_share_server(context, share_server)

        db_api.share_network_delete(context, id)

        try:
            reservations = QUOTAS.reserve(
                context, project_id=share_network['project_id'],
                share_networks=-1, user_id=share_network['user_id'])
        except Exception:
            LOG.exception("Failed to update usages deleting "
                          "share-network.")
        else:
            QUOTAS.commit(context, reservations,
                          project_id=share_network['project_id'],
                          user_id=share_network['user_id'])
        return webob.Response(status_int=http_client.ACCEPTED)
示例#10
0
 def _lookup(self, id=None, *remainder):
     if id:
         id = unquote(id)
         return self.ThreadController(self._discussion_controller, id), remainder
     else:
         raise exc.HTTPNotFound()
示例#11
0
 def __init__(self, prefix='', key='dream.app'):
     decoroute.App.__init__(self, prefix, key)
     self.map = dict(((method, decoroute.UrlMap()) for method in ('HEAD', 'GET', 'POST', 'PUT', 'DELETE')))
     self.not_found(lambda e: exc.HTTPNotFound(detail='Not found'))
     self._render = self._render_response
示例#12
0
 def _lookup(self, name, *remainder):
     app = c.project.app_instance(name)
     if app is None:
         raise exc.HTTPNotFound(name)
     return app.admin, remainder
示例#13
0
    def create(self, req, body):
        """Instruct Cinder to manage a storage snapshot object.

        Manages an existing backend storage snapshot object (e.g. a Linux
        logical volume or a SAN disk) by creating the Cinder objects required
        to manage it, and possibly renaming the backend storage snapshot object
        (driver dependent).

        From an API perspective, this operation behaves very much like a
        snapshot creation operation.

        Required HTTP Body:

        .. code-block:: json

         {
           "snapshot":
           {
             "volume_id": <Cinder volume already exists in volume backend>,
             "ref":  <Driver-specific reference to the existing storage object>
           }
         }

        See the appropriate Cinder drivers' implementations of the
        manage_snapshot method to find out the accepted format of 'ref'.
        For example,in LVM driver, it will be the logic volume name of snapshot
        which you want to manage.

        This API call will return with an error if any of the above elements
        are missing from the request, or if the 'volume_id' element refers to
        a cinder volume that could not be found.

        The snapshot will later enter the error state if it is discovered that
        'ref' is bad.

        Optional elements to 'snapshot' are::

         name           A name for the new snapshot.
         description    A description for the new snapshot.
         metadata       Key/value pairs to be associated with the new snapshot.

        """
        context = req.environ['cinder.context']
        authorize_manage(context)

        if not self.is_valid_body(body, 'snapshot'):
            msg = _("Missing required element snapshot in request body.")
            raise exc.HTTPBadRequest(explanation=msg)

        snapshot = body['snapshot']

        # Check that the required keys are present, return an error if they
        # are not.
        required_keys = ('ref', 'volume_id')
        missing_keys = set(required_keys) - set(snapshot.keys())

        if missing_keys:
            msg = _("The following elements are required: "
                    "%s") % ', '.join(missing_keys)
            raise exc.HTTPBadRequest(explanation=msg)

        # Check whether volume exists
        volume_id = snapshot['volume_id']
        try:
            volume = self.volume_api.get(context, volume_id)
        except exception.VolumeNotFound:
            msg = _("Volume: %s could not be found.") % volume_id
            raise exc.HTTPNotFound(explanation=msg)

        LOG.debug('Manage snapshot request body: %s', body)

        snapshot_parameters = {}

        snapshot_parameters['metadata'] = snapshot.get('metadata', None)
        snapshot_parameters['description'] = snapshot.get('description', None)
        # NOTE(wanghao) if name in request body, we are overriding the 'name'
        snapshot_parameters['name'] = snapshot.get(
            'name', snapshot.get('display_name'))

        try:
            new_snapshot = self.volume_api.manage_existing_snapshot(
                context, snapshot['ref'], volume, **snapshot_parameters)
        except exception.ServiceNotFound:
            msg = _("Service %s not found.") % CONF.volume_topic
            raise exc.HTTPNotFound(explanation=msg)

        return self._view_builder.detail(req, new_snapshot)
示例#14
0
 def _get_instance(self, context, instance_id):
     try:
         return self.compute_api.get(context, instance_id)
     except exception.InstanceNotFound:
         msg = _("Server not found")
         raise exc.HTTPNotFound(msg)
示例#15
0
    def create(self, req, body):
        """Creates a new volume."""
        if not self.is_valid_body(body, 'volume'):
            raise exc.HTTPUnprocessableEntity()

        LOG.debug('Create volume request body: %s', body)
        context = req.environ['cinder.context']
        volume = body['volume']

        kwargs = {}

        req_volume_type = volume.get('volume_type', None)
        if req_volume_type:
            try:
                if not uuidutils.is_uuid_like(req_volume_type):
                    kwargs['volume_type'] = \
                        volume_types.get_volume_type_by_name(
                            context, req_volume_type)
                else:
                    kwargs['volume_type'] = volume_types.get_volume_type(
                        context, req_volume_type)
            except exception.VolumeTypeNotFound:
                explanation = 'Volume type not found.'
                raise exc.HTTPNotFound(explanation=explanation)

        kwargs['metadata'] = volume.get('metadata', None)

        snapshot_id = volume.get('snapshot_id')
        if snapshot_id is not None:
            try:
                kwargs['snapshot'] = self.volume_api.get_snapshot(
                    context, snapshot_id)
            except exception.NotFound:
                explanation = _('snapshot id:%s not found') % snapshot_id
                raise exc.HTTPNotFound(explanation=explanation)

        else:
            kwargs['snapshot'] = None

        source_volid = volume.get('source_volid')
        if source_volid is not None:
            try:
                kwargs['source_volume'] = \
                    self.volume_api.get_volume(context,
                                               source_volid)
            except exception.NotFound:
                explanation = _('source vol id:%s not found') % source_volid
                raise exc.HTTPNotFound(explanation=explanation)
        else:
            kwargs['source_volume'] = None

        size = volume.get('size', None)
        if size is None and kwargs['snapshot'] is not None:
            size = kwargs['snapshot']['volume_size']
        elif size is None and kwargs['source_volume'] is not None:
            size = kwargs['source_volume']['size']

        LOG.info(_LI("Create volume of %s GB"), size, context=context)

        image_href = None
        image_uuid = None
        if self.ext_mgr.is_loaded('os-image-create'):
            # NOTE(jdg): misleading name "imageRef" as it's an image-id
            image_href = volume.get('imageRef')
            if image_href is not None:
                image_uuid = self._image_uuid_from_href(image_href)
                kwargs['image_id'] = image_uuid

        kwargs['availability_zone'] = volume.get('availability_zone', None)

        new_volume = self.volume_api.create(context, size,
                                            volume.get('display_name'),
                                            volume.get('display_description'),
                                            **kwargs)

        # TODO(vish): Instance should be None at db layer instead of
        #             trying to lazy load, but for now we turn it into
        #             a dict to avoid an error.
        new_volume = dict(new_volume.iteritems())

        retval = _translate_volume_detail_view(context, new_volume, image_uuid)

        return {'volume': retval}
示例#16
0
 def index(self, req, server_id):
     try:
         instance = self.compute_api.get(req.environ['nova.context'], id)
     except nova.exception.NotFound:
         return faults.Fault(exc.HTTPNotFound())
     return {'addresses': self.builder.build(instance)}
示例#17
0
    def _create_backup(self, req, id, body):
        """Backup a server instance.

        Images now have an `image_type` associated with them, which can be
        'snapshot' or the backup type, like 'daily' or 'weekly'.

        If the image_type is backup-like, then the rotation factor can be
        included and that will cause the oldest backups that exceed the
        rotation factor to be deleted.

        """
        context = req.environ["nova.context"]
        authorize(context, 'create_backup')

        try:
            entity = body["create_backup"]
        except (KeyError, TypeError):
            raise exc.HTTPBadRequest(_("Malformed request body"))

        try:
            image_name = entity["name"]
            backup_type = entity["backup_type"]
            rotation = entity["rotation"]

        except KeyError as missing_key:
            msg = _("create_backup entity requires %s attribute") % missing_key
            raise exc.HTTPBadRequest(explanation=msg)

        except TypeError:
            msg = _("Malformed create_backup entity")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            rotation = int(rotation)
        except ValueError:
            msg = _("create_backup attribute 'rotation' must be an integer")
            raise exc.HTTPBadRequest(explanation=msg)
        if rotation < 0:
            msg = _("create_backup attribute 'rotation' must be greater "
                    "than or equal to zero")
            raise exc.HTTPBadRequest(explanation=msg)

        props = {}
        metadata = entity.get('metadata', {})
        common.check_img_metadata_properties_quota(context, metadata)
        try:
            props.update(metadata)
        except ValueError:
            msg = _("Invalid metadata")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            instance = self.compute_api.get(context, id, want_objects=True)
        except exception.InstanceNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())

        try:
            image = self.compute_api.backup(context,
                                            instance,
                                            image_name,
                                            backup_type,
                                            rotation,
                                            extra_properties=props)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'create_backup')

        resp = webob.Response(status_int=202)

        # build location of newly-created image entity if rotation is not zero
        if rotation > 0:
            image_id = str(image['id'])
            image_ref = os.path.join(req.application_url, 'images', image_id)
            resp.headers['Location'] = image_ref

        return resp
示例#18
0
 def private(self, req, server_id):
     try:
         instance = self.compute_api.get(req.environ['nova.context'], id)
     except nova.exception.NotFound:
         return faults.Fault(exc.HTTPNotFound())
     return {'private': self.builder.build_private_parts(instance)}
示例#19
0
文件: servers.py 项目: scholery/nova
    def _action_rebuild(self, req, id, body):
        """Rebuild an instance with the given attributes."""
        rebuild_dict = body['rebuild']

        image_href = rebuild_dict["imageRef"]
        image_href = self._image_uuid_from_href(image_href)

        password = self._get_server_admin_password(rebuild_dict)

        context = req.environ['nova.context']
        authorize(context, action='rebuild')
        instance = self._get_server(context, req, id)

        attr_map = {
            'name': 'display_name',
            'metadata': 'metadata',
        }

        rebuild_kwargs = {}

        if list(self.rebuild_extension_manager):
            self.rebuild_extension_manager.map(self._rebuild_extension_point,
                                               rebuild_dict, rebuild_kwargs)

        for request_attribute, instance_attribute in attr_map.items():
            try:
                rebuild_kwargs[instance_attribute] = rebuild_dict[
                    request_attribute]
            except (KeyError, TypeError):
                pass

        try:
            self.compute_api.rebuild(context, instance, image_href, password,
                                     **rebuild_kwargs)
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'rebuild', id)
        except exception.InstanceNotFound:
            msg = _("Instance could not be found")
            raise exc.HTTPNotFound(explanation=msg)
        except exception.ImageNotFound:
            msg = _("Cannot find image for rebuild")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.QuotaError as error:
            raise exc.HTTPForbidden(explanation=error.format_message())
        except (exception.ImageNotActive, exception.FlavorDiskTooSmall,
                exception.FlavorMemoryTooSmall, exception.InvalidMetadata,
                exception.AutoDiskConfigDisabledByImage) as error:
            raise exc.HTTPBadRequest(explanation=error.format_message())

        instance = self._get_server(context, req, id)

        view = self._view_builder.show(req, instance, extend_address=False)

        # Add on the admin_password attribute since the view doesn't do it
        # unless instance passwords are disabled
        if CONF.enable_instance_password:
            view['server']['adminPass'] = password

        robj = wsgi.ResponseObject(view)
        return self._add_location(robj)
示例#20
0
    def _retrieve_key(self, req, match_object, user_request_id):
        unified_id = int(match_object.group("unified_id"))
        conjoined_part = int(match_object.group("conjoined_part"))

        lower_bound = 0
        upper_bound = None
        slice_offset = 0
        slice_size = None
        total_file_size = None
        if "range" in req.headers:
            lower_bound, upper_bound, slice_offset, slice_size = \
                _parse_range_header(req.headers["range"])
            if not "x-nimbus-io-expected-content-length" in req.headers:
                message = "expected x-nimbus-io-expected-content-length header"
                self._log.error("request {0} {1}".format(
                    user_request_id, message))
                raise exc.HTTPBadRequest(message)
            total_file_size = \
                int(req.headers["x-nimbus-io-expected-content-length"])

        assert slice_offset % block_size == 0, slice_offset
        block_offset = slice_offset / block_size
        if slice_size is None:
            block_count = None
        else:
            assert slice_size % block_size == 0, slice_size
            block_count = slice_size / block_size

        connected_data_readers = _connected_clients(self.data_readers)

        if len(connected_data_readers) < _min_connected_clients:
            self._log.error("request {0} too few connected readers {1}".format(
                user_request_id, len(connected_data_readers)))
            raise exc.HTTPServiceUnavailable(
                "Too few connected readers {0}".format(
                    len(connected_data_readers)))

        result = self._get_params_from_memcache(unified_id, conjoined_part)
        if result is None:
            self._log.warn("request {0} cache miss unified-id {1} {2}".format(
                user_request_id, unified_id, conjoined_part))
            result = self._get_params_from_database(unified_id, conjoined_part)
        if result is None:
            error_message = "unknown unified-id {0} {1}".format(
                unified_id, conjoined_part)
            self._log.error("request {0} {1}".format(user_request_id,
                                                     error_message))
            raise exc.HTTPServiceUnavailable(error_message)
        collection_id, key = result

        description = "request {0} retrieve: ({1}) key={2} unified_id={3}-{4} {5}:{6}".format(
            user_request_id, collection_id, key, unified_id, conjoined_part,
            slice_offset, slice_size)
        self._log.info(description)

        start_time = time.time()
        self._stats["retrieves"] += 1

        retriever = Retriever(self._node_local_connection, self.data_readers,
                              collection_id, key, unified_id, conjoined_part,
                              block_offset, block_count, _min_segments,
                              user_request_id)

        retrieved = retriever.retrieve(_reply_timeout)

        try:
            first_segments = retrieved.next()
        except RetrieveFailedError, instance:
            self._log.error("retrieve failed: {0} {1}".format(
                description, instance))
            self._stats["retrieves"] -= 1
            return exc.HTTPNotFound(str(instance))
示例#21
0
 def _get_instance(self, context, instance_id):
     try:
         return self.compute_api.get(context, instance_id)
     except exception.InstanceNotFound as e:
         raise exc.HTTPNotFound(explanation=e.format_message())
示例#22
0
    def create(self, req, body):
        """Creates a new share."""
        context = req.environ['manila.context']

        if not self.is_valid_body(body, 'share'):
            raise exc.HTTPUnprocessableEntity()

        share = body['share']

        # NOTE(rushiagr): v2 API allows name instead of display_name
        if share.get('name'):
            share['display_name'] = share.get('name')
            del share['name']

        # NOTE(rushiagr): v2 API allows description instead of
        #                display_description
        if share.get('description'):
            share['display_description'] = share.get('description')
            del share['description']

        size = share['size']
        share_proto = share['share_proto'].upper()

        msg = (_LI("Create %(share_proto)s share of %(size)s GB") % {
            'share_proto': share_proto,
            'size': size
        })
        LOG.info(msg, context=context)

        kwargs = {}
        kwargs['availability_zone'] = share.get('availability_zone')

        kwargs['metadata'] = share.get('metadata', None)

        snapshot_id = share.get('snapshot_id')
        if snapshot_id:
            snapshot = self.share_api.get_snapshot(context, snapshot_id)
        else:
            snapshot = None

        kwargs['snapshot'] = snapshot

        share_network_id = share.get('share_network_id')

        if snapshot:
            # Need to check that share_network_id from snapshot's
            # parents share equals to share_network_id from args.
            # If share_network_id is empty than update it with
            # share_network_id of parent share.
            parent_share = self.share_api.get(context, snapshot['share_id'])
            parent_share_net_id = parent_share['share_network_id']
            if share_network_id:
                if share_network_id != parent_share_net_id:
                    msg = "Share network ID should be the same as snapshot's" \
                          " parent share's or empty"
                    raise exc.HTTPBadRequest(explanation=msg)
            elif parent_share_net_id:
                share_network_id = parent_share_net_id

        if share_network_id:
            try:
                self.share_api.get_share_network(context, share_network_id)
            except exception.ShareNetworkNotFound as e:
                raise exc.HTTPNotFound(explanation=six.text_type(e))
            kwargs['share_network_id'] = share_network_id

        display_name = share.get('display_name')
        display_description = share.get('display_description')

        req_volume_type = share.get('volume_type', None)
        if req_volume_type:
            try:
                if not uuidutils.is_uuid_like(req_volume_type):
                    kwargs['volume_type'] = \
                        volume_types.get_volume_type_by_name(
                            context, req_volume_type)
                else:
                    kwargs['volume_type'] = volume_types.get_volume_type(
                        context, req_volume_type)
            except exception.VolumeTypeNotFound:
                msg = _("Volume type not found.")
                raise exc.HTTPNotFound(explanation=msg)

        new_share = self.share_api.create(context, share_proto, size,
                                          display_name, display_description,
                                          **kwargs)

        return self._view_builder.detail(req, dict(six.iteritems(new_share)))
示例#23
0
 def test_get_bridge_not_found(self):
     self.mock_api.get_bridge.side_effect = w_exc.HTTPNotFound()
     self.assertRaises(midonet_lib.MidonetResourceNotFound,
                       self.client.get_bridge, uuidutils.generate_uuid())
 def __call__(self, request: Request):
     for router in self.ROUTERs:
         response = router.match(request)
         if response:  # handler(request)  返回的就是处理好的对象,直接抛给浏览器
             return response
     raise exc.HTTPNotFound("wrongpage")
示例#25
0
def license_deed_view(request):
    """
    The main and major deed generating view.
    """
    ##########################
    # Try and get the license.
    ##########################
    license = by_code(
        request.matchdict['code'],
        jurisdiction=request.matchdict.get('jurisdiction'),
        version=request.matchdict.get('version'))
    if not license:
        license_versions = util.catch_license_versions_from_request(request)

        if license_versions:
            # If we can't get it, but others of that code exist, give
            # a special 404.
            return license_catcher(request)
        else:
            # Otherwise, give the normal 404.
            return exc.HTTPNotFound()

    ####################
    # Everything else ;)
    ####################
    # "color" of the license; the color reflects the relative amount
    # of freedom.
    if license.license_code in ('devnations', 'sampling'):
       color = 'red'
    elif license.license_code.find('sampling') > -1 or \
             license.license_code.find('nc') > -1 or \
             license.license_code.find('nd') > -1:
       color = 'yellow'
    else:
       color = 'green'

    # Get the language this view will be displayed in.
    #  - First checks to see if the routing matchdict specifies the language
    #  - Or, next gets the jurisdictions' default language if the jurisdiction
    #    specifies one
    #  - Otherwise it's english!
    if request.matchdict.has_key('target_lang'):
        target_lang = request.matchdict.get('target_lang')
    elif license.jurisdiction.default_language:
        target_lang = locale_to_lower_upper(
            license.jurisdiction.default_language)
    else:
        target_lang = 'en'

    # True if the legalcode for this license is available in
    # multiple languages (or a single language with a language code different
    # than that of the jurisdiction).
    #
    # Stored in the RDF, we'll just check license.legalcodes() :)
    legalcodes = license.legalcodes(target_lang)
    if len(legalcodes) > 1 \
            or list(legalcodes)[0][2] is not None:
        multi_language = True
        legalcodes = sorted(legalcodes, key=lambda lc: lc[2])
    else:
        multi_language = False

    # Use the lower-dash style for all RDF-related locale stuff
    rdf_style_target_lang = locale_to_lower_lower(target_lang)

    license_title = None
    try:
        license_title = license.title(rdf_style_target_lang)
    except KeyError:
        # don't have one for that language, use default
        license_title = license.title()

    conditions = {}
    for code in license.license_code.split('-'):
        conditions[code] = 1

    # Find out all the active languages
    active_languages = get_well_translated_langs()
    negotiated_locale = negotiate_locale(target_lang)

    # If negotiating the locale says that this isn't a valid language,
    # let's fall back to something that is.
    if target_lang != negotiated_locale:
        base_url = REMOVE_DEED_URL_RE.match(request.path_info).groups()[0]
        redirect_to = base_url + 'deed.' + negotiated_locale
        return exc.HTTPFound(location=redirect_to)

    if DEED_TEMPLATE_MAPPING.has_key(license.license_code):
        main_template = DEED_TEMPLATE_MAPPING[license.license_code]
    else:
        main_template = 'licenses/standard_deed.html'

    get_this = "/choose/results-one?license_code=%s&amp;jurisdiction=%s&amp;version=%s&amp;lang=%s" % (urllib.quote(license.license_code), license.jurisdiction.code, license.version, target_lang)

    context = {
        'request': request,
        'license_code': license.license_code,
        'license_code_quoted': urllib.quote(license.license_code),
        'license_title': license_title,
        'license': license,
        'multi_language': multi_language,
        'legalcodes': legalcodes,
        'color': color,
        'conditions': conditions,
        'active_languages': active_languages,
        'target_lang': target_lang,
        'jurisdiction':license.jurisdiction.code,
        'get_this': get_this,
        }
    context.update(util.rtl_context_stuff(target_lang))

    return Response(
        util.render_template(
            request, target_lang,
            main_template, context))
示例#26
0
    def create(self, req, body):
        """Creates a new volume."""
        if not self.is_valid_body(body, 'volume'):
            raise exc.HTTPBadRequest()

        context = req.environ['cinder.context']
        volume = body['volume']

        kwargs = {}

        # NOTE(thingee): v2 API allows name instead of display_name
        if volume.get('name'):
            volume['display_name'] = volume.get('name')
            del volume['name']

        # NOTE(thingee): v2 API allows description instead of description
        if volume.get('description'):
            volume['display_description'] = volume.get('description')
            del volume['description']

        req_volume_type = volume.get('volume_type', None)
        if req_volume_type:
            try:
                kwargs['volume_type'] = volume_types.get_volume_type(
                    context, req_volume_type)
            except exception.VolumeTypeNotFound:
                explanation = 'Volume type not found.'
                raise exc.HTTPNotFound(explanation=explanation)

        kwargs['metadata'] = volume.get('metadata', None)

        snapshot_id = volume.get('snapshot_id')
        if snapshot_id is not None:
            kwargs['snapshot'] = self.volume_api.get_snapshot(
                context, snapshot_id)
        else:
            kwargs['snapshot'] = None

        source_volid = volume.get('source_volid')
        if source_volid is not None:
            kwargs['source_volume'] = self.volume_api.get_volume(
                context, source_volid)
        else:
            kwargs['source_volume'] = None

        size = volume.get('size', None)
        if size is None and kwargs['snapshot'] is not None:
            size = kwargs['snapshot']['volume_size']
        elif size is None and kwargs['source_volume'] is not None:
            size = kwargs['source_volume']['size']

        LOG.audit(_("Create volume of %s GB"), size, context=context)

        image_href = None
        image_uuid = None
        if self.ext_mgr.is_loaded('os-image-create'):
            image_href = volume.get('imageRef')
            if image_href:
                image_uuid = self._image_uuid_from_href(image_href)
                kwargs['image_id'] = image_uuid

        kwargs['availability_zone'] = volume.get('availability_zone', None)

        new_volume = self.volume_api.create(context, size,
                                            volume.get('display_name'),
                                            volume.get('display_description'),
                                            **kwargs)

        # TODO(vish): Instance should be None at db layer instead of
        #             trying to lazy load, but for now we turn it into
        #             a dict to avoid an error.
        retval = self._view_builder.summary(req, dict(new_volume.iteritems()))

        return retval
示例#27
0
文件: images.py 项目: vefimova/glance
    def update(self, req, id, body):
        """Updates an existing image with the registry.

        :param req: wsgi Request object
        :param body: Dictionary of information about the image
        :param id:  The opaque internal identifier for the image

        :retval Returns the updated image information as a mapping,
        """
        image_data = body['image']
        from_state = body.get('from_state', None)

        # Prohibit modification of 'owner'
        if not req.context.is_admin and 'owner' in image_data:
            del image_data['owner']

        if 'location' in image_data:
            image_data['locations'] = [image_data.pop('location')]

        purge_props = req.headers.get("X-Glance-Registry-Purge-Props", "false")
        try:
            LOG.debug(
                "Updating image %(id)s with metadata: %(image_data)r", {
                    'id':
                    id,
                    'image_data':
                    dict((k, v)
                         for k, v in image_data.items() if k != 'locations')
                })
            image_data = _normalize_image_location_for_db(image_data)
            if purge_props == "true":
                purge_props = True
            else:
                purge_props = False

            updated_image = self.db_api.image_update(req.context,
                                                     id,
                                                     image_data,
                                                     purge_props=purge_props,
                                                     from_state=from_state)

            msg = _LI("Updating metadata for image %(id)s") % {'id': id}
            LOG.info(msg)
            return dict(image=make_image_dict(updated_image))
        except exception.Invalid as e:
            msg = (_("Failed to update image metadata. "
                     "Got error: %s") % utils.exception_to_str(e))
            LOG.error(msg)
            return exc.HTTPBadRequest(msg)
        except exception.NotFound:
            msg = _LI("Image %(id)s not found") % {'id': id}
            LOG.info(msg)
            raise exc.HTTPNotFound(body='Image not found',
                                   request=req,
                                   content_type='text/plain')
        except exception.ForbiddenPublicImage:
            msg = _LI("Update denied for public image %(id)s") % {'id': id}
            LOG.info(msg)
            raise exc.HTTPForbidden()
        except exception.Forbidden:
            # If it's private and doesn't belong to them, don't let on
            # that it exists
            msg = _LI("Access denied to image %(id)s but returning"
                      " 'not found'") % {
                          'id': id
                      }
            LOG.info(msg)
            raise exc.HTTPNotFound(body='Image not found',
                                   request=req,
                                   content_type='text/plain')
        except exception.Conflict as e:
            LOG.info(utils.exception_to_str(e))
            raise exc.HTTPConflict(body='Image operation conflicts',
                                   request=req,
                                   content_type='text/plain')
        except Exception:
            LOG.exception(_LE("Unable to update image %s") % id)
            raise
 def _lookup(self, *args):
     if args:
         return NamedController(args[0]), args[1:]
     else:
         raise exc.HTTPNotFound()
示例#29
0
 def _lookup(self, year, month, name, *rest):
     slug = '/'.join((year, month, urllib2.unquote(name).decode('utf-8')))
     post = BM.BlogPost.query.get(slug=slug, app_config_id=c.app.config._id)
     if post is None:
         raise exc.HTTPNotFound()
     return PostController(post), rest
示例#30
0
    def detach(self, req, id, body):
        server_id = id
        context = req.environ['nova.context']
        authorize_detach(context)

        volume_id = body['detach']['volume_id']

        LOG.audit(
            _("Detach volume %(volume_id)s from "
              "instance %(server_id)s"), {
                  "volume_id": volume_id,
                  "server_id": id,
                  "context": context
              })
        instance = common.get_instance(self.compute_api,
                                       context,
                                       server_id,
                                       want_objects=True)
        try:
            volume = self.volume_api.get(context, volume_id)
        except exception.VolumeNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())

        bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
            context, instance.uuid)
        if not bdms:
            msg = _("Volume %(volume_id)s is not attached to the "
                    "instance %(server_id)s") % {
                        'server_id': server_id,
                        'volume_id': volume_id
                    }
            LOG.debug(msg)
            raise exc.HTTPNotFound(explanation=msg)

        for bdm in bdms:
            if bdm.volume_id != volume_id:
                continue
            if bdm.is_root:
                msg = _("Can't detach root device volume")
                raise exc.HTTPForbidden(explanation=msg)
            try:
                self.compute_api.detach_volume(context, instance, volume)
                break
            except exception.VolumeUnattached:
                # The volume is not attached.  Treat it as NotFound
                # by falling through.
                pass
            except exception.InvalidVolume as e:
                raise exc.HTTPBadRequest(explanation=e.format_message())
            except exception.InstanceIsLocked as e:
                raise exc.HTTPConflict(explanation=e.format_message())
            except exception.InstanceInvalidState as state_error:
                common.raise_http_conflict_for_instance_invalid_state(
                    state_error, 'detach_volume')
        else:
            msg = _("Volume %(volume_id)s is not attached to the "
                    "instance %(server_id)s") % {
                        'server_id': server_id,
                        'volume_id': volume_id
                    }
            raise exc.HTTPNotFound(explanation=msg)