diff --git a/toscaparser/functions.py b/toscaparser/functions.py index fa43c4e3..d4982297 100644 --- a/toscaparser/functions.py +++ b/toscaparser/functions.py @@ -207,10 +207,13 @@ class GetAttribute(Function): """ return self._find_node_template_containing_attribute() + # Attributes can be explicitly created as part of the type definition + # or a property name can be implicitly used as an attribute name def _find_node_template_containing_attribute(self): node_tpl = self._find_node_template(self.args[0]) if node_tpl and \ - not self._attribute_exists_in_type(node_tpl.type_definition): + not self._attribute_exists_in_type(node_tpl.type_definition) \ + and self.attribute_name not in node_tpl.get_properties(): ExceptionCollector.appendException( KeyError(_('Attribute "%(att)s" was not found in node ' 'template "%(ntpl)s".') % diff --git a/toscaparser/tests/data/functions/test_get_implicit_attribute.yaml b/toscaparser/tests/data/functions/test_get_implicit_attribute.yaml new file mode 100644 index 00000000..a269005a --- /dev/null +++ b/toscaparser/tests/data/functions/test_get_implicit_attribute.yaml @@ -0,0 +1,25 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Attribute can be defined explicitly as part of type definition + or implicitly via property. This TOSCA template tests validation + of attribute name implicitly created as a property and referenced + via get_attribute function. + +node_types: + ServerNode: + derived_from: SoftwareComponent + properties: + notification_port: + type: integer + +topology_template: + node_templates: + my_server: + type: ServerNode + properties: + notification_port: 8000 + + outputs: + ip_address: + value: { get_attribute: [ my_server, notification_port ] } \ No newline at end of file diff --git a/toscaparser/tests/test_functions.py b/toscaparser/tests/test_functions.py index d4a79927..fa601406 100644 --- a/toscaparser/tests/test_functions.py +++ b/toscaparser/tests/test_functions.py @@ -314,6 +314,10 @@ class GetAttributeTest(TestCase): self._load_template( 'functions/test_get_attribute_with_nested_params.yaml') + def test_implicit_attribute(self): + self.assertIsNotNone(self._load_template( + 'functions/test_get_implicit_attribute.yaml')) + class ConcatTest(TestCase):