Merge "Add JSON schema to limits
"
This commit is contained in:
commit
516a341b90
@ -17,10 +17,10 @@ import http.client
|
||||
import flask
|
||||
import flask_restful
|
||||
|
||||
from keystone.api import validation
|
||||
from keystone.common import json_home
|
||||
from keystone.common import provider_api
|
||||
from keystone.common import rbac_enforcer
|
||||
from keystone.common import validation
|
||||
from keystone import exception
|
||||
from keystone.limit import schema
|
||||
from keystone.server import flask as ks_flask
|
||||
@ -58,7 +58,13 @@ class LimitsResource(ks_flask.ResourceBase):
|
||||
api='unified_limit_api', method='get_limit'
|
||||
)
|
||||
|
||||
def _list_limits(self):
|
||||
@validation.request_query_schema(schema.limits_index_request_query)
|
||||
@validation.response_body_schema(schema.limits_index_response_body)
|
||||
def get(self):
|
||||
"""List limits.
|
||||
|
||||
GET /v3/limits
|
||||
"""
|
||||
filters = [
|
||||
'service_id',
|
||||
'region_id',
|
||||
@ -95,25 +101,17 @@ class LimitsResource(ks_flask.ResourceBase):
|
||||
|
||||
return self.wrap_collection(filtered_refs, hints=hints)
|
||||
|
||||
def _get_limit(self, limit_id):
|
||||
ENFORCER.enforce_call(
|
||||
action='identity:get_limit',
|
||||
build_target=_build_limit_enforcement_target,
|
||||
)
|
||||
ref = PROVIDERS.unified_limit_api.get_limit(limit_id)
|
||||
return self.wrap_member(ref)
|
||||
|
||||
def get(self, limit_id=None):
|
||||
if limit_id is not None:
|
||||
return self._get_limit(limit_id)
|
||||
return self._list_limits()
|
||||
|
||||
@validation.request_body_schema(schema.limits_create_request_body)
|
||||
@validation.response_body_schema(schema.limits_create_response_body)
|
||||
def post(self):
|
||||
"""Create new limits.
|
||||
|
||||
POST /v3/limits
|
||||
"""
|
||||
ENFORCER.enforce_call(action='identity:create_limits')
|
||||
limits_b = (flask.request.get_json(silent=True, force=True) or {}).get(
|
||||
'limits', {}
|
||||
)
|
||||
validation.lazy_validate(schema.limit_create, limits_b)
|
||||
limits = [
|
||||
self._assign_unique_id(self._normalize_dict(limit))
|
||||
for limit in limits_b
|
||||
@ -123,17 +121,51 @@ class LimitsResource(ks_flask.ResourceBase):
|
||||
refs.pop('links')
|
||||
return refs, http.client.CREATED
|
||||
|
||||
|
||||
class LimitResource(ks_flask.ResourceBase):
|
||||
collection_key = 'limits'
|
||||
member_key = 'limit'
|
||||
json_home_resource_status = json_home.Status.EXPERIMENTAL
|
||||
get_member_from_driver = PROVIDERS.deferred_provider_lookup(
|
||||
api='unified_limit_api', method='get_limit'
|
||||
)
|
||||
|
||||
@validation.request_body_schema(None)
|
||||
@validation.response_body_schema(schema.limit_show_response_body)
|
||||
def get(self, limit_id):
|
||||
"""Retrieve an existing limit.
|
||||
|
||||
GET /v3/limits/{limit_id}
|
||||
"""
|
||||
ENFORCER.enforce_call(
|
||||
action='identity:get_limit',
|
||||
build_target=_build_limit_enforcement_target,
|
||||
)
|
||||
ref = PROVIDERS.unified_limit_api.get_limit(limit_id)
|
||||
return self.wrap_member(ref)
|
||||
|
||||
@validation.request_body_schema(schema.limit_update_request_body)
|
||||
@validation.response_body_schema(schema.limit_show_response_body)
|
||||
def patch(self, limit_id):
|
||||
"""Update an existing limit.
|
||||
|
||||
PATCH /v3/limits/{limit_id}
|
||||
"""
|
||||
ENFORCER.enforce_call(action='identity:update_limit')
|
||||
limit = (flask.request.get_json(silent=True, force=True) or {}).get(
|
||||
'limit', {}
|
||||
)
|
||||
validation.lazy_validate(schema.limit_update, limit)
|
||||
self._require_matching_id(limit)
|
||||
ref = PROVIDERS.unified_limit_api.update_limit(limit_id, limit)
|
||||
return self.wrap_member(ref)
|
||||
|
||||
@validation.request_body_schema(None)
|
||||
@validation.response_body_schema(None)
|
||||
def delete(self, limit_id):
|
||||
"""Delete a limit.
|
||||
|
||||
DELETE /v3/limits/{limit_id}
|
||||
"""
|
||||
ENFORCER.enforce_call(action='identity:delete_limit')
|
||||
return (
|
||||
PROVIDERS.unified_limit_api.delete_limit(limit_id),
|
||||
@ -142,7 +174,13 @@ class LimitsResource(ks_flask.ResourceBase):
|
||||
|
||||
|
||||
class LimitModelResource(flask_restful.Resource):
|
||||
@validation.request_body_schema(None)
|
||||
@validation.response_body_schema(schema.limit_model_show_response_body)
|
||||
def get(self):
|
||||
"""Retrieve enforcement model.
|
||||
|
||||
GET /v3/limits/model
|
||||
"""
|
||||
ENFORCER.enforce_call(action='identity:get_limit_model')
|
||||
model = PROVIDERS.unified_limit_api.get_model()
|
||||
return {'model': model}
|
||||
@ -151,15 +189,32 @@ class LimitModelResource(flask_restful.Resource):
|
||||
class LimitsAPI(ks_flask.APIBase):
|
||||
_name = 'limits'
|
||||
_import_name = __name__
|
||||
resources = [LimitsResource]
|
||||
resource_mapping = [
|
||||
ks_flask.construct_resource_map(
|
||||
resource=LimitsResource,
|
||||
url='/limits',
|
||||
resource_kwargs={},
|
||||
rel="limits",
|
||||
path_vars=None,
|
||||
status=json_home.Status.EXPERIMENTAL,
|
||||
),
|
||||
ks_flask.construct_resource_map(
|
||||
resource=LimitResource,
|
||||
url='/limits/<string:limit_id>',
|
||||
resource_kwargs={},
|
||||
rel="limit",
|
||||
path_vars={
|
||||
'limit_id': json_home.build_v3_parameter_relation("limit_id")
|
||||
},
|
||||
status=json_home.Status.EXPERIMENTAL,
|
||||
),
|
||||
ks_flask.construct_resource_map(
|
||||
resource=LimitModelResource,
|
||||
resource_kwargs={},
|
||||
url='/limits/model',
|
||||
rel='limit_model',
|
||||
status=json_home.Status.EXPERIMENTAL,
|
||||
)
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
|
@ -21,6 +21,7 @@ name: dict[str, Any] = {
|
||||
"minLength": 1,
|
||||
"maxLength": 255,
|
||||
"pattern": r"[\S]+",
|
||||
"description": "The resource name.",
|
||||
}
|
||||
|
||||
boolean = {
|
||||
@ -28,11 +29,36 @@ boolean = {
|
||||
"enum": [True, "True", "TRUE", "true", False, "False", "FALSE", "false"],
|
||||
}
|
||||
|
||||
description: dict[str, Any] = {
|
||||
"type": "string",
|
||||
"description": "The resource description.",
|
||||
}
|
||||
|
||||
domain_id: dict[str, str] = {"type": "string"}
|
||||
domain_id: dict[str, Any] = {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 64,
|
||||
"pattern": r"^[a-zA-Z0-9-]+$",
|
||||
"description": "The ID of the domain.",
|
||||
}
|
||||
|
||||
project_id: dict[str, Any] = {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 64,
|
||||
"pattern": r"^[a-zA-Z0-9-]+$",
|
||||
"description": "The ID of the project.",
|
||||
}
|
||||
|
||||
parent_id: dict[str, str] = {"type": "string", "format": "uuid"}
|
||||
|
||||
region_id: dict[str, Any] = {
|
||||
"type": ["string", "null"],
|
||||
"minLength": 1,
|
||||
"maxLength": 255,
|
||||
"description": "The ID of the region.",
|
||||
}
|
||||
|
||||
_tag_name_property = {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
@ -41,7 +67,7 @@ _tag_name_property = {
|
||||
# guidelines as set by the API-WG, which matches anything that
|
||||
# does not contain a '/' or ','.
|
||||
# https://specs.openstack.org/openstack/api-wg/guidelines/tags.html
|
||||
"pattern": "^[^,/]*$",
|
||||
"pattern": r"^[^,/]*$",
|
||||
}
|
||||
|
||||
tags: dict[str, Any] = {
|
||||
|
@ -17,6 +17,7 @@ from typing import Any
|
||||
# Common schema for resource `link` attribute
|
||||
links: dict[str, Any] = {
|
||||
"type": "object",
|
||||
"description": "Links for the collection of resources.",
|
||||
"properties": {
|
||||
"next": {"type": ["string", "null"], "format": "uri"},
|
||||
"previous": {"type": ["string", "null"], "format": "uri"},
|
||||
@ -24,13 +25,16 @@ links: dict[str, Any] = {
|
||||
},
|
||||
"required": ["self"],
|
||||
"additionalProperties": False,
|
||||
"readOnly": True,
|
||||
}
|
||||
|
||||
# Resource `links` attribute schema
|
||||
resource_links: dict[str, Any] = {
|
||||
"type": "object",
|
||||
"description": "The link to the resource in question.",
|
||||
"properties": {"self": {"type": "string", "format": "uri"}},
|
||||
"additionalProperties": False,
|
||||
"readOnly": True,
|
||||
}
|
||||
|
||||
truncated: dict[str, Any] = {
|
||||
|
@ -12,11 +12,15 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from typing import Any
|
||||
|
||||
from keystone.api.validation import parameter_types
|
||||
from keystone.api.validation import response_types
|
||||
from keystone.common import validation
|
||||
from keystone.common.validation import parameter_types
|
||||
from keystone.common.validation import parameter_types as old_parameter_types
|
||||
|
||||
_registered_limit_properties = {
|
||||
'service_id': parameter_types.id_string,
|
||||
'service_id': old_parameter_types.id_string,
|
||||
'region_id': {'type': ['null', 'string']},
|
||||
'resource_name': {'type': 'string', 'minLength': 1, 'maxLength': 255},
|
||||
'default_limit': {
|
||||
@ -24,7 +28,7 @@ _registered_limit_properties = {
|
||||
'minimum': -1,
|
||||
'maximum': 0x7FFFFFFF, # The maximum value a signed INT may have
|
||||
},
|
||||
'description': validation.nullable(parameter_types.description),
|
||||
'description': validation.nullable(old_parameter_types.description),
|
||||
}
|
||||
|
||||
_registered_limit_create = {
|
||||
@ -45,71 +49,214 @@ registered_limit_update = {
|
||||
'additionalProperties': False,
|
||||
}
|
||||
|
||||
_project_limit_create_properties = {
|
||||
'project_id': parameter_types.id_string,
|
||||
'service_id': parameter_types.id_string,
|
||||
'region_id': {'type': 'string'},
|
||||
'resource_name': {'type': 'string', 'minLength': 1, 'maxLength': 255},
|
||||
'resource_limit': {
|
||||
'type': 'integer',
|
||||
'minimum': -1,
|
||||
'maximum': 0x7FFFFFFF, # The maximum value a signed INT may have
|
||||
},
|
||||
'description': validation.nullable(parameter_types.description),
|
||||
_limit_integer_type = {
|
||||
"type": "integer",
|
||||
"minimum": -1,
|
||||
"maximum": 0x7FFFFFFF, # The maximum value a signed INT may have
|
||||
}
|
||||
|
||||
_domain_limit_create_properties = {
|
||||
'domain_id': parameter_types.id_string,
|
||||
'service_id': parameter_types.id_string,
|
||||
'region_id': {'type': 'string'},
|
||||
'resource_name': {'type': 'string', 'minLength': 1, 'maxLength': 255},
|
||||
'resource_limit': {
|
||||
'type': 'integer',
|
||||
'minimum': -1,
|
||||
'maximum': 0x7FFFFFFF, # The maximum value a signed INT may have
|
||||
# Individual properties of the `Limit`
|
||||
_limit_properties = {
|
||||
"resource_name": parameter_types.name,
|
||||
"region_id": {
|
||||
"description": (
|
||||
"The ID of the region that contains the service endpoint."
|
||||
),
|
||||
**parameter_types.region_id,
|
||||
},
|
||||
'description': validation.nullable(parameter_types.description),
|
||||
"service_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "The UUID of the service to which the limit belongs.",
|
||||
},
|
||||
"resource_limit": {
|
||||
"description": "The override limit.",
|
||||
**_limit_integer_type,
|
||||
},
|
||||
"description": validation.nullable(parameter_types.description),
|
||||
}
|
||||
|
||||
# Common schema of `Limit` resource
|
||||
limit_schema: dict[str, Any] = {
|
||||
"type": "object",
|
||||
"description": "A limit object.",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "The limit ID.",
|
||||
"readOnly": True,
|
||||
},
|
||||
"project_id": validation.nullable(parameter_types.project_id),
|
||||
"domain_id": validation.nullable(parameter_types.domain_id),
|
||||
"links": response_types.resource_links,
|
||||
**_limit_properties,
|
||||
},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
# Response body of API operations returning a single limit
|
||||
# `GET /limits/{limit_id}` and `PATCH /limits/{limit_id}`
|
||||
limit_show_response_body: dict[str, Any] = {
|
||||
"type": "object",
|
||||
"properties": {"limit": limit_schema},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
# Query parameters of the `GET /limits` API operation
|
||||
# returning a list of limits
|
||||
limits_index_request_query: dict[str, Any] = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"service_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Filters the response by a service ID.",
|
||||
},
|
||||
"region_id": {
|
||||
"description": "Filters the response by a region ID.",
|
||||
**parameter_types.region_id,
|
||||
},
|
||||
"resource_name": {
|
||||
"description": (
|
||||
"Filters the response by a specified resource name."
|
||||
),
|
||||
**parameter_types.name,
|
||||
},
|
||||
"project_id": {
|
||||
"description": "Filters the response by a project ID.",
|
||||
**parameter_types.project_id,
|
||||
},
|
||||
"domain_id": {
|
||||
"description": "Filters the response by a domain ID.",
|
||||
**parameter_types.domain_id,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
# Response body of the `GET /limits` API operation
|
||||
# returning a list of limits
|
||||
limits_index_response_body: dict[str, Any] = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"links": response_types.links,
|
||||
"limits": {
|
||||
"type": "array",
|
||||
"items": limit_schema,
|
||||
"description": "A list of limit objects.",
|
||||
},
|
||||
"truncated": response_types.truncated,
|
||||
},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
# Response body of the `GET /limits/model` API operation
|
||||
# returning an enforcement model
|
||||
limit_model_show_response_body: dict[str, Any] = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"model": {
|
||||
"type": "object",
|
||||
"description": (
|
||||
"A model object describing the configured enforcement model "
|
||||
"used by the deployment."
|
||||
),
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": (
|
||||
"A short description of the enforcement model used."
|
||||
),
|
||||
},
|
||||
"name": {
|
||||
**parameter_types.name,
|
||||
"description": "The name of the enforcement model.",
|
||||
},
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
# Individual properties for creating a new limit
|
||||
_limit_create = {
|
||||
'type': 'object',
|
||||
'oneOf': [
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project_id": validation.nullable(parameter_types.project_id),
|
||||
"domain_id": validation.nullable(parameter_types.domain_id),
|
||||
**_limit_properties,
|
||||
},
|
||||
"required": ["service_id", "resource_name", "resource_limit"],
|
||||
"oneOf": [
|
||||
{
|
||||
'properties': _project_limit_create_properties,
|
||||
'required': [
|
||||
'project_id',
|
||||
'service_id',
|
||||
'resource_name',
|
||||
'resource_limit',
|
||||
],
|
||||
'additionalProperties': False,
|
||||
"required": [
|
||||
"service_id",
|
||||
"resource_name",
|
||||
"resource_limit",
|
||||
"domain_id",
|
||||
]
|
||||
},
|
||||
{
|
||||
'properties': _domain_limit_create_properties,
|
||||
'required': [
|
||||
'domain_id',
|
||||
'service_id',
|
||||
'resource_name',
|
||||
'resource_limit',
|
||||
],
|
||||
'additionalProperties': False,
|
||||
"required": [
|
||||
"service_id",
|
||||
"resource_name",
|
||||
"resource_limit",
|
||||
"project_id",
|
||||
]
|
||||
},
|
||||
],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
limit_create = {'type': 'array', 'items': _limit_create, 'minItems': 1}
|
||||
|
||||
_limit_update_properties = {
|
||||
'resource_limit': {
|
||||
'type': 'integer',
|
||||
'minimum': -1,
|
||||
'maximum': 0x7FFFFFFF, # The maximum value a signed INT may have
|
||||
# Request body of the `POST /limits` API operation
|
||||
limits_create_request_body = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"limits": {
|
||||
"type": "array",
|
||||
"items": _limit_create,
|
||||
"minItems": 1,
|
||||
"description": "A list of limit objects.",
|
||||
}
|
||||
},
|
||||
'description': validation.nullable(parameter_types.description),
|
||||
"required": ["limits"],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
limit_update = {
|
||||
'type': 'object',
|
||||
'properties': _limit_update_properties,
|
||||
'additionalProperties': False,
|
||||
# Response body of the `POST /limits` API operation
|
||||
limits_create_response_body: dict[str, Any] = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"limits": {
|
||||
"type": "array",
|
||||
"items": limit_schema,
|
||||
"description": "A list of limit objects.",
|
||||
}
|
||||
},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
# Request body of the `PATCH /limits/{limit_id}` operation
|
||||
limit_update_request_body = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"limit": {
|
||||
"type": "object",
|
||||
"description": "Updates to make to a limit.",
|
||||
"properties": {
|
||||
"resource_limit": {
|
||||
"description": "The override limit.",
|
||||
**_limit_integer_type,
|
||||
},
|
||||
"description": validation.nullable(
|
||||
parameter_types.description
|
||||
),
|
||||
},
|
||||
"additionalProperties": False,
|
||||
}
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["limit"],
|
||||
}
|
||||
|
@ -3060,8 +3060,8 @@ class LimitValidationTestCase(unit.BaseTestCase):
|
||||
|
||||
create_registered_limits = limit_schema.registered_limit_create
|
||||
update_registered_limits = limit_schema.registered_limit_update
|
||||
create_limits = limit_schema.limit_create
|
||||
update_limits = limit_schema.limit_update
|
||||
create_limits = limit_schema.limits_create_request_body
|
||||
update_limits = limit_schema.limit_update_request_body
|
||||
|
||||
self.create_registered_limits_validator = validators.SchemaValidator(
|
||||
create_registered_limits
|
||||
@ -3222,55 +3222,60 @@ class LimitValidationTestCase(unit.BaseTestCase):
|
||||
)
|
||||
|
||||
def test_validate_project_limit_create_request_succeeds(self):
|
||||
request_to_validate = [
|
||||
{
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
'description': 'test description',
|
||||
}
|
||||
]
|
||||
request_to_validate = {
|
||||
"limits": [
|
||||
{
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
'description': 'test description',
|
||||
}
|
||||
]
|
||||
}
|
||||
self.create_limits_validator.validate(request_to_validate)
|
||||
|
||||
def test_validate_domain_limit_create_request_succeeds(self):
|
||||
request_to_validate = [
|
||||
{
|
||||
'domain_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
'description': 'test description',
|
||||
}
|
||||
]
|
||||
request_to_validate = {
|
||||
"limits": [
|
||||
{
|
||||
'domain_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
'description': 'test description',
|
||||
}
|
||||
]
|
||||
}
|
||||
self.create_limits_validator.validate(request_to_validate)
|
||||
|
||||
def test_validate_limit_create_request_without_optional(self):
|
||||
request_to_validate = [
|
||||
{
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
}
|
||||
]
|
||||
request_to_validate = {
|
||||
"limits": [
|
||||
{
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
}
|
||||
]
|
||||
}
|
||||
self.create_limits_validator.validate(request_to_validate)
|
||||
|
||||
def test_validate_limit_update_request_succeeds(self):
|
||||
request_to_validate = {
|
||||
'resource_limit': 10,
|
||||
'description': 'test description',
|
||||
"limit": {'resource_limit': 10, 'description': 'test description'}
|
||||
}
|
||||
self.update_limits_validator.validate(request_to_validate)
|
||||
|
||||
def test_validate_limit_update_request_without_optional(self):
|
||||
request_to_validate = {'resource_limit': 10}
|
||||
request_to_validate = {"limit": {'resource_limit': 10}}
|
||||
self.update_limits_validator.validate(request_to_validate)
|
||||
|
||||
def test_validate_limit_request_with_no_parameters(self):
|
||||
request_to_validate = []
|
||||
request_to_validate = {"limits": []}
|
||||
# At least one property should be given.
|
||||
self.assertRaises(
|
||||
exception.SchemaValidationError,
|
||||
@ -3292,17 +3297,19 @@ class LimitValidationTestCase(unit.BaseTestCase):
|
||||
{'description': 123},
|
||||
]
|
||||
for invalid_attribute in _INVALID_FORMATS:
|
||||
request_to_validate = [
|
||||
{
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
'description': 'test description',
|
||||
}
|
||||
]
|
||||
request_to_validate[0].update(invalid_attribute)
|
||||
request_to_validate = {
|
||||
"limits": [
|
||||
{
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
'description': 'test description',
|
||||
}
|
||||
]
|
||||
}
|
||||
request_to_validate['limits'][0].update(invalid_attribute)
|
||||
|
||||
self.assertRaises(
|
||||
exception.SchemaValidationError,
|
||||
@ -3311,16 +3318,18 @@ class LimitValidationTestCase(unit.BaseTestCase):
|
||||
)
|
||||
|
||||
def test_validate_limit_create_request_with_invalid_domain(self):
|
||||
request_to_validate = [
|
||||
{
|
||||
'domain_id': 'fake_id',
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
'description': 'test description',
|
||||
}
|
||||
]
|
||||
request_to_validate = {
|
||||
"limits": [
|
||||
{
|
||||
'domain_id': 'fake_id',
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
'description': 'test description',
|
||||
}
|
||||
]
|
||||
}
|
||||
self.assertRaises(
|
||||
exception.SchemaValidationError,
|
||||
self.create_limits_validator.validate,
|
||||
@ -3338,8 +3347,8 @@ class LimitValidationTestCase(unit.BaseTestCase):
|
||||
{'description': 123},
|
||||
]
|
||||
for invalid_desc in _INVALID_FORMATS:
|
||||
request_to_validate = [
|
||||
{
|
||||
request_to_validate = {
|
||||
"limit": {
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
@ -3347,8 +3356,8 @@ class LimitValidationTestCase(unit.BaseTestCase):
|
||||
'resource_limit': 10,
|
||||
'description': 'test description',
|
||||
}
|
||||
]
|
||||
request_to_validate[0].update(invalid_desc)
|
||||
}
|
||||
request_to_validate['limit'].update(invalid_desc)
|
||||
|
||||
self.assertRaises(
|
||||
exception.SchemaValidationError,
|
||||
@ -3357,15 +3366,17 @@ class LimitValidationTestCase(unit.BaseTestCase):
|
||||
)
|
||||
|
||||
def test_validate_limit_create_request_with_addition_input_fails(self):
|
||||
request_to_validate = [
|
||||
{
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
'more_key': 'more_value',
|
||||
}
|
||||
]
|
||||
request_to_validate = {
|
||||
"limits": [
|
||||
{
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
'more_key': 'more_value',
|
||||
}
|
||||
]
|
||||
}
|
||||
self.assertRaises(
|
||||
exception.SchemaValidationError,
|
||||
self.create_limits_validator.validate,
|
||||
@ -3374,9 +3385,11 @@ class LimitValidationTestCase(unit.BaseTestCase):
|
||||
|
||||
def test_validate_limit_update_request_with_addition_input_fails(self):
|
||||
request_to_validate = {
|
||||
'id': uuid.uuid4().hex,
|
||||
'resource_limit': 10,
|
||||
'more_key': 'more_value',
|
||||
"limit": {
|
||||
'id': uuid.uuid4().hex,
|
||||
'resource_limit': 10,
|
||||
'more_key': 'more_value',
|
||||
}
|
||||
}
|
||||
self.assertRaises(
|
||||
exception.SchemaValidationError,
|
||||
@ -3393,16 +3406,18 @@ class LimitValidationTestCase(unit.BaseTestCase):
|
||||
'resource_name',
|
||||
'resource_limit',
|
||||
]:
|
||||
request_to_validate = [
|
||||
{
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
}
|
||||
]
|
||||
request_to_validate[0].pop(key)
|
||||
request_to_validate = {
|
||||
"limits": [
|
||||
{
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
}
|
||||
]
|
||||
}
|
||||
request_to_validate['limits'][0].pop(key)
|
||||
self.assertRaises(
|
||||
exception.SchemaValidationError,
|
||||
self.create_limits_validator.validate,
|
||||
@ -3416,16 +3431,18 @@ class LimitValidationTestCase(unit.BaseTestCase):
|
||||
'resource_name',
|
||||
'resource_limit',
|
||||
]:
|
||||
request_to_validate = [
|
||||
{
|
||||
'domain_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
}
|
||||
]
|
||||
request_to_validate[0].pop(key)
|
||||
request_to_validate = {
|
||||
"limits": [
|
||||
{
|
||||
'domain_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
}
|
||||
]
|
||||
}
|
||||
request_to_validate['limits'][0].pop(key)
|
||||
self.assertRaises(
|
||||
exception.SchemaValidationError,
|
||||
self.create_limits_validator.validate,
|
||||
@ -3433,17 +3450,19 @@ class LimitValidationTestCase(unit.BaseTestCase):
|
||||
)
|
||||
|
||||
def test_validate_limit_create_request_with_both_project_and_domain(self):
|
||||
request_to_validate = [
|
||||
{
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'domain_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
'description': 'test description',
|
||||
}
|
||||
]
|
||||
request_to_validate = {
|
||||
"limits": [
|
||||
{
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'domain_id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
'region_id': 'RegionOne',
|
||||
'resource_name': 'volume',
|
||||
'resource_limit': 10,
|
||||
'description': 'test description',
|
||||
}
|
||||
]
|
||||
}
|
||||
self.assertRaises(
|
||||
exception.SchemaValidationError,
|
||||
self.create_limits_validator.validate,
|
||||
|
Loading…
x
Reference in New Issue
Block a user