Пример #1
0
    def _set_metadata(self, req, id, body):
        """Replaces the aggregate's existing metadata with new metadata."""
        context = _get_context(req)
        authorize(context)

        if len(body) != 1:
            raise exc.HTTPBadRequest()
        try:
            metadata = body["metadata"]
        except KeyError:
            raise exc.HTTPBadRequest()

        # The metadata should be a dict
        if not isinstance(metadata, dict):
            msg = _('The value of metadata must be a dict')
            raise exc.HTTPBadRequest(explanation=msg)
        try:
            for key, value in metadata.items():
                utils.check_string_length(key, "metadata.key", 1, 255)
                if value is not None:
                    utils.check_string_length(value, "metadata.value", 0, 255)
        except exception.InvalidInput as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
        try:
            aggregate = self.api.update_aggregate_metadata(context,
                                                           id, metadata)
        except exception.AggregateNotFound:
            msg = _('Cannot set metadata %(metadata)s in aggregate'
                    ' %(id)s') % {'metadata': metadata, 'id': id}
            raise exc.HTTPNotFound(explanation=msg)
        except exception.InvalidAggregateAction as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        return self._marshall_aggregate(aggregate)
Пример #2
0
    def _check_extra_specs(self, specs):
        if type(specs) is not dict:
            msg = _('Bad extra_specs provided')
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            flavors.validate_extra_spec_keys(specs.keys())
        except TypeError:
            msg = _("Fail to validate provided extra specs keys. "
                    "Expected string")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.InvalidInput as error:
            raise exc.HTTPBadRequest(explanation=error.format_message())

        for key, value in six.iteritems(specs):
            try:
                utils.check_string_length(key, 'extra_specs key',
                                          min_length=1, max_length=255)

                # NOTE(dims): The following check was added for backwards
                # compatibility.
                if (isinstance(value, float) or
                        type(value) in six.integer_types):
                    value = six.text_type(value)
                utils.check_string_length(value, 'extra_specs value',
                                          max_length=255)
            except exception.InvalidInput as error:
                raise exc.HTTPBadRequest(explanation=error.format_message())
Пример #3
0
    def _validate_input_body(self, body, entity_name):
        if not self.is_valid_body(body, entity_name):
            msg = _("the body is invalid.")
            raise jacket.compute.exception.InvalidInput(reason=msg)

        subbody = dict(body[entity_name])

        expected_fields = ['name', 'policies']
        for field in expected_fields:
            value = subbody.pop(field, None)
            if not value:
                msg = _("'%s' is either missing or empty.") % field
                raise jacket.compute.exception.InvalidInput(reason=msg)
            if field == 'name':
                utils.check_string_length(value, field,
                                          min_length=1, max_length=255)
                if not parameter_types.valid_name_regex_obj.search(value):
                    msg = _("Invalid format for name: '%s'") % value
                    raise jacket.compute.exception.InvalidInput(reason=msg)
            elif field == 'policies':
                if isinstance(value, list):
                    [utils.check_string_length(v, field,
                        min_length=1, max_length=255) for v in value]
                    self._validate_policies(value)
                else:
                    msg = _("'%s' is not a list") % value
                    raise jacket.compute.exception.InvalidInput(reason=msg)

        if subbody:
            msg = _("unsupported fields: %s") % subbody.keys()
            raise jacket.compute.exception.InvalidInput(reason=msg)
Пример #4
0
 def _check_string_length(self, value, name, max_length=None):
     try:
         if isinstance(value, six.string_types):
             value = value.strip()
         utils.check_string_length(value, name, min_length=1,
                                   max_length=max_length)
     except exception.InvalidInput as e:
         raise exc.HTTPBadRequest(explanation=e.format_message())
Пример #5
0
    def _is_valid_as_reason(self, reason):
        try:
            utils.check_string_length(reason.strip(), 'Disabled reason',
                                      min_length=1, max_length=255)
        except exception.InvalidInput:
            return False

        return True
