Validation of id values for volumes_roles_mapping

Any string can be set as 'id' in 'volumes_roles_mapping' and validation of
  node's role on PUT-request passes without an error.

* Add an additional validation step into 'RoleValidator.validate_update'.
* Add unit tests for node roles validation.

Change-Id: I2f199f742931c582eb6ea35a3030d470724864c0
Closes-Bug: #1467097
This commit is contained in:
Ivan Kliuk 2015-06-20 17:55:19 +03:00
parent a69188a334
commit 4e5e889f82
4 changed files with 68 additions and 8 deletions

View File

@ -52,8 +52,9 @@ class RoleHandler(base.SingleHandler):
* 200 (OK)
* 404 (no such object found)
"""
data = self.checked_data()
release = self.get_object_or_404(objects.Release, release_id)
data = self.checked_data(
self.validator.validate_update, instance=release)
objects.Release.update_role(release, data)
return RoleSerializer.serialize_from_release(release, role_name)

View File

@ -46,7 +46,21 @@ class RoleValidator(BasicValidator):
@classmethod
def validate_update(cls, data, instance):
return cls.validate(data, instance=instance)
parsed = cls.validate(data, instance=instance)
allowed_ids = [m['id'] for m in instance.volumes_metadata['volumes']]
missing_volume_ids = []
for volume in parsed['volumes_roles_mapping']:
if volume['id'] not in allowed_ids:
missing_volume_ids.append(volume['id'])
if missing_volume_ids:
raise errors.InvalidData(
"Wrong data in volumes_roles_mapping. Volumes with ids {0} are"
" not in the list of allowed volumes {1}".format(
missing_volume_ids, allowed_ids))
return parsed
@classmethod
def validate_create(cls, data):

View File

@ -81,6 +81,25 @@ class TestRoleApi(BaseRoleTest):
self.release.id, self.role_data, expect_errors=True)
self.assertEqual(resp.status_code, 400)
def test_create_role_w_invalid_volumes_allocate_size(self):
self.role_data['volumes_roles_mapping'][0]['allocate_size'] = \
'some_string'
resp = self.env.create_role(
self.release.id, self.role_data, expect_errors=True)
self.assertEqual(400, resp.status_code)
self.assertIn('Failed validating', resp.body)
self.assertIn('volumes_roles_mapping', resp.body)
def test_update_role_w_invalid_volumes_id(self):
self.role_data['volumes_roles_mapping'][0]['id'] = 'some_string'
resp = self.env.update_role(
self.release.id,
self.role_data['name'],
self.role_data,
expect_errors=True)
self.assertEqual(400, resp.status_code)
self.assertIn('Wrong data in volumes_roles_mapping', resp.body)
def test_delete_role(self):
self.env.create_role(self.release.id, self.role_data)

View File

@ -12,18 +12,44 @@
# License for the specific language governing permissions and limitations
# under the License.
from nailgun.api.v1.validators.json_schema import role
from nailgun.api.v1.validators.role import RoleValidator
from nailgun.errors import errors
from nailgun.test.base import BaseUnitTest
class TestNodeAssignmentValidator(BaseUnitTest):
class TestRoleVolumeAllocationsValidationBySchema(BaseUnitTest):
invalid_data = [1, 'some_string', dict(), list()]
ids = ['os', 'image', 'vm', 'cinder', 'ceph', 'cephjournal', 'mongo']
allocation_sizes = ['all', 'min', 'full-disk']
def test_allocate_volumes_validator(self):
volumes = [{'allocate_size': 'all', 'id': 'os'}]
RoleValidator.validate_schema(volumes, role.VOLUME_ALLOCATIONS)
def assertInvalidData(self, volumes):
self.assertRaises(
errors.InvalidData, RoleValidator.validate_schema,
volumes, role.VOLUME_ALLOCATIONS)
def test_meta_validator(self):
def test_properties_allocate_size(self):
for size in self.allocation_sizes:
volumes = [{'allocate_size': size, 'id': self.ids[0]}]
RoleValidator.validate_schema(volumes, role.VOLUME_ALLOCATIONS)
for size in self.invalid_data:
volumes = [{'allocate_size': size, 'id': self.ids[0]}]
self.assertInvalidData(volumes)
def test_properties_id(self):
for i in self.ids:
volumes = [{'allocate_size': self.allocation_sizes[0], 'id': i}]
RoleValidator.validate_schema(volumes, role.VOLUME_ALLOCATIONS)
def test_full_restriction(self):
full_restriction = {'condition': "some_string"}
RoleValidator.validate_schema(full_restriction, role.FULL_RESTRICTION)
def test_restrictions(self):
restrictions = ["conidtion", {'condition': "some condition"}]
RoleValidator.validate_schema(restrictions, role.RESTRICTIONS)
def test_meta_info(self):
meta = {'name': 'Some Name', 'description': 'Some Description'}
RoleValidator.validate_schema(meta, role.ROLE_META_INFO)