diff --git a/toscaparser/elements/entity_type.py b/toscaparser/elements/entity_type.py index 710a026..5d620a5 100644 --- a/toscaparser/elements/entity_type.py +++ b/toscaparser/elements/entity_type.py @@ -10,6 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. +import copy import logging import os from toscaparser.common.exception import ExceptionCollector @@ -88,9 +89,11 @@ class EntityType(object): return None defs = self.defs if ndtype in defs: - value = defs[ndtype] + # copy the value to avoid that next operations add items in the + # item definitions + value = copy.copy(defs[ndtype]) if parent: - p = self.parent_type + p = self if p: while p: if ndtype in p.defs: @@ -106,7 +109,7 @@ class EntityType(object): if p_value not in value: value.append(p_value) else: - value = parent_value + value = copy.copy(parent_value) p = p.parent_type return value diff --git a/toscaparser/entity_template.py b/toscaparser/entity_template.py index 681032d..e23cdfa 100644 --- a/toscaparser/entity_template.py +++ b/toscaparser/entity_template.py @@ -142,13 +142,24 @@ class EntityTemplate(object): def _create_capabilities(self): capability = [] caps = self.type_definition.get_value(self.CAPABILITIES, - self.entity_tpl) + self.entity_tpl, True) if caps: for name, props in caps.items(): capabilities = self.type_definition.get_capabilities() if name in capabilities.keys(): c = capabilities[name] - cap = Capability(name, props['properties'], c) + properties = {} + # first use the definition default value + if c.properties: + for property_name in c.properties.keys(): + prop_def = c.properties[property_name] + if 'default' in prop_def: + properties[property_name] = prop_def['default'] + # then update (if available) with the node properties + if 'properties' in props and props['properties']: + properties.update(props['properties']) + + cap = Capability(name, properties, c) capability.append(cap) return capability diff --git a/toscaparser/tests/data/custom_types/node_with_cap.yaml b/toscaparser/tests/data/custom_types/node_with_cap.yaml new file mode 100644 index 0000000..11e1b51 --- /dev/null +++ b/toscaparser/tests/data/custom_types/node_with_cap.yaml @@ -0,0 +1,30 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Node type that has a requirement of a capability with a defined value + +node_types: + tosca.capabilities.SomeCap: + derived_from: tosca.capabilities.Root + properties: + type: + type: string + required: true + default: someval + constraints: + - equal: someval + + tosca.nodes.SomeNode: + derived_from: tosca.nodes.Root + requirements: + - some_req: + capability: tosca.capabilities.SomeCap + node: tosca.nodes.NodeWithCap + relationship: tosca.relationships.HostedOn + + tosca.nodes.NodeWithCap: + derived_from: tosca.nodes.Root + capabilities: + some_req: + type: tosca.capabilities.SomeCap + diff --git a/toscaparser/tests/data/functions/test_capabilties_inheritance.yaml b/toscaparser/tests/data/functions/test_capabilties_inheritance.yaml new file mode 100644 index 0000000..f0bec84 --- /dev/null +++ b/toscaparser/tests/data/functions/test_capabilties_inheritance.yaml @@ -0,0 +1,25 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: TOSCA simple profile to test the attribute inheritance + +imports: + - ../custom_types/node_with_cap.yaml + +topology_template: + + node_templates: + + some_node: + type: tosca.nodes.SomeNode + requirements: + - some_req: node_cap + interfaces: + Standard: + configure: + implementation: some_script.sh + inputs: + some_input: { get_property: [ SELF, some_req, type ] } + + node_cap: + type: tosca.nodes.NodeWithCap + diff --git a/toscaparser/tests/test_functions.py b/toscaparser/tests/test_functions.py index 4fe3d19..182d8e1 100644 --- a/toscaparser/tests/test_functions.py +++ b/toscaparser/tests/test_functions.py @@ -147,6 +147,16 @@ class IntrinsicFunctionsTest(TestCase): self.assertTrue(isinstance(wp_list_prop, functions.GetProperty)) self.assertEqual(3, wp_list_prop.result()) + def test_get_property_with_capabilties_inheritance(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/functions/test_capabilties_inheritance.yaml") + some_node = self._get_node('some_node', ToscaTemplate(tosca_tpl)) + operation = self._get_operation(some_node.interfaces, 'configure') + some_input = operation.inputs['some_input'] + self.assertTrue(isinstance(some_input, functions.GetProperty)) + self.assertEqual('someval', some_input.result()) + class GetAttributeTest(TestCase): diff --git a/toscaparser/tests/test_topology_template.py b/toscaparser/tests/test_topology_template.py index b72c7e1..0f1a33e 100644 --- a/toscaparser/tests/test_topology_template.py +++ b/toscaparser/tests/test_topology_template.py @@ -76,7 +76,7 @@ class TopologyTemplateTest(TestCase): tpl_name = "app" expected_type = "example.SomeApp" expected_properties = ['admin_user', 'pool_size'] - expected_capabilities = ['message_receiver'] + expected_capabilities = ['feature', 'message_receiver'] expected_requirements = [{'host': {'node': 'websrv'}}] expected_relationshp = ['tosca.relationships.HostedOn'] expected_host = ['websrv'] diff --git a/toscaparser/tests/test_toscatpl.py b/toscaparser/tests/test_toscatpl.py index 6dbf891..930a925 100644 --- a/toscaparser/tests/test_toscatpl.py +++ b/toscaparser/tests/test_toscatpl.py @@ -67,7 +67,7 @@ class ToscaTemplateTest(TestCase): tpl_name = "mysql_database" expected_type = "tosca.nodes.Database" expected_properties = ['name', 'password', 'user'] - expected_capabilities = ['database_endpoint'] + expected_capabilities = ['database_endpoint', 'feature'] expected_requirements = [{'host': 'mysql_dbms'}] ''' TODO: needs enhancement in tosca_elk.yaml.. expected_relationshp = ['tosca.relationships.HostedOn'] @@ -372,7 +372,7 @@ class ToscaTemplateTest(TestCase): type: integer required: false ''' - expected_capabilities = ['test_cap'] + expected_capabilities = ['app_endpoint', 'feature', 'test_cap'] nodetemplates = (toscaparser.utils.yamlparser. simple_parse(tpl_snippet))['node_templates'] custom_def = (toscaparser.utils.yamlparser.