Пример #6
0
 def _check_extra_specs_value(self, specs):
     for key, value in six.iteritems(specs):
         try:
             if isinstance(value, (six.integer_types, float)):
                 value = six.text_type(value)
                 utils.check_string_length(value, 'extra_specs value',
                                           max_length=255)
         except exception.InvalidInput as error:
             raise webob.exc.HTTPBadRequest(
                       explanation=error.format_message())
Пример #7
0
def validate_device_name(value):
    try:
        # NOTE (ndipanov): Do not allow empty device names
        #                  until assigning default values
        #                  is supported by compute.compute
        utils.check_string_length(value, 'Device name',
                                  min_length=1, max_length=255)
    except exception.InvalidInput:
        raise exception.InvalidBDMFormat(
            details=_("Device name empty or too long."))

    if ' ' in value:
        raise exception.InvalidBDMFormat(
            details=_("Device name contains spaces."))
Пример #8
0
    def validate_property(self, value, property, allowed):
        """Validate given security group property.

        :param value:    the value to validate, as a string or unicode
        :param property: the property, either 'name' or 'description'
        :param allowed:  the range of characters allowed, but not used because
                         Neutron is allowing any characters.
        """

        # NOTE: If using compute-network as the backend, min_length is 1. However
        # if using Neutron, Nova has allowed empty string as its history.
        # So this min_length should be 0 for passing the existing requests.
        utils.check_string_length(value, name=property, min_length=0,
                                  max_length=255)
Пример #9
0
    def update(self, req, id, body):
        context = req.environ['compute.context']
        authorize(context)
        try:
            utils.check_string_length(id,
                                      'quota_class_name',
                                      min_length=1,
                                      max_length=255)
        except exception.InvalidInput as e:
            raise webob.exc.HTTPBadRequest(explanation=e.format_message())

        quota_class = id
        bad_keys = []

        if not self.is_valid_body(body, 'quota_class_set'):
            msg = _("quota_class_set not specified")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        quota_class_set = body['quota_class_set']
        for key in quota_class_set.keys():
            if key not in self.supported_quotas:
                bad_keys.append(key)
                continue
            try:
                body['quota_class_set'][key] = utils.validate_integer(
                    body['quota_class_set'][key], key, max_value=db.MAX_INT)
            except exception.InvalidInput as e:
                raise webob.exc.HTTPBadRequest(explanation=e.format_message())

        if bad_keys:
            msg = _("Bad key(s) %s in quota_set") % ",".join(bad_keys)
            raise webob.exc.HTTPBadRequest(explanation=msg)

        try:
            # NOTE(alex_xu): back-compatible with compute layer hard-code admin
            # permission checks. This has to be left only for API v2.0 because
            # this version has to be stable even if it means that only admins
            # can call this method while the policy could be changed.
            jacket.context.require_admin_context(context)
        except exception.AdminRequired:
            raise webob.exc.HTTPForbidden()

        for key, value in quota_class_set.items():
            try:
                db.quota_class_update(context, quota_class, key, value)
            except exception.QuotaClassNotFound:
                db.quota_class_create(context, quota_class, key, value)

        values = QUOTAS.get_class_quotas(context, quota_class)
        return self._format_quota_set(None, values)
