Add JSON schema validation for project tags
This change adds json schema for project tags validation, with the limits for number of characters per tag as well as the limit for the number of tags a project can have per update. Co-Authored-By: Jaewoo Park <jp655p@att.com> Co-Authored-By: Nicolas <nh202b@att.com> Change-Id: I5f8e4a53089b9fcc38084bb958d09f63ccc59d2a Partially-Implements: bp project-tags
This commit is contained in:
parent
7c91276290
commit
5329071174
@ -20,6 +20,25 @@ _name_properties = {
|
||||
'pattern': '[\S]+'
|
||||
}
|
||||
|
||||
_project_tag_name_properties = {
|
||||
'type': 'string',
|
||||
'minLength': 1,
|
||||
'maxLength': 255,
|
||||
# NOTE(gagehugo) This pattern is for tags which follows the
|
||||
# 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': '^[^,/]*$'
|
||||
}
|
||||
|
||||
_project_tags_list_properties = {
|
||||
'type': 'array',
|
||||
'items': _project_tag_name_properties,
|
||||
'required': [],
|
||||
'maxItems': 80,
|
||||
'uniqueItems': True
|
||||
}
|
||||
|
||||
_project_properties = {
|
||||
'description': validation.nullable(parameter_types.description),
|
||||
# NOTE(htruta): domain_id is nullable for projects acting as a domain.
|
||||
@ -27,9 +46,16 @@ _project_properties = {
|
||||
'enabled': parameter_types.boolean,
|
||||
'is_domain': parameter_types.boolean,
|
||||
'parent_id': validation.nullable(parameter_types.id_string),
|
||||
'name': _name_properties
|
||||
'name': _name_properties,
|
||||
'tags': _project_tags_list_properties
|
||||
}
|
||||
|
||||
# This is for updating a single project tag via the URL
|
||||
project_tag_create = _project_tag_name_properties
|
||||
|
||||
# This is for updaing a project with a list of tags
|
||||
project_tags_update = _project_tags_list_properties
|
||||
|
||||
project_create = {
|
||||
'type': 'object',
|
||||
'properties': _project_properties,
|
||||
@ -51,7 +77,8 @@ project_update = {
|
||||
_domain_properties = {
|
||||
'description': validation.nullable(parameter_types.description),
|
||||
'enabled': parameter_types.boolean,
|
||||
'name': _name_properties
|
||||
'name': _name_properties,
|
||||
'tags': project_tags_update
|
||||
}
|
||||
|
||||
domain_create = {
|
||||
|
@ -381,6 +381,37 @@ class ProjectValidationTestCase(unit.BaseTestCase):
|
||||
self.create_project_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_project_create_with_tags(self):
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': ['foo', 'bar']}
|
||||
self.create_project_validator.validate(request_to_validate)
|
||||
|
||||
def test_validate_project_create_with_tags_invalid_char(self):
|
||||
invalid_chars = [',', '/', ',foo', 'foo/bar']
|
||||
for char in invalid_chars:
|
||||
tag = uuid.uuid4().hex + char
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': ['foo', tag]}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.create_project_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_project_create_with_tag_name_too_long(self):
|
||||
invalid_name = 'a' * 256
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': ['foo', invalid_name]}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.create_project_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_project_create_with_too_many_tags(self):
|
||||
tags = [uuid.uuid4().hex for _ in range(81)]
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': tags}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.create_project_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_project_request_with_valid_parent_id(self):
|
||||
"""Test that we validate `parent_id` in create project requests."""
|
||||
# parent_id is nullable
|
||||
@ -432,6 +463,37 @@ class ProjectValidationTestCase(unit.BaseTestCase):
|
||||
self.update_project_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_project_update_with_tags(self):
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': ['foo', 'bar']}
|
||||
self.update_project_validator.validate(request_to_validate)
|
||||
|
||||
def test_validate_project_update_with_tags_invalid_char(self):
|
||||
invalid_chars = [',', '/']
|
||||
for char in invalid_chars:
|
||||
tag = uuid.uuid4().hex + char
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': ['foo', tag]}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.update_project_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_project_update_with_tag_name_too_long(self):
|
||||
invalid_name = 'a' * 256
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': ['foo', invalid_name]}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.update_project_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_project_update_with_too_many_tags(self):
|
||||
tags = [uuid.uuid4().hex for _ in range(81)]
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': tags}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.update_project_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_project_create_request_with_valid_domain_id(self):
|
||||
"""Test that we validate `domain_id` in create project requests."""
|
||||
# domain_id is nullable
|
||||
@ -521,6 +583,37 @@ class DomainValidationTestCase(unit.BaseTestCase):
|
||||
self.create_domain_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_domain_create_with_tags(self):
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': ['foo', 'bar']}
|
||||
self.create_domain_validator.validate(request_to_validate)
|
||||
|
||||
def test_validate_domain_create_with_tags_invalid_char(self):
|
||||
invalid_chars = [',', '/']
|
||||
for char in invalid_chars:
|
||||
tag = uuid.uuid4().hex + char
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': ['foo', tag]}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.create_domain_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_domain_create_with_tag_name_too_long(self):
|
||||
invalid_name = 'a' * 256
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': ['foo', invalid_name]}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.create_domain_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_domain_create_with_too_many_tags(self):
|
||||
tags = [uuid.uuid4().hex for _ in range(81)]
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': tags}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.create_domain_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_domain_update_request(self):
|
||||
"""Test that we validate a domain update request."""
|
||||
request_to_validate = {'domain_id': uuid.uuid4().hex}
|
||||
@ -549,6 +642,37 @@ class DomainValidationTestCase(unit.BaseTestCase):
|
||||
self.update_domain_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_domain_update_with_tags(self):
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': ['foo', 'bar']}
|
||||
self.update_domain_validator.validate(request_to_validate)
|
||||
|
||||
def test_validate_domain_update_with_tags_invalid_char(self):
|
||||
invalid_chars = [',', '/']
|
||||
for char in invalid_chars:
|
||||
tag = uuid.uuid4().hex + char
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': ['foo', tag]}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.update_domain_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_domain_update_with_tag_name_too_long(self):
|
||||
invalid_name = 'a' * 256
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': ['foo', invalid_name]}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.update_domain_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_domain_update_with_too_many_tags(self):
|
||||
tags = [uuid.uuid4().hex for _ in range(81)]
|
||||
request_to_validate = {'name': uuid.uuid4().hex,
|
||||
'tags': tags}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.update_domain_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
|
||||
class RoleValidationTestCase(unit.BaseTestCase):
|
||||
"""Test for V3 Role API validation."""
|
||||
|
Loading…
Reference in New Issue
Block a user