summaryrefslogtreecommitdiffstats
path: root/tosca2heat/tosca-parser/toscaparser/functions.py
diff options
context:
space:
mode:
Diffstat (limited to 'tosca2heat/tosca-parser/toscaparser/functions.py')
-rw-r--r--tosca2heat/tosca-parser/toscaparser/functions.py110
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