Пример #10
0
    def update(self, req, id, body):
        context = req.environ['compute.context']
        authorize(context)
        try:
            utils.check_string_length(id, 'quota_class_name',
                                      min_length=1, max_length=255)
        except exception.InvalidInput as e:
                raise webob.exc.HTTPBadRequest(
                    explanation=e.format_message())

        quota_class = id
        bad_keys = []

        if not self.is_valid_body(body, 'quota_class_set'):
            msg = _("quota_class_set not specified")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        quota_class_set = body['quota_class_set']
        for key in quota_class_set.keys():
            if key not in self.supported_quotas:
                bad_keys.append(key)
                continue
            try:
                body['quota_class_set'][key] = utils.validate_integer(
                    body['quota_class_set'][key], key, max_value=db.MAX_INT)
            except exception.InvalidInput as e:
                raise webob.exc.HTTPBadRequest(
                    explanation=e.format_message())

        if bad_keys:
            msg = _("Bad key(s) %s in quota_set") % ",".join(bad_keys)
            raise webob.exc.HTTPBadRequest(explanation=msg)

        try:
            # NOTE(alex_xu): back-compatible with compute layer hard-code admin
            # permission checks. This has to be left only for API v2.0 because
            # this version has to be stable even if it means that only admins
            # can call this method while the policy could be changed.
            jacket.context.require_admin_context(context)
        except exception.AdminRequired:
            raise webob.exc.HTTPForbidden()

        for key, value in quota_class_set.items():
            try:
                db.quota_class_update(context, quota_class, key, value)
            except exception.QuotaClassNotFound:
                db.quota_class_create(context, quota_class, key, value)

        values = QUOTAS.get_class_quotas(context, quota_class)
        return self._format_quota_set(None, values)
Пример #11
0
    def wrapped(self, req, id, body, *args, **kwargs):
        if len(body) != 1:
            msg = _('Only host parameter can be specified')
            raise exc.HTTPBadRequest(explanation=msg)
        elif 'host' not in body:
            msg = _('Host parameter must be specified')
            raise exc.HTTPBadRequest(explanation=msg)
        try:
            utils.check_string_length(body['host'], 'host', 1, 255)
        except exception.InvalidInput as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        host = body['host']

        return fn(self, req, id, host, *args, **kwargs)
Пример #12
0
    def wrapped(self, req, id, body, *args, **kwargs):
        if len(body) != 1:
            msg = _('Only host parameter can be specified')
            raise exc.HTTPBadRequest(explanation=msg)
        elif 'host' not in body:
            msg = _('Host parameter must be specified')
            raise exc.HTTPBadRequest(explanation=msg)
        try:
            utils.check_string_length(body['host'], 'host', 1, 255)
        except exception.InvalidInput as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        host = body['host']

        return fn(self, req, id, host, *args, **kwargs)
Пример #13
0
def validate_device_name(value):
    try:
        # NOTE (ndipanov): Do not allow empty device names
        #                  until assigning default values
        #                  is supported by compute.compute
        utils.check_string_length(value,
                                  'Device name',
                                  min_length=1,
                                  max_length=255)
    except exception.InvalidInput:
        raise exception.InvalidBDMFormat(
            details=_("Device name empty or too long."))

    if ' ' in value:
        raise exception.InvalidBDMFormat(
            details=_("Device name contains spaces."))
Пример #14
0
    def validate_property(self, value, property, allowed):
        """Validate given security group property.

        :param value:    the value to validate, as a string or unicode
        :param property: the property, either 'name' or 'description'
        :param allowed:  the range of characters allowed, but not used because
                         Neutron is allowing any characters.
        """

        # NOTE: If using compute-network as the backend, min_length is 1. However
        # if using Neutron, Nova has allowed empty string as its history.
        # So this min_length should be 0 for passing the existing requests.
        utils.check_string_length(value,
                                  name=property,
                                  min_length=0,
                                  max_length=255)
Пример #15
0
    def update(self, req, id, body):
        context = req.environ['compute.context']
        authorize(context, action='update', target={'quota_class': id})
        try:
            utils.check_string_length(id, 'quota_class_name',
                                      min_length=1, max_length=255)
        except exception.InvalidInput as e:
            raise webob.exc.HTTPBadRequest(
                explanation=e.format_message())

        quota_class = id

        for key, value in six.iteritems(body['quota_class_set']):
            try:
                db.quota_class_update(context, quota_class, key, value)
            except exception.QuotaClassNotFound:
                db.quota_class_create(context, quota_class, key, value)

        values = QUOTAS.get_class_quotas(context, quota_class)
        return self._format_quota_set(None, values)
