def update(self, req, id, body): """Updates the name and/or description of given affinity group.""" context = _get_context(req) authorize(context) if len(body) != 1: raise exc.HTTPBadRequest() description = "" try: affinitygroup_updates = body["os-affinity-group"] name = affinitygroup_updates.get("name", None) description = affinitygroup_updates.get("description", None) except KeyError: raise exc.HTTPBadRequest() try: if name != None: utils.check_string_length(name, "Affinity Group name", 1, 255) if description != None: utils.check_string_length(description, "Affinity Group description", 1, 255) except exception.InvalidInput as e: raise exc.HTTPBadRequest(explanation=e.format_message()) try: affinity_group = self.api.update_affinitygroup(context, id, affinitygroup_updates) except huawei_exception.AffinityGroupNotFound: LOG.info(_('Cannot update affinity_group: %s'), id) raise exc.HTTPNotFound() return self._marshall_affinity_group(affinity_group)
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) 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: LOG.info(e) raise exc.HTTPConflict() except exception.InvalidAggregateAction as e: LOG.info(e) raise return self._marshall_aggregate(aggregate)
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, (int, long, float))): 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())
def _set_metadata(self, req, id, body): """Replaces the aggregate's existing metadata with new metadata.""" context = _get_context(req) authorize(context, action='set_metadata') if not self.is_valid_body(body, 'set_metadata'): raise exc.HTTPBadRequest(explanation=_("Invalid request body")) if not self.is_valid_body(body["set_metadata"], "metadata"): raise exc.HTTPBadRequest( explanation=_("Invalid request format for metadata")) metadata = body["set_metadata"]["metadata"] # 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 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)
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
def create(self, req, body): """Creates an aggregate, given its name and optional availability zone. """ context = _get_context(req) authorize(context, action='create') if not self.is_valid_body(body, 'aggregate'): raise exc.HTTPBadRequest(explanation=_("Invalid request body")) try: host_aggregate = body["aggregate"] name = host_aggregate["name"] except KeyError as e: msg = _("Could not find %s parameter in the request") % e.args[0] raise exc.HTTPBadRequest(explanation=msg) 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()) return self._marshall_aggregate(aggregate)
def _validate_input_body(self, body, entity_name): if not self.is_valid_body(body, entity_name): msg = _("the body is invalid.") raise nova.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 nova.exception.InvalidInput(reason=msg) if field == 'name': utils.check_string_length(value, field, min_length=1, max_length=255) if not common.VALID_NAME_REGEX.search(value): msg = _("Invalid format for name: '%s'") % value raise nova.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 nova.exception.InvalidInput(reason=msg) if subbody: msg = _("unsupported fields: %s") % subbody.keys() raise nova.exception.InvalidInput(reason=msg)
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() if 'name' in updates: try: utils.check_string_length(updates['name'], "Aggregate name", 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.AggregateNotFound: LOG.info(_('Cannot update aggregate: %s'), id) raise exc.HTTPNotFound() except exception.InvalidAggregateAction as e: raise exc.HTTPBadRequest(explanation=e.format_message()) return self._marshall_aggregate(aggregate)
def update(self, req, id, body): """Updates the name and/or availability_zone of given aggregate.""" context = _get_context(req) authorize(context, action='update') if not self.is_valid_body(body, 'aggregate'): raise exc.HTTPBadRequest(explanation=_("Invalid request body")) updates = body["aggregate"] if len(updates) < 1: raise exc.HTTPBadRequest( explanation=_("Request body is empty")) for key in updates.keys(): if key not in ["name", "availability_zone"]: msg = _("Invalid key %s in request body.") % key raise exc.HTTPBadRequest(explanation=msg) if 'name' in updates: try: utils.check_string_length(updates['name'], "Aggregate name", 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.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)
def _validate_input_body(self, body, entity_name): if not self.is_valid_body(body, entity_name): msg = _("the body is invalid.") raise nova.exception.InvalidInput(reason=msg) subbody = dict(body[entity_name]) policies = subbody.get("policies") # Validate that the policies do not contradict one another self._validate_policies(policies) 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 nova.exception.InvalidInput(reason=msg) if isinstance(value, basestring): utils.check_string_length(value, field, min_length=1, max_length=255) elif isinstance(value, list): [utils.check_string_length(v, field, min_length=1, max_length=255) for v in value] if subbody: msg = _("unsupported fields: %s") % subbody.keys() raise nova.exception.InvalidInput(reason=msg)
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)
def create(self, req, body): """Creates an aggregate, given its name and availability_zone.""" context = _get_context(req) authorize(context) try: host_aggregate = body["aggregate"] name = host_aggregate["name"] avail_zone = host_aggregate["availability_zone"] except KeyError as e: msg = _("Could not find %s parameter in the request") % e.args[0] raise exc.HTTPBadRequest(explanation=msg) if len(body) != 1 or len(host_aggregate) != 2: raise exc.HTTPBadRequest() try: utils.check_string_length(name, "Aggregate name", 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()) return self._marshall_aggregate(aggregate)
def create(self, req, body): """Creates an affinity group, given its name and type.""" context = _get_context(req) authorize(context) if len(body) != 1: raise exc.HTTPBadRequest() try: affinity_group = body["os-affinity-group"] name = affinity_group.get("name") description = affinity_group.get("description", "") affinity_type = affinity_group.get("type", "affinity") metadata = affinity_group.get("metadata", {}) except KeyError: raise exc.HTTPBadRequest() try: utils.check_string_length(name, "Affinity Group Name", 1, 255) except exception.InvalidInput as e: raise exc.HTTPBadRequest(explanation=e.format_message()) try: affinityGroup = self.api.create_affinity_group(context, name, description, affinity_type, metadata) except huawei_exception.AffinityGroupNameExists as e: LOG.info(e) raise exc.HTTPConflict() except huawei_exception.InvalidAffinityGroupAction as e: LOG.info(e) raise return self._marshall_affinity_group(affinityGroup)
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())
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())
def validate_device_name(value): try: # NOTE (ndipanov): Do not allow empty device names # until assigning default values # is supported by nova.compute utils.check_string_length(value, "Device name", min_length=1, max_length=255) except exception.InvalidInput as e: raise exception.InvalidBDMFormat(details="Device name empty or too long.") if " " in value: raise exception.InvalidBDMFormat(details="Device name contains spaces.")
def _migrate(self, req, id, body): if body.get('migrate') is not None: if not self.is_valid_body(body, 'migrate'): raise exc.HTTPBadRequest( explanation=_("Malformed request body")) try: host = body.get('migrate').get('host') if host is not None: utils.check_string_length(host, 'host', min_length=1, max_length=255) except exception.InvalidInput as e: raise exc.HTTPBadRequest(explanation=e.format_message()) yield
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 nova-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)
def validate_device_name(value): try: # NOTE (ndipanov): Do not allow empty device names # until assigning default values # are supported by nova.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."))
def update(self, req, id, body): context = req.environ['nova.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 db 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. nova.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)
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)
def update(self, req, id, body): context = req.environ["nova.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 db 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. nova.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)
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 exception.InvalidInput as error: raise exc.HTTPBadRequest(explanation=error.format_message()) for key, value in specs.iteritems(): try: utils.check_string_length(key, 'extra_specs key', min_length=1, max_length=255) utils.check_string_length(value, 'extra_specs value', max_length=255) except exception.InvalidInput as error: raise exc.HTTPBadRequest(explanation=error.format_message())
def update(self, req, id, body): context = req.environ['nova.context'] context.can(qcs_policies.POLICY_ROOT % 'update', {'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)
def test_check_string_length(self): self.assertIsNone(utils.check_string_length( 'test', 'name', max_length=255)) self.assertRaises(exception.InvalidInput, utils.check_string_length, 11, 'name', max_length=255) self.assertRaises(exception.InvalidInput, utils.check_string_length, '', 'name', min_length=1) self.assertRaises(exception.InvalidInput, utils.check_string_length, 'a' * 256, 'name', max_length=255)
def test_check_string_length_noname(self): self.assertIsNone(utils.check_string_length( 'test', max_length=255)) self.assertRaises(exception.InvalidInput, utils.check_string_length, 11, max_length=255) self.assertRaises(exception.InvalidInput, utils.check_string_length, '', min_length=1) self.assertRaises(exception.InvalidInput, utils.check_string_length, 'a' * 256, max_length=255)
def update(self, req, id, body): """Update an existing agent build.""" context = req.environ['nova.context'] authorize(context) try: para = body['para'] url = para['url'] md5hash = para['md5hash'] version = para['version'] except (TypeError, KeyError): raise webob.exc.HTTPUnprocessableEntity() try: 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: db.agent_build_update(context, id, {'version': version, 'url': url, 'md5hash': md5hash}) 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 after v3 API feature exposed by # micro-version in the future. lp bug #1333494 return {"agent": {'agent_id': id, 'version': version, 'url': url, 'md5hash': md5hash}}
def update(self, req, id, body): """Update an existing agent build.""" context = req.environ['nova.context'] authorize(context) try: para = body['para'] url = para['url'] md5hash = para['md5hash'] version = para['version'] except (TypeError, KeyError): raise webob.exc.HTTPUnprocessableEntity() try: 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: db.agent_build_update(context, id, {'version': version, 'url': url, 'md5hash': md5hash}) except exception.AgentBuildNotFound as ex: raise webob.exc.HTTPNotFound(explanation=ex.format_message()) return {"agent": {'agent_id': id, 'version': version, 'url': url, 'md5hash': md5hash}}
def update(self, req, id, body): """Update an existing agent build.""" context = req.environ['nova.context'] authorize(context) try: para = body['agent'] url = para['url'] md5hash = para['md5hash'] version = para['version'] except TypeError as e: raise webob.exc.HTTPBadRequest() except KeyError as e: raise webob.exc.HTTPBadRequest(explanation=_( "Could not find %s parameter in the request") % e.args[0]) try: 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: db.agent_build_update(context, id, {'version': version, 'url': url, 'md5hash': md5hash}) except exception.AgentBuildNotFound as ex: raise webob.exc.HTTPNotFound(explanation=ex.format_message()) return {"agent": {'agent_id': id, 'version': version, 'url': url, 'md5hash': md5hash}}
def _update(self, req, id, body, filtered_quotas=None, exclude_server_groups=False): context = req.environ['nova.context'] context.can(qcs_policies.POLICY_ROOT % 'update', {'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 body['quota_class_set'].items(): try: objects.Quotas.update_class(context, quota_class, key, value) except exception.QuotaClassNotFound: objects.Quotas.create_class(context, quota_class, key, value) values = QUOTAS.get_class_quotas(context, quota_class) return self._format_quota_set(None, values, filtered_quotas, exclude_server_groups)
def _check_extra_specs_value(self, req, specs): validation_supported = api_version_request.is_supported( req, min_version='2.86', ) for name, value in specs.items(): # NOTE(gmann): Max length for numeric value is being checked # explicitly as json schema cannot have max length check for # numeric value if isinstance(value, (six.integer_types, float)): value = six.text_type(value) try: utils.check_string_length(value, 'extra_specs value', max_length=255) except exception.InvalidInput as error: raise webob.exc.HTTPBadRequest( explanation=error.format_message()) if validation_supported: validators.validate(name, value)
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)
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 # nova objects were made. del agg['aggregate']['hosts'] del agg['aggregate']['metadata'] return agg
def _validate_input_body(self, body, entity_name): if not self.is_valid_body(body, entity_name): msg = _("the body is invalid.") raise nova.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 nova.exception.InvalidInput(reason=msg) if field == 'name': utils.check_string_length(value, field, min_length=1, max_length=255) if not common.VALID_NAME_REGEX.search(value): msg = _("Invalid format for name: '%s'") % value raise nova.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 nova.exception.InvalidInput(reason=msg) if subbody: msg = _("unsupported fields: %s") % subbody.keys() raise nova.exception.InvalidInput(reason=msg)
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)
def update(self, req, id, body): """Update an existing agent build.""" context = req.environ['nova.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.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 ValueError as ex: msg = _("Invalid request body: %s") % ex raise webob.exc.HTTPBadRequest(explanation=msg) 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 after v3 API feature exposed by # micro-version in the future. lp bug #1333494 return { "agent": { 'agent_id': id, 'version': version, 'url': url, 'md5hash': md5hash } }
def update(self, req, id, body): """Update an existing agent build.""" context = req.environ['nova.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.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 ValueError as ex: msg = _("Invalid request body: %s") % ex raise webob.exc.HTTPBadRequest(explanation=msg) 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 after v3 API feature exposed by # micro-version in the future. lp bug #1333494 return {"agent": {'agent_id': id, 'version': version, 'url': url, 'md5hash': md5hash}}
def create(name, memory, vcpus, root_gb, ephemeral_gb=None, flavorid=None, swap=None, rxtx_factor=None, is_public=True): """Creates instance types.""" if flavorid is None or flavorid == '': flavorid = uuid.uuid4() if swap is None: swap = 0 if rxtx_factor is None: rxtx_factor = 1.0 if ephemeral_gb is None: ephemeral_gb = 0 kwargs = { 'memory_mb': memory, 'vcpus': vcpus, 'root_gb': root_gb, 'ephemeral_gb': ephemeral_gb, 'swap': swap, 'rxtx_factor': rxtx_factor, } # 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 invalid_name = INVALID_NAME_REGEX.search(name) if invalid_name: msg = _("names can only contain [a-zA-Z0-9_.- ]") raise exception.InvalidInput(reason=msg) # ensure some attributes are integers and greater than or equal to 0 for option in ['memory_mb', 'vcpus', 'root_gb', 'ephemeral_gb', 'swap']: try: kwargs[option] = int(kwargs[option]) assert kwargs[option] >= 0 except (ValueError, AssertionError): msg = _("'%s' argument must be a positive integer") % option raise exception.InvalidInput(reason=msg) # rxtx_factor should be a positive float try: kwargs['rxtx_factor'] = float(kwargs['rxtx_factor']) assert kwargs['rxtx_factor'] > 0 except (ValueError, AssertionError): msg = _("'rxtx_factor' argument must be a positive float") raise exception.InvalidInput(reason=msg) # some value are required to be nonzero, not just positive for option in ['memory_mb', 'vcpus']: try: assert kwargs[option] > 0 except AssertionError: msg = _("'%s' argument must be greater than 0") % option raise exception.InvalidInput(reason=msg) kwargs['name'] = name # NOTE(vish): Internally, flavorid is stored as a string but it comes # in through json as an integer, so we convert it here. kwargs['flavorid'] = unicode(flavorid) # ensure is_public attribute is boolean if not utils.is_valid_boolstr(is_public): msg = _("is_public must be a boolean") raise exception.InvalidInput(reason=msg) kwargs['is_public'] = utils.bool_from_str(is_public) try: return db.instance_type_create(context.get_admin_context(), kwargs) except db_exc.DBError, e: LOG.exception(_('DB error: %s') % e) raise exception.InstanceTypeCreateFailed()
def create(self, req, body): """Creates a new agent build.""" context = req.environ['nova.context'] authorize(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): raise webob.exc.HTTPUnprocessableEntity() 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.HTTPServerError(explanation=ex.format_message()) return {'agent': agent}
def create(self, req, body): """Creates a new agent build.""" context = req.environ['nova.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}
def create(self, req, body): """Creates a new agent build.""" context = req.environ['nova.context'] authorize(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 as e: raise webob.exc.HTTPBadRequest() except KeyError as e: raise webob.exc.HTTPBadRequest( explanation=_("Could not find %s parameter in the request") % e.args[0]) 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_build_ref = db.agent_build_create( context, { 'hypervisor': hypervisor, 'os': os, 'architecture': architecture, 'version': version, 'url': url, 'md5hash': md5hash }) agent['agent_id'] = agent_build_ref.id except exception.AgentBuildExists as ex: raise webob.exc.HTTPConflict(explanation=ex.format_message()) return {'agent': agent}
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, } # 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 invalid_name = INVALID_NAME_REGEX.search(name) if invalid_name: msg = _("names can only contain [a-zA-Z0-9_.- ]") raise exception.InvalidInput(reason=msg) # Some attributes are positive ( > 0) integers for option in ['memory_mb', 'vcpus']: try: if int(str(kwargs[option])) <= 0: raise ValueError() kwargs[option] = int(kwargs[option]) except (ValueError, TypeError): msg = _("'%s' argument must be a positive integer") % option raise exception.InvalidInput(reason=msg) # Some attributes are non-negative ( >= 0) integers for option in ['root_gb', 'ephemeral_gb', 'swap']: try: if int(str(kwargs[option])) < 0: raise ValueError() kwargs[option] = int(kwargs[option]) except (ValueError, TypeError): msg = _("'%s' argument must be an integer greater than or" " equal to 0") % option raise exception.InvalidInput(reason=msg) # rxtx_factor should be a positive float try: kwargs['rxtx_factor'] = float(kwargs['rxtx_factor']) if kwargs['rxtx_factor'] <= 0: raise ValueError() except ValueError: msg = _("'rxtx_factor' argument must be a positive float") raise exception.InvalidInput(reason=msg) kwargs['name'] = name # NOTE(vish): Internally, flavorid is stored as a string but it comes # in through json as an integer, so we convert it here. kwargs['flavorid'] = unicode(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")) try: return db.flavor_create(context.get_admin_context(), kwargs) except db_exc.DBError as e: LOG.exception(_('DB error: %s') % e) raise exception.InstanceTypeCreateFailed()
def create(self, req, body): """Creates a new agent build.""" context = req.environ['nova.context'] authorize(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): raise webob.exc.HTTPUnprocessableEntity() 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_build_ref = db.agent_build_create( context, { 'hypervisor': hypervisor, 'os': os, 'architecture': architecture, 'version': version, 'url': url, 'md5hash': md5hash }) agent['agent_id'] = agent_build_ref.id except Exception as ex: raise webob.exc.HTTPServerError(str(ex)) return {'agent': agent}
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 = VALID_NAME_REGEX.search(name) if not valid_name: msg = _("Flavor names can only contain alphanumeric characters, " "periods, dashes, underscores and 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 = unicode(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")) try: return db.flavor_create(context.get_admin_context(), kwargs) except db_exc.DBError as e: LOG.exception(_LE('DB error: %s'), e) raise exception.FlavorCreateFailed()
def create(self, req, body): """Creates a new agent build.""" context = req.environ['nova.context'] authorize(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 as e: raise webob.exc.HTTPBadRequest() except KeyError as e: raise webob.exc.HTTPBadRequest(explanation=_( "Could not find %s parameter in the request") % e.args[0]) 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_build_ref = db.agent_build_create(context, {'hypervisor': hypervisor, 'os': os, 'architecture': architecture, 'version': version, 'url': url, 'md5hash': md5hash}) agent['agent_id'] = agent_build_ref.id except exception.AgentBuildExists as ex: raise webob.exc.HTTPConflict(explanation=ex.format_message()) return {'agent': agent}
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 = VALID_NAME_OR_ID_REGEX.search(name) if not valid_name: msg = _("names can only contain [a-zA-Z0-9_.- ]") 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 = unicode(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_NAME_OR_ID_REGEX.search(flavorid) if not valid_flavor_id: msg = _("id can only contain [a-zA-Z0-9_.- ]") raise exception.InvalidInput(reason=msg) # Some attributes are positive ( > 0) integers for option in ['memory_mb', 'vcpus']: kwargs[option] = utils.validate_integer(kwargs[option], option, 1, sys.maxint) # Some attributes are non-negative ( >= 0) integers for option in ['root_gb', 'ephemeral_gb', 'swap']: kwargs[option] = utils.validate_integer(kwargs[option], option, 0, sys.maxint) # rxtx_factor should be a positive float try: kwargs['rxtx_factor'] = float(kwargs['rxtx_factor']) if kwargs['rxtx_factor'] <= 0: raise ValueError() except ValueError: msg = _("'rxtx_factor' argument must be a positive float") 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")) try: return db.flavor_create(context.get_admin_context(), kwargs) except db_exc.DBError as e: LOG.exception(_('DB error: %s') % e) raise exception.InstanceTypeCreateFailed()