diff options
Diffstat (limited to 'tosca2heat/tosca-parser/toscaparser/functions.py')
-rw-r--r-- | tosca2heat/tosca-parser/toscaparser/functions.py | 110 |
1 files changed, 101 insertions, 9 deletions
diff --git a/tosca2heat/tosca-parser/toscaparser/functions.py b/tosca2heat/tosca-parser/toscaparser/functions.py index 1b64416..d498229 100644 --- a/tosca2heat/tosca-parser/toscaparser/functions.py +++ b/tosca2heat/tosca-parser/toscaparser/functions.py @@ -14,6 +14,7 @@ import abc import six +import toscaparser.elements.interfaces from toscaparser.common.exception import ExceptionCollector from toscaparser.common.exception import UnknownInputError @@ -22,12 +23,14 @@ from toscaparser.elements.constraints import Schema from toscaparser.elements.datatype import DataType from toscaparser.elements.entity_type import EntityType from toscaparser.elements.relationshiptype import RelationshipType +from toscaparser.elements.statefulentitytype import StatefulEntityType from toscaparser.utils.gettextutils import _ GET_PROPERTY = 'get_property' GET_ATTRIBUTE = 'get_attribute' GET_INPUT = 'get_input' +GET_OPERATION_OUTPUT = 'get_operation_output' CONCAT = 'concat' TOKEN = 'token' @@ -143,6 +146,8 @@ class GetAttribute(Function): self._find_node_template_containing_attribute() else: node_tpl = self._find_node_template(self.args[0]) + if node_tpl is None: + return index = 2 attrs = node_tpl.type_definition.get_attributes_def() found = [attrs[self.args[1]]] if self.args[1] in attrs else [] @@ -202,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".') % @@ -229,7 +237,7 @@ class GetAttribute(Function): target_type = target_node.type_definition for capability in target_type.get_capabilities_objects(): if capability.type in \ - hosted_on_rel['valid_target_types']: + hosted_on_rel['valid_target_types']: if self._attribute_exists_in_type(target_type): return target_node return self._find_host_containing_attribute( @@ -609,6 +617,88 @@ class GetProperty(Function): return None +class GetOperationOutput(Function): + def validate(self): + if len(self.args) == 4: + self._find_node_template(self.args[0]) + interface_name = self._find_interface_name(self.args[1]) + self._find_operation_name(interface_name, self.args[2]) + else: + ExceptionCollector.appendException( + ValueError(_('Illegal arguments for function "{0}". Expected ' + 'arguments: "template_name","interface_name",' + '"operation_name","output_variable_name"' + ).format(GET_OPERATION_OUTPUT))) + return + + def _find_interface_name(self, interface_name): + if interface_name in toscaparser.elements.interfaces.SECTIONS: + return interface_name + else: + ExceptionCollector.appendException( + ValueError(_('Enter a valid interface name' + ).format(GET_OPERATION_OUTPUT))) + return + + def _find_operation_name(self, interface_name, operation_name): + if(interface_name == 'Configure' or + interface_name == 'tosca.interfaces.node.relationship.Configure'): + if(operation_name in + StatefulEntityType. + interfaces_relationship_configure_operations): + return operation_name + else: + ExceptionCollector.appendException( + ValueError(_('Enter an operation of Configure interface' + ).format(GET_OPERATION_OUTPUT))) + return + elif(interface_name == 'Standard' or + interface_name == 'tosca.interfaces.node.lifecycle.Standard'): + if(operation_name in + StatefulEntityType.interfaces_node_lifecycle_operations): + return operation_name + else: + ExceptionCollector.appendException( + ValueError(_('Enter an operation of Standard interface' + ).format(GET_OPERATION_OUTPUT))) + return + else: + ExceptionCollector.appendException( + ValueError(_('Enter a valid operation name' + ).format(GET_OPERATION_OUTPUT))) + return + + def _find_node_template(self, node_template_name): + if node_template_name == TARGET: + if not isinstance(self.context.type_definition, RelationshipType): + ExceptionCollector.appendException( + KeyError(_('"TARGET" keyword can only be used in context' + ' to "Relationships" target node'))) + return + return self.context.target + if node_template_name == SOURCE: + if not isinstance(self.context.type_definition, RelationshipType): + ExceptionCollector.appendException( + KeyError(_('"SOURCE" keyword can only be used in context' + ' to "Relationships" source node'))) + return + return self.context.source + name = self.context.name \ + if node_template_name == SELF and \ + not isinstance(self.context, list) \ + else node_template_name + for node_template in self.tosca_tpl.nodetemplates: + if node_template.name == name: + return node_template + ExceptionCollector.appendException( + KeyError(_( + 'Node template "{0}" was not found.' + ).format(node_template_name))) + + def result(self): + return self + + class Concat(Function): """Validate the function and provide an instance of the function @@ -687,6 +777,7 @@ function_mappings = { GET_PROPERTY: GetProperty, GET_INPUT: GetInput, GET_ATTRIBUTE: GetAttribute, + GET_OPERATION_OUTPUT: GetOperationOutput, CONCAT: Concat, TOKEN: Token } @@ -724,11 +815,12 @@ def get_function(tosca_tpl, node_template, raw_function): parsing was unsuccessful. """ if is_function(raw_function): - func_name = list(raw_function.keys())[0] - if func_name in function_mappings: - func = function_mappings[func_name] - func_args = list(raw_function.values())[0] - if not isinstance(func_args, list): - func_args = [func_args] - return func(tosca_tpl, node_template, func_name, func_args) + if isinstance(raw_function, dict): + func_name = list(raw_function.keys())[0] + if func_name in function_mappings: + func = function_mappings[func_name] + func_args = list(raw_function.values())[0] + if not isinstance(func_args, list): + func_args = [func_args] + return func(tosca_tpl, node_template, func_name, func_args) return raw_function |