Пример #16
0
    def update(self, req, id, body):
        context = req.environ['compute.context']
        authorize(context, action='update', target={'quota_class': id})
        try:
            utils.check_string_length(id,
                                      'quota_class_name',
                                      min_length=1,
                                      max_length=255)
        except exception.InvalidInput as e:
            raise webob.exc.HTTPBadRequest(explanation=e.format_message())

        quota_class = id

        for key, value in six.iteritems(body['quota_class_set']):
            try:
                db.quota_class_update(context, quota_class, key, value)
            except exception.QuotaClassNotFound:
                db.quota_class_create(context, quota_class, key, value)

        values = QUOTAS.get_class_quotas(context, quota_class)
        return self._format_quota_set(None, values)
Пример #17
0
    def update(self, req, id, body):
        """Updates the name and/or availability_zone of given aggregate."""
        context = _get_context(req)
        authorize(context)

        if len(body) != 1:
            raise exc.HTTPBadRequest()
        try:
            updates = body["aggregate"]
        except KeyError:
            raise exc.HTTPBadRequest()

        if len(updates) < 1:
            raise exc.HTTPBadRequest()

        for key in updates.keys():
            if key not in ["name", "availability_zone"]:
                raise exc.HTTPBadRequest()

        try:
            if 'name' in updates:
                utils.check_string_length(updates['name'], "Aggregate name", 1,
                                          255)
            if updates.get("availability_zone") is not None:
                utils.check_string_length(updates['availability_zone'],
                                          "Availability_zone", 1, 255)
        except exception.InvalidInput as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        try:
            aggregate = self.api.update_aggregate(context, id, updates)
        except exception.AggregateNameExists as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.AggregateNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InvalidAggregateAction as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        return self._marshall_aggregate(aggregate)
Пример #18
0
    def update(self, req, id, body):
        """Updates the name and/or availability_zone of given aggregate."""
        context = _get_context(req)
        authorize(context)

        if len(body) != 1:
            raise exc.HTTPBadRequest()
        try:
            updates = body["aggregate"]
        except KeyError:
            raise exc.HTTPBadRequest()

        if len(updates) < 1:
            raise exc.HTTPBadRequest()

        for key in updates.keys():
            if key not in ["name", "availability_zone"]:
                raise exc.HTTPBadRequest()

        try:
            if 'name' in updates:
                utils.check_string_length(updates['name'], "Aggregate name", 1,
                                          255)
            if updates.get("availability_zone") is not None:
                utils.check_string_length(updates['availability_zone'],
                                          "Availability_zone", 1, 255)
        except exception.InvalidInput as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        try:
            aggregate = self.api.update_aggregate(context, id, updates)
        except exception.AggregateNameExists as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.AggregateNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InvalidAggregateAction as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        return self._marshall_aggregate(aggregate)
Пример #19
0
    def create(self, req, body):
        """Creates an aggregate, given its name and
        optional availability zone.
        """
        context = _get_context(req)
        authorize(context)

        if len(body) != 1:
            raise exc.HTTPBadRequest()
        try:
            host_aggregate = body["aggregate"]
            name = host_aggregate["name"]
        except KeyError:
            raise exc.HTTPBadRequest()
        avail_zone = host_aggregate.get("availability_zone")
        try:
            utils.check_string_length(name, "Aggregate name", 1, 255)
            if avail_zone is not None:
                utils.check_string_length(avail_zone, "Availability_zone", 1,
                                          255)
        except exception.InvalidInput as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        try:
            aggregate = self.api.create_aggregate(context, name, avail_zone)
        except exception.AggregateNameExists as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InvalidAggregateAction as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        agg = self._marshall_aggregate(aggregate)

        # To maintain the same API result as before the changes for returning
        # compute objects were made.
        del agg['aggregate']['hosts']
        del agg['aggregate']['metadata']

        return agg
