Add validation for required property of policies

Tosca-parser validates the required parameter for node_template but does
not validate the required property of the policy like node_template.

This patch fixes the issue for validation required property of policy.

Change-Id: I137addfa0d7d46e6821573f7770214f5c1754172
Closes-Bug: 1903233
This commit is contained in:
Ayumu Ueha 2020-11-18 18:27:15 +09:00
parent b598d9cfe4
commit 00d3a394d5
7 changed files with 174 additions and 1 deletions

View File

@ -89,3 +89,8 @@ class Policy(EntityTemplate):
ExceptionCollector.appendException(
UnknownFieldError(what='Policy "%s"' % self.name,
field=key))
def validate(self):
self._validate_properties(self.entity_tpl, self.type_definition)
for prop in self.get_properties_objects():
prop.validate()

View File

@ -0,0 +1,13 @@
tosca_definitions_version: tosca_simple_yaml_1_1
policy_types:
tosca.policies.somePolicy:
derived_from: tosca.policies.Root
properties:
name:
type: string
required: true
value:
type: integer
required: false
default: 100

View File

@ -0,0 +1,102 @@
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
description: sample-tosca-vnfd-scaling
imports:
- tacker_defs.yaml
- tacker_nfv_defs.yaml
metadata:
template_name: sample-tosca-vnfd-scaling
topology_template:
node_templates:
VDU1:
type: tosca.nodes.nfv.VDU.Tacker
properties:
image: cirros-0.3.4-x86_64-uec
mgmt_driver: noop
availability_zone: nova
flavor: m1.tiny
CP1:
type: tosca.nodes.nfv.CP.Tacker
properties:
management: true
order: 0
anti_spoofing_protection: false
requirements:
- virtualLink:
node: VL1
- virtualBinding:
node: VDU1
VDU2:
type: tosca.nodes.nfv.VDU.Tacker
properties:
image: cirros-0.3.4-x86_64-uec
mgmt_driver: noop
availability_zone: nova
flavor: m1.tiny
CP2:
type: tosca.nodes.nfv.CP.Tacker
properties:
management: true
order: 0
anti_spoofing_protection: false
requirements:
- virtualLink:
node: VL1
- virtualBinding:
node: VDU2
VL1:
type: tosca.nodes.nfv.VL
properties:
network_name: net_mgmt
vendor: Tacker
policies:
- SP1:
type: tosca.policies.tacker.Scaling
targets: [VDU1]
properties:
increment: 1
cooldown: 120
min_instances: 1
max_instances: 2
default_instances: 1
targets: [VDU1]
- SP2:
type: tosca.policies.tacker.Scaling
targets: [VDU2]
properties:
#increment: 1
cooldown: 120
min_instances: 1
max_instances: 2
default_instances: 1
targets: [VDU2]
- ALRM1:
type: tosca.policies.tacker.Monitoring
triggers:
resize_compute:
event_type:
type: tosca.events.resource.utilization
implementation: ceilometer
condition:
constraint: 50
granularity: 600
evaluations: 1
aggregation_method: mean
resource_type: instance
action:
resize_compute:
action_name: SP1
properties:
name: alrm1
actions:
resize_compute: "action_name: SP1"

View File

@ -67,6 +67,7 @@ topology_template:
min_instances: 1
max_instances: 2
default_instances: 1
targets: [VDU1]
- SP2:
type: tosca.policies.tacker.Scaling
@ -77,6 +78,7 @@ topology_template:
min_instances: 1
max_instances: 2
default_instances: 1
targets: [VDU2]
- ALRM1:
type: tosca.policies.tacker.Monitoring
@ -94,3 +96,7 @@ topology_template:
action:
resize_compute:
action_name: SP1
properties:
name: alrm1
actions:
resize_compute: "action_name: SP1"

View File

@ -1006,3 +1006,10 @@ class ToscaTemplateTest(TestCase):
rel_tpls = trgt.get_relationship_template()
self.assertEqual(rel_tpls[0].type, "MyAttachesTo")
def test_policies_without_required_property(self):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"data/policies/test_policies_without_required_property.yaml")
self.assertRaises(exception.ValidationError, ToscaTemplate,
tosca_tpl, None)

View File

@ -774,6 +774,18 @@ heat-translator/master/translator/tests/data/custom_types/wordpress.yaml
custom_types[name] = defintion
return custom_types
def _custom_types_policy(self):
custom_types = {}
def_file = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"data/custom_types/custom_policy.yaml")
custom_type = toscaparser.utils.yamlparser.load_yaml(def_file)
policy_types = custom_type['policy_types']
for name in policy_types:
defintion = policy_types[name]
custom_types[name] = defintion
return custom_types
def _single_node_template_content_test(self, tpl_snippet):
nodetemplates = (toscaparser.utils.yamlparser.
simple_ordered_parse(tpl_snippet))['node_templates']
@ -1746,6 +1758,26 @@ heat-translator/master/translator/tests/data/custom_types/wordpress.yaml
lambda: Policy(name, policies[name], None, None))
self.assertEqual(expectedmessage, err.__str__())
def test_policy_without_required_property(self):
tpl_snippet = '''
policies:
- some_policy:
type: tosca.policies.somePolicy
properties:
value: 100
'''
policies = (toscaparser.utils.yamlparser.
simple_parse(tpl_snippet))['policies'][0]
name = list(policies.keys())[0]
policyObj = Policy(name, policies[name], None, None,
self._custom_types_policy())
expectedmessage = _('"properties" of template "some_policy" is '
'missing required field "[\'name\']".')
err = self.assertRaises(
exception.MissingRequiredFieldError,
policyObj.validate)
self.assertEqual(expectedmessage, err.__str__())
def test_credential_datatype(self):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),

View File

@ -140,7 +140,15 @@ class TopologyTemplate(object):
policyObj = Policy(policy_name, policy_tpl,
target_objects, targets_type,
self.custom_defs)
policies.append(policyObj)
# If the policyObj.type is defined in TOSCA_definition_1_0.yaml
# or is defined as a custom definition, validate the properties
# before adding it to the policies list.
if (policyObj.type_definition and
(policyObj.type in policyObj.type_definition.TOSCA_DEF or
(policyObj.type not in policyObj.type_definition.TOSCA_DEF
and bool(policyObj.custom_def)))):
policyObj.validate()
policies.append(policyObj)
return policies
def _groups(self):