Add policy_validate function to engine
This function will do a deep check to policy properties. Change-Id: Ie633a732ad69792ad6bd1516a250a071c71b4eef
This commit is contained in:
parent
c853a4e8cb
commit
c167430eaf
|
@ -566,6 +566,44 @@ class EngineService(service.Service):
|
|||
project_safe=project_safe)
|
||||
return [p.to_dict() for p in policies]
|
||||
|
||||
@request_context
|
||||
def _validate_policy(self, context, spec, name=None, validate_props=False):
|
||||
"""Validate a policy.
|
||||
|
||||
:param context: An instance of the request context.
|
||||
:param spec: A dictionary containing the spec for the policy.
|
||||
:param name: The name for the policy to be created.
|
||||
:param validate_props: Whether to validate the value of property.
|
||||
:return: Validated policy object.
|
||||
"""
|
||||
|
||||
type_name, version = schema.get_spec_version(spec)
|
||||
type_str = "-".join([type_name, version])
|
||||
try:
|
||||
plugin = environment.global_env().get_policy(type_str)
|
||||
except exception.PolicyTypeNotFound:
|
||||
msg = _("The specified policy type (%(name)s) is not found."
|
||||
) % {"name": type_str}
|
||||
raise exception.SpecValidationFailed(message=msg)
|
||||
|
||||
kwargs = {
|
||||
'user': context.user,
|
||||
'project': context.project,
|
||||
'domain': context.domain,
|
||||
}
|
||||
if name is None:
|
||||
name = 'validated_policy'
|
||||
policy = plugin(name, spec, **kwargs)
|
||||
|
||||
try:
|
||||
policy.validate(validate_props=validate_props)
|
||||
except exception.InvalidSpec as ex:
|
||||
msg = six.text_type(ex)
|
||||
LOG.error(_LE("Failed in validating policy: %s"), msg)
|
||||
raise exception.SpecValidationFailed(message=msg)
|
||||
|
||||
return policy
|
||||
|
||||
@request_context
|
||||
def policy_create(self, context, name, spec):
|
||||
"""Create a policy with the given name and spec.
|
||||
|
@ -582,31 +620,10 @@ class EngineService(service.Service):
|
|||
) % {"name": name}
|
||||
raise exception.BadRequest(msg=msg)
|
||||
|
||||
type_name, version = schema.get_spec_version(spec)
|
||||
type_str = "-".join([type_name, version])
|
||||
try:
|
||||
plugin = environment.global_env().get_policy(type_str)
|
||||
except exception.PolicyTypeNotFound:
|
||||
msg = _("The specified policy type (%(name)s) is not found."
|
||||
) % {"name": type_str}
|
||||
raise exception.BadRequest(msg=msg)
|
||||
policy = self._validate_policy(context, spec, name=name)
|
||||
|
||||
LOG.info(_LI("Creating policy %(type)s '%(name)s'"),
|
||||
{'type': type_str, 'name': name})
|
||||
|
||||
kwargs = {
|
||||
'user': context.user,
|
||||
'project': context.project,
|
||||
'domain': context.domain,
|
||||
}
|
||||
policy = plugin(name, spec, **kwargs)
|
||||
|
||||
try:
|
||||
policy.validate()
|
||||
except exception.InvalidSpec as ex:
|
||||
msg = six.text_type(ex)
|
||||
LOG.error(_LE("Failed in creating policy: %s"), msg)
|
||||
raise exception.BadRequest(msg=msg)
|
||||
{'type': policy.type, 'name': policy.name})
|
||||
|
||||
policy.store(context)
|
||||
LOG.info(_LI("Policy '%(name)s' is created: %(id)s."),
|
||||
|
@ -672,6 +689,19 @@ class EngineService(service.Service):
|
|||
|
||||
LOG.info(_LI("Policy '%s' is deleted."), identity)
|
||||
|
||||
@request_context
|
||||
def policy_validate(self, context, spec):
|
||||
"""Validate a policy with the given properties.
|
||||
|
||||
:param context: An instance of the request context.
|
||||
:param spec: A dictionary containing the spec for the policy.
|
||||
:return: A dictionary containing the details of the policy object
|
||||
validated.
|
||||
"""
|
||||
policy = self._validate_policy(context, spec, validate_props=True)
|
||||
|
||||
return policy.to_dict()
|
||||
|
||||
def cluster_find(self, context, identity, project_safe=True):
|
||||
"""Find a cluster with the given identity.
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ class Policy(object):
|
|||
|
||||
return self.id
|
||||
|
||||
def validate(self):
|
||||
def validate(self, validate_props=False):
|
||||
'''Validate the schema and the data provided.'''
|
||||
self.spec_data.validate()
|
||||
self.properties.validate()
|
||||
|
|
|
@ -268,11 +268,13 @@ class LoadBalancingPolicy(base.Policy):
|
|||
self.validate()
|
||||
self.lb = None
|
||||
|
||||
def validate(self):
|
||||
def validate(self, validate_props=False):
|
||||
super(LoadBalancingPolicy, self).validate()
|
||||
|
||||
# validate subnet's exists
|
||||
# subnet = self.nc.subnet_get(vip[self.VIP_SUBNET])
|
||||
# TODO(elynn): Check if subnet exists
|
||||
if validate_props:
|
||||
pass
|
||||
# subnet = self.nc.subnet_get(vip[self.VIP_SUBNET])
|
||||
|
||||
def attach(self, cluster):
|
||||
"""Routine to be invoked when policy is to be attached to a cluster.
|
||||
|
|
|
@ -247,8 +247,8 @@ class PolicyTest(base.SenlinTestCase):
|
|||
self.eng.policy_create,
|
||||
self.ctx, 'p-2', spec)
|
||||
|
||||
self.assertEqual(exc.BadRequest, ex.exc_info[0])
|
||||
self.assertEqual("The request is malformed: The specified policy "
|
||||
self.assertEqual(exc.SpecValidationFailed, ex.exc_info[0])
|
||||
self.assertEqual("The specified policy "
|
||||
"type (FakePolicy-1.0) is not found.",
|
||||
six.text_type(ex.exc_info[1]))
|
||||
|
||||
|
@ -275,8 +275,46 @@ class PolicyTest(base.SenlinTestCase):
|
|||
ex = self.assertRaises(rpc.ExpectedException,
|
||||
self.eng.policy_create,
|
||||
self.ctx, 'p-2', self.spec)
|
||||
self.assertEqual(exc.BadRequest, ex.exc_info[0])
|
||||
self.assertEqual('The request is malformed: BOOM',
|
||||
self.assertEqual(exc.SpecValidationFailed, ex.exc_info[0])
|
||||
self.assertEqual('BOOM',
|
||||
six.text_type(ex.exc_info[1]))
|
||||
|
||||
def test_policy_validate_pass(self):
|
||||
self._setup_fakes()
|
||||
|
||||
expected_resp = {
|
||||
'created_at': None,
|
||||
'domain': '',
|
||||
'id': None,
|
||||
'data': {},
|
||||
'name': 'validated_policy',
|
||||
'project': 'policy_test_project',
|
||||
'type': 'TestPolicy-1.0',
|
||||
'updated_at': None,
|
||||
'user': 'test_user_id',
|
||||
'spec': {
|
||||
'type': 'TestPolicy',
|
||||
'version': '1.0',
|
||||
'properties': {
|
||||
'KEY2': 6
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resp = self.eng.policy_validate(self.ctx, self.spec)
|
||||
self.assertEqual(expected_resp, resp)
|
||||
|
||||
def test_policy_validate_failed(self):
|
||||
self._setup_fakes()
|
||||
|
||||
mock_validate = self.patchobject(fakes.TestPolicy, 'validate')
|
||||
mock_validate.side_effect = exc.SpecValidationFailed(message='BOOM')
|
||||
|
||||
ex = self.assertRaises(rpc.ExpectedException,
|
||||
self.eng.policy_validate,
|
||||
self.ctx, self.spec)
|
||||
self.assertEqual(exc.SpecValidationFailed, ex.exc_info[0])
|
||||
self.assertEqual('BOOM',
|
||||
six.text_type(ex.exc_info[1]))
|
||||
|
||||
@mock.patch.object(pb.Policy, 'load')
|
||||
|
|
Loading…
Reference in New Issue