Пример #20
0
    def create(self, req, body):
        """Creates an aggregate, given its name and
        optional availability zone.
        """
        context = _get_context(req)
        authorize(context)

        if len(body) != 1:
            raise exc.HTTPBadRequest()
        try:
            host_aggregate = body["aggregate"]
            name = host_aggregate["name"]
        except KeyError:
            raise exc.HTTPBadRequest()
        avail_zone = host_aggregate.get("availability_zone")
        try:
            utils.check_string_length(name, "Aggregate name", 1, 255)
            if avail_zone is not None:
                utils.check_string_length(avail_zone, "Availability_zone", 1,
                                          255)
        except exception.InvalidInput as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        try:
            aggregate = self.api.create_aggregate(context, name, avail_zone)
        except exception.AggregateNameExists as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InvalidAggregateAction as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        agg = self._marshall_aggregate(aggregate)

        # To maintain the same API result as before the changes for returning
        # compute objects were made.
        del agg['aggregate']['hosts']
        del agg['aggregate']['metadata']

        return agg
Пример #21
0
    def _set_metadata(self, req, id, body):
        """Replaces the aggregate's existing metadata with new metadata."""
        context = _get_context(req)
        authorize(context)

        if len(body) != 1:
            raise exc.HTTPBadRequest()
        try:
            metadata = body["metadata"]
        except KeyError:
            raise exc.HTTPBadRequest()

        # The metadata should be a dict
        if not isinstance(metadata, dict):
            msg = _('The value of metadata must be a dict')
            raise exc.HTTPBadRequest(explanation=msg)
        try:
            for key, value in metadata.items():
                utils.check_string_length(key, "metadata.key", 1, 255)
                if value is not None:
                    utils.check_string_length(value, "metadata.value", 0, 255)
        except exception.InvalidInput as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
        try:
            aggregate = self.api.update_aggregate_metadata(
                context, id, metadata)
        except exception.AggregateNotFound:
            msg = _('Cannot set metadata %(metadata)s in aggregate'
                    ' %(id)s') % {
                        'metadata': metadata,
                        'id': id
                    }
            raise exc.HTTPNotFound(explanation=msg)
        except exception.InvalidAggregateAction as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        return self._marshall_aggregate(aggregate)
Пример #22
0
    def update(self, req, id, body):
        """Update an existing agent build."""
        context = req.environ['compute.context']
        authorize(context)
        # NOTE(alex_xu): back-compatible with db layer hard-code admin
        # permission checks.
        nova_context.require_admin_context(context)
        try:
            para = body['para']
            url = para['url']
            md5hash = para['md5hash']
            version = para['version']
        except (TypeError, KeyError) as ex:
            msg = _("Invalid request body: %s") % ex
            raise webob.exc.HTTPBadRequest(explanation=msg)

        try:
            utils.validate_integer(id, 'id')
            utils.check_string_length(url, 'url', max_length=255)
            utils.check_string_length(md5hash, 'md5hash', max_length=255)
            utils.check_string_length(version, 'version', max_length=255)
        except exception.InvalidInput as exc:
            raise webob.exc.HTTPBadRequest(explanation=exc.format_message())

        try:
            agent = objects.Agent(context=context, id=id)
            agent.obj_reset_changes()
            agent.version = version
            agent.url = url
            agent.md5hash = md5hash
            agent.save()
        except exception.AgentBuildNotFound as ex:
            raise webob.exc.HTTPNotFound(explanation=ex.format_message())

        # NOTE(alex_xu): The agent_id should be integer that consistent with
        # create/index actions. But parameter 'id' is string type that parsed
        # from url. This is a bug, but because back-compatibility, it can't be
        # fixed for v2 API. This will be fixed in v2.1 API by Microversions in
        # the future. lp bug #1333494
        return {
            "agent": {
                'agent_id': id,
                'version': version,
                'url': url,
                'md5hash': md5hash
            }
        }
Пример #23
0
    def update(self, req, id, body):
        """Update an existing agent build."""
        context = req.environ['compute.context']
        authorize(context)
        # NOTE(alex_xu): back-compatible with db layer hard-code admin
        # permission checks.
        nova_context.require_admin_context(context)
        try:
            para = body['para']
            url = para['url']
            md5hash = para['md5hash']
            version = para['version']
        except (TypeError, KeyError) as ex:
            msg = _("Invalid request body: %s") % ex
            raise webob.exc.HTTPBadRequest(explanation=msg)

        try:
            utils.validate_integer(id, 'id')
            utils.check_string_length(url, 'url', max_length=255)
            utils.check_string_length(md5hash, 'md5hash', max_length=255)
            utils.check_string_length(version, 'version', max_length=255)
        except exception.InvalidInput as exc:
            raise webob.exc.HTTPBadRequest(explanation=exc.format_message())

        try:
            agent = objects.Agent(context=context, id=id)
            agent.obj_reset_changes()
            agent.version = version
            agent.url = url
            agent.md5hash = md5hash
            agent.save()
        except exception.AgentBuildNotFound as ex:
            raise webob.exc.HTTPNotFound(explanation=ex.format_message())

        # NOTE(alex_xu): The agent_id should be integer that consistent with
        # create/index actions. But parameter 'id' is string type that parsed
        # from url. This is a bug, but because back-compatibility, it can't be
        # fixed for v2 API. This will be fixed in v2.1 API by Microversions in
        # the future. lp bug #1333494
        return {"agent": {'agent_id': id, 'version': version,
                'url': url, 'md5hash': md5hash}}
Пример #24
0
    def create(self, req, body):
        """Creates a new agent build."""
        context = req.environ['compute.context']
        authorize(context)
        # NOTE(alex_xu): back-compatible with db layer hard-code admin
        # permission checks.
        nova_context.require_admin_context(context)
        try:
            agent = body['agent']
            hypervisor = agent['hypervisor']
            os = agent['os']
            architecture = agent['architecture']
            version = agent['version']
            url = agent['url']
            md5hash = agent['md5hash']
        except (TypeError, KeyError) as ex:
            msg = _("Invalid request body: %s") % ex
            raise webob.exc.HTTPBadRequest(explanation=msg)

        try:
            utils.check_string_length(hypervisor, 'hypervisor', max_length=255)
            utils.check_string_length(os, 'os', max_length=255)
            utils.check_string_length(architecture, 'architecture',
                                      max_length=255)
            utils.check_string_length(version, 'version', max_length=255)
            utils.check_string_length(url, 'url', max_length=255)
            utils.check_string_length(md5hash, 'md5hash', max_length=255)
        except exception.InvalidInput as exc:
            raise webob.exc.HTTPBadRequest(explanation=exc.format_message())

        try:
            agent_obj = objects.Agent(context=context)
            agent_obj.hypervisor = hypervisor
            agent_obj.os = os
            agent_obj.architecture = architecture
            agent_obj.version = version
            agent_obj.url = url
            agent_obj.md5hash = md5hash
            agent_obj.create()
            agent['agent_id'] = agent_obj.id
        except exception.AgentBuildExists as ex:
            raise webob.exc.HTTPConflict(explanation=ex.format_message())
        return {'agent': agent}
Пример #25
0
def create(name,
           memory,
           vcpus,
           root_gb,
           ephemeral_gb=0,
           flavorid=None,
           swap=0,
           rxtx_factor=1.0,
           is_public=True):
    """Creates flavors."""
    if not flavorid:
        flavorid = uuid.uuid4()

    kwargs = {
        'memory_mb': memory,
        'vcpus': vcpus,
        'root_gb': root_gb,
        'ephemeral_gb': ephemeral_gb,
        'swap': swap,
        'rxtx_factor': rxtx_factor,
    }

    if isinstance(name, six.string_types):
        name = name.strip()
    # ensure name do not exceed 255 characters
    utils.check_string_length(name, 'name', min_length=1, max_length=255)

    # ensure name does not contain any special characters
    valid_name = parameter_types.valid_name_regex_obj.search(name)
    if not valid_name:
        msg = _("Flavor names can only contain printable characters "
                "and horizontal spaces.")
        raise exception.InvalidInput(reason=msg)

    # NOTE(vish): Internally, flavorid is stored as a string but it comes
    #             in through json as an integer, so we convert it here.
    flavorid = six.text_type(flavorid)

    # ensure leading/trailing whitespaces not present.
    if flavorid.strip() != flavorid:
        msg = _("id cannot contain leading and/or trailing whitespace(s)")
        raise exception.InvalidInput(reason=msg)

    # ensure flavor id does not exceed 255 characters
    utils.check_string_length(flavorid, 'id', min_length=1, max_length=255)

    # ensure flavor id does not contain any special characters
    valid_flavor_id = VALID_ID_REGEX.search(flavorid)
    if not valid_flavor_id:
        msg = _("Flavor id can only contain letters from A-Z (both cases), "
                "periods, dashes, underscores and spaces.")
        raise exception.InvalidInput(reason=msg)

    # NOTE(wangbo): validate attributes of the creating flavor.
    # ram and vcpus should be positive ( > 0) integers.
    # disk, ephemeral and swap should be non-negative ( >= 0) integers.
    flavor_attributes = {
        'memory_mb': ('ram', 1),
        'vcpus': ('vcpus', 1),
        'root_gb': ('disk', 0),
        'ephemeral_gb': ('ephemeral', 0),
        'swap': ('swap', 0)
    }

    for key, value in flavor_attributes.items():
        kwargs[key] = utils.validate_integer(kwargs[key], value[0], value[1],
                                             db.MAX_INT)

    # rxtx_factor should be a positive float
    try:
        kwargs['rxtx_factor'] = float(kwargs['rxtx_factor'])
        if (kwargs['rxtx_factor'] <= 0
                or kwargs['rxtx_factor'] > SQL_SP_FLOAT_MAX):
            raise ValueError()
    except ValueError:
        msg = (_("'rxtx_factor' argument must be a float between 0 and %g") %
               SQL_SP_FLOAT_MAX)
        raise exception.InvalidInput(reason=msg)

    kwargs['name'] = name
    kwargs['flavorid'] = flavorid
    # ensure is_public attribute is boolean
    try:
        kwargs['is_public'] = strutils.bool_from_string(is_public, strict=True)
    except ValueError:
        raise exception.InvalidInput(reason=_("is_public must be a boolean"))

    flavor = objects.Flavor(context=context.get_admin_context(), **kwargs)
    flavor.create()
    return flavor
Пример #26
0
    def create(self, req, body):
        """Creates a new agent build."""
        context = req.environ['compute.context']
        authorize(context)
        # NOTE(alex_xu): back-compatible with db layer hard-code admin
        # permission checks.
        nova_context.require_admin_context(context)
        try:
            agent = body['agent']
            hypervisor = agent['hypervisor']
            os = agent['os']
            architecture = agent['architecture']
            version = agent['version']
            url = agent['url']
            md5hash = agent['md5hash']
        except (TypeError, KeyError) as ex:
            msg = _("Invalid request body: %s") % ex
            raise webob.exc.HTTPBadRequest(explanation=msg)

        try:
            utils.check_string_length(hypervisor, 'hypervisor', max_length=255)
            utils.check_string_length(os, 'os', max_length=255)
            utils.check_string_length(architecture,
                                      'architecture',
                                      max_length=255)
            utils.check_string_length(version, 'version', max_length=255)
            utils.check_string_length(url, 'url', max_length=255)
            utils.check_string_length(md5hash, 'md5hash', max_length=255)
        except exception.InvalidInput as exc:
            raise webob.exc.HTTPBadRequest(explanation=exc.format_message())

        try:
            agent_obj = objects.Agent(context=context)
            agent_obj.hypervisor = hypervisor
            agent_obj.os = os
            agent_obj.architecture = architecture
            agent_obj.version = version
            agent_obj.url = url
            agent_obj.md5hash = md5hash
            agent_obj.create()
            agent['agent_id'] = agent_obj.id
        except exception.AgentBuildExists as ex:
            raise webob.exc.HTTPConflict(explanation=ex.format_message())
        return {'agent': agent}