You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by em...@apache.org on 2017/05/01 22:24:02 UTC
[13/13] incubator-ariatosca git commit: ARIA-139 Support attributes
ARIA-139 Support attributes
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/b7e1836d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/b7e1836d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/b7e1836d
Branch: refs/heads/ARIA-139-attributes
Commit: b7e1836d894944ca1ae32fc63bb1b25e2fcaad6a
Parents: 0878526
Author: Tal Liron <ta...@gmail.com>
Authored: Wed Apr 19 20:07:33 2017 -0500
Committer: Tal Liron <ta...@gmail.com>
Committed: Mon May 1 17:03:52 2017 -0500
----------------------------------------------------------------------
aria/core.py | 6 +-
aria/modeling/functions.py | 113 ++-
aria/modeling/mixins.py | 2 +-
aria/modeling/relationship.py | 19 +-
aria/modeling/service_common.py | 220 +++++-
aria/modeling/service_instance.py | 78 ++-
aria/modeling/service_template.py | 126 ++--
aria/modeling/utils.py | 33 +-
aria/parser/consumption/__init__.py | 11 +-
aria/parser/consumption/modeling.py | 4 +-
aria/utils/formatting.py | 4 +-
.../block-storage-1/block-storage-1.yaml | 2 +-
.../block-storage-2/block-storage-2.yaml | 2 +-
.../block-storage-3/block-storage-3.yaml | 2 +-
.../block-storage-4/block-storage-4.yaml | 2 +-
.../block-storage-5/block-storage-5.yaml | 6 +-
.../block-storage-6/block-storage-6.yaml | 4 +-
.../use-cases/multi-tier-1/multi-tier-1.yaml | 14 +-
.../simple_v1_0/__init__.py | 12 +-
.../simple_v1_0/functions.py | 536 ---------------
.../simple_v1_0/modeling/__init__.py | 171 ++---
.../simple_v1_0/modeling/data_types.py | 10 +-
.../simple_v1_0/modeling/functions.py | 687 +++++++++++++++++++
.../simple_v1_0/modeling/properties.py | 17 +-
.../simple_v1_0/presenter.py | 4 +-
.../simple_v1_0/templates.py | 7 +-
.../node-cellar/node-cellar.yaml | 6 +-
27 files changed, 1248 insertions(+), 850 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/aria/core.py
----------------------------------------------------------------------
diff --git a/aria/core.py b/aria/core.py
index af1984a..cc943ef 100644
--- a/aria/core.py
+++ b/aria/core.py
@@ -77,10 +77,14 @@ class Core(object):
consumption.ConsumerChain(
context,
(
+ consumption.CoerceServiceInstanceValues,
+ consumption.ValidateServiceInstance,
consumption.SatisfyRequirements,
+ consumption.CoerceServiceInstanceValues,
consumption.ValidateCapabilities,
consumption.FindHosts,
- consumption.ConfigureOperations
+ consumption.ConfigureOperations,
+ consumption.CoerceServiceInstanceValues
)).consume()
if context.validation.dump_issues():
raise exceptions.InstantiationError('Failed to instantiate service template')
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/aria/modeling/functions.py
----------------------------------------------------------------------
diff --git a/aria/modeling/functions.py b/aria/modeling/functions.py
index 02f4454..7c773ed 100644
--- a/aria/modeling/functions.py
+++ b/aria/modeling/functions.py
@@ -13,20 +13,127 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from ..parser.consumption import ConsumptionContext
+from ..parser.exceptions import InvalidValueError
+from ..utils.collections import OrderedDict
+from . import exceptions
+
+
class Function(object):
"""
- An intrinsic function.
+ Base class for intrinsic functions. Serves as a placeholder for a value that should eventually
+ be derived by "evaluating" (calling) the function.
- Serves as a placeholder for a value that should eventually be derived by calling the function.
+ Note that this base class is provided as a convenience and you do not have to inherit it: any
+ object with an ``__evaluate__`` method would be treated similarly.
"""
@property
def as_raw(self):
raise NotImplementedError
- def _evaluate(self, context, container):
+ def __evaluate__(self, container_holder):
+ """
+ Evaluates the function if possible. If impossible, raises
+ :class:`CannotEvaluateFunctionException` (do not just return None).
+
+ :rtype: Evaluation (or any object with ``value`` and ``final`` properties)
+ """
+
raise NotImplementedError
def __deepcopy__(self, memo):
# Circumvent cloning in order to maintain our state
return self
+
+
+class Evaluation(object):
+ """
+ A wrapper for an evaluated :class:`Function` value.
+ """
+
+ def __init__(self, value, final=False):
+ self.value = value
+ self.final = final
+
+
+class NodeTemplateConstraint(object):
+ """
+ Used to constrain requirements for node templates.
+
+ Must be serializable.
+ """
+
+ def matches(self, source_node_template, target_node_template):
+ """
+ Returns true is the target matches the constraint for the source.
+ """
+ raise NotImplementedError
+
+
+def evaluate(value, container_holder, report_issues=False): # pylint: disable=too-many-branches
+ """
+ Recursively attempts to call ``__evaluate__``. If an evaluation occurred will return an
+ :class:`Evaluation`, otherwise it will be None. If any evaluation is non-final, then the entire
+ evaluation will also be non-final.
+ """
+
+ evaluated = False
+ final = True
+
+ if hasattr(value, '__evaluate__'):
+ try:
+ evaluation = value.__evaluate__(container_holder)
+
+ # Verify evaluation structure
+ if (evaluation is None) \
+ or (not hasattr(evaluation, 'value')) \
+ or (not hasattr(evaluation, 'final')):
+ raise InvalidValueError('bad __evaluate__ implementation')
+
+ evaluated = True
+ value = evaluation.value
+ final = evaluation.final
+
+ # The evaluated value might itself be evaluable
+ evaluation = evaluate(value, container_holder, report_issues)
+ if evaluation is not None:
+ value = evaluation.value
+ if not evaluation.final:
+ final = False
+ except exceptions.CannotEvaluateFunctionException:
+ pass
+ except InvalidValueError as e:
+ if report_issues:
+ context = ConsumptionContext.get_thread_local()
+ context.validation.report(e.issue)
+
+ elif isinstance(value, list):
+ evaluated_list = []
+ for v in value:
+ evaluation = evaluate(v, container_holder, report_issues)
+ if evaluation is not None:
+ evaluated_list.append(evaluation.value)
+ evaluated = True
+ if not evaluation.final:
+ final = False
+ else:
+ evaluated_list.append(v)
+ if evaluated:
+ value = evaluated_list
+
+ elif isinstance(value, dict):
+ evaluated_dict = OrderedDict()
+ for k, v in value.iteritems():
+ evaluation = evaluate(v, container_holder, report_issues)
+ if evaluation is not None:
+ evaluated_dict[k] = evaluation.value
+ evaluated = True
+ if not evaluation.final:
+ final = False
+ else:
+ evaluated_dict[k] = v
+ if evaluated:
+ value = evaluated_dict
+
+ return Evaluation(value, final) if evaluated else None
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/aria/modeling/mixins.py
----------------------------------------------------------------------
diff --git a/aria/modeling/mixins.py b/aria/modeling/mixins.py
index e6db5a3..38c812d 100644
--- a/aria/modeling/mixins.py
+++ b/aria/modeling/mixins.py
@@ -124,7 +124,7 @@ class InstanceModelMixin(ModelMixin):
def validate(self):
pass
- def coerce_values(self, container, report_issues):
+ def coerce_values(self, report_issues):
pass
def dump(self):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/aria/modeling/relationship.py
----------------------------------------------------------------------
diff --git a/aria/modeling/relationship.py b/aria/modeling/relationship.py
index 291d08c..40be5b2 100644
--- a/aria/modeling/relationship.py
+++ b/aria/modeling/relationship.py
@@ -146,13 +146,18 @@ def one_to_one(model_class,
false to disable
:type back_populates: basestring|bool
"""
- if back_populates is None:
- back_populates = model_class.__tablename__
+ backref_kwargs = None
+ if back_populates is not NO_BACK_POP:
+ if back_populates is None:
+ back_populates = model_class.__tablename__
+ backref_kwargs = {'name': back_populates, 'uselist': False}
+ back_populates = None
return _relationship(model_class,
other_table,
fk=fk,
back_populates=back_populates,
+ backref_kwargs=backref_kwargs,
other_fk=other_fk)
@@ -190,6 +195,7 @@ def one_to_many(model_class,
rel_kwargs.setdefault('cascade', 'all')
if back_populates is None:
back_populates = model_class.__tablename__
+
return _relationship(
model_class,
child_table,
@@ -330,10 +336,11 @@ def _relationship(model_class,
if backref_kwargs:
assert back_populates is None
- return relationship(lambda: _get_class_for_table(model_class, other_table_name),
- backref=backref(**backref_kwargs),
- **relationship_kwargs
- )
+ return relationship(
+ lambda: _get_class_for_table(model_class, other_table_name),
+ backref=backref(**backref_kwargs),
+ **relationship_kwargs
+ )
else:
if back_populates is not NO_BACK_POP:
relationship_kwargs['back_populates'] = back_populates
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/aria/modeling/service_common.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_common.py b/aria/modeling/service_common.py
index 1188f34..25ea905 100644
--- a/aria/modeling/service_common.py
+++ b/aria/modeling/service_common.py
@@ -15,6 +15,8 @@
# pylint: disable=no-self-argument, no-member, abstract-method
+import datetime
+
from sqlalchemy import (
Column,
Text,
@@ -22,12 +24,13 @@ from sqlalchemy import (
)
from sqlalchemy.ext.declarative import declared_attr
+from ..parser import dsl_specification
from ..parser.consumption import ConsumptionContext
from ..utils import collections, formatting, console
from .mixins import InstanceModelMixin, TemplateModelMixin
from . import (
relationship,
- utils
+ functions
)
@@ -50,8 +53,171 @@ class ParameterBase(TemplateModelMixin):
name = Column(Text)
type_name = Column(Text)
- value = Column(PickleType)
description = Column(Text)
+ _value = Column(PickleType)
+
+ @property
+ def value(self):
+ value = self._value
+ if value is not None:
+ evaluation = functions.evaluate(value, self)
+ if evaluation is not None:
+ value = evaluation.value
+ return value
+
+ @value.setter
+ def value(self, value):
+ self._value = value
+
+ @property
+ def container(self): # pylint: disable=too-many-return-statements,too-many-branches
+ """
+ The container for this parameter, which would be another model.
+
+ *All* parameters should have a container model. In case this property method fails to find
+ it, it will raise a ValueError, which should signify an abnormal, orphaned parameter.
+ """
+
+ def get_interface_container(interface):
+ # Node
+ if interface.node:
+ return interface.node
+ elif interface.relationship:
+ return interface.relationship.source_node
+ # Group
+ elif interface.group:
+ return interface.group
+ raise ValueError('interface parameter does not have a container: {0}'
+ .format(self.name))
+
+ def get_interface_template_container(interface_template):
+ # NodeTemplate
+ if interface_template.node_template:
+ return interface_template.node_template
+ elif interface_template.relationship_template:
+ relationship_template = interface_template.relationship_template
+ requirement_template = relationship_template.requirement_template
+ return requirement_template.node_template
+ # GroupTemplate
+ elif interface_template.group_template:
+ return interface_template.group_template
+ raise ValueError('interface_template parameter does not have a container: {0}'
+ .format(self.name))
+
+ # Node
+ if self.properties_nodes:
+ return self.properties_nodes[0]
+ elif self.attributes_nodes:
+ return self.attributes_nodes[0]
+ elif self.properties_capabilities:
+ capability = self.properties_capabilities[0]
+ return capability.node
+ elif self.properties_artifacts:
+ artifact = self.properties_artifacts[0]
+ return artifact.node
+ elif self.properties_relationships:
+ relationship = self.properties_relationships[0] # pylint: disable=redefined-outer-name
+ return relationship.source_node
+ # Group
+ elif self.properties_groups:
+ return self.properties_groups[0]
+ # Policy
+ elif self.properties_policies:
+ return self.properties_policies[0]
+ # Service
+ elif self.inputs_services:
+ return self.inputs_services[0]
+ elif self.outputs_services:
+ return self.outputs_services[0]
+ # Execution
+ elif self.inputs_executions:
+ return self.inputs_executions[0]
+ # Node or Group
+ elif self.inputs_interfaces:
+ interface = self.inputs_interfaces[0]
+ return get_interface_container(interface)
+ elif self.inputs_operations:
+ operation = self.inputs_operations[0]
+ # Node or Group
+ if operation.interface:
+ return get_interface_container(operation.interface)
+ # Service
+ elif operation.service:
+ return operation.service
+ raise ValueError('operation parameter does not have a container: {0}'
+ .format(self.name))
+
+ # NodeTemplate
+ elif self.properties_node_templates:
+ return self.properties_node_templates[0]
+ elif self.attributes_node_templates:
+ return self.attributes_node_templates[0]
+ elif self.properties_capability_templates:
+ capability_template = self.properties_capability_templates[0]
+ return capability_template.node_template
+ elif self.properties_artifact_templates:
+ artifact_template = self.properties_artifact_templates[0]
+ return artifact_template.node_template
+ elif self.properties_relationship_templates:
+ relationship_template = self.properties_relationship_templates[0]
+ requirement_template = relationship_template.requirement_template
+ return requirement_template.node_template
+ # GroupTemplate
+ elif self.properties_group_templates:
+ return self.properties_group_templates[0]
+ # PolicyTemplate
+ elif self.properties_policy_templates:
+ return self.properties_policy_templates[0]
+ # ServiceTemplate
+ elif self.inputs_service_templates:
+ return self.inputs_service_templates[0]
+ elif self.outputs_service_templates:
+ return self.outputs_service_templates[0]
+ # NodeTemplate or GroupTemplate
+ elif self.inputs_interface_templates:
+ interface_template = self.inputs_interface_templates[0]
+ return get_interface_template_container(interface_template)
+ elif self.inputs_operation_templates:
+ operation_template = self.inputs_operation_templates[0]
+ # NodeTemplate or GroupTemplate
+ if operation_template.interface_template:
+ return get_interface_template_container(operation_template.interface_template)
+ # ServiceTemplate
+ elif operation_template.service_template:
+ return operation_template.service_template
+ raise ValueError('operation_template parameter does not have a container: {0}'
+ .format(self.name))
+
+ raise ValueError('parameter does not have a container: {0}'.format(self.name))
+
+ @property
+ def service(self):
+ """
+ The :class:`Service` containing this parameter, or None if not contained in a service.
+ """
+
+ from . import models
+ container = self.container
+ if isinstance(container, models.Service):
+ return container
+ elif hasattr(container, 'service'):
+ return container.service
+ return None
+
+ @property
+ def service_template(self):
+ """
+ The :class:`ServiceTemplate` containing this parameter, or None if not contained in a
+ service template.
+ """
+
+ from . import models
+ container = self.container
+ if isinstance(container, models.ServiceTemplate):
+ return container
+ elif hasattr(container, 'service_template'):
+ return container.service_template
+ return None
@property
def as_raw(self):
@@ -65,47 +231,69 @@ class ParameterBase(TemplateModelMixin):
from . import models
return models.Parameter(name=self.name,
type_name=self.type_name,
- value=self.value,
+ _value=self._value,
description=self.description)
- def coerce_values(self, container, report_issues):
- if self.value is not None:
- self.value = utils.coerce_value(container, self.value,
- report_issues)
+ def coerce_values(self, report_issues):
+ value = self._value
+ if value is not None:
+ evaluation = functions.evaluate(value, self, report_issues)
+ if (evaluation is not None) and evaluation.final:
+ # A final evaluation can safely replace the existing value
+ self._value = evaluation.value
def dump(self):
context = ConsumptionContext.get_thread_local()
if self.type_name is not None:
console.puts('{0}: {1} ({2})'.format(
context.style.property(self.name),
- context.style.literal(self.value),
+ context.style.literal(formatting.as_raw(self.value)),
context.style.type(self.type_name)))
else:
console.puts('{0}: {1}'.format(
context.style.property(self.name),
- context.style.literal(self.value)))
+ context.style.literal(formatting.as_raw(self.value))))
if self.description:
console.puts(context.style.meta(self.description))
def unwrap(self):
return self.name, self.value
+ @dsl_specification('3.2.1-2', 'tosca-simple-1.0')
@classmethod
def wrap(cls, name, value, description=None):
"""
Wraps an arbitrary value as a parameter. The type will be guessed via introspection.
+ For primitive types, we will prefer their TOSCA aliases. See the `TOSCA Simple Profile v1.0
+ cos01 specification <http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01
+ /TOSCA-Simple-Profile-YAML-v1.0-cos01.html#_Toc373867862>`__
+
:param name: Parameter name
:type name: basestring
:param value: Parameter value
:param description: Description (optional)
:type description: basestring
"""
- return cls(name=name,
- type_name=formatting.full_type_name(value)
- if value is not None else None,
- value=value,
- description=description)
+ from . import models
+ if value is None:
+ type_name = 'null'
+ elif isinstance(value, basestring):
+ type_name = 'string'
+ elif isinstance(value, int):
+ type_name = 'integer'
+ elif isinstance(value, float):
+ type_name = 'float'
+ elif isinstance(value, bool):
+ type_name = 'boolean'
+ elif isinstance(value, datetime.datetime):
+ type_name = 'timestamp'
+ else:
+ type_name = formatting.full_type_name(value)
+ return models.Parameter(name=name,
+ type_name=type_name,
+ value=value,
+ description=description)
class TypeBase(InstanceModelMixin):
@@ -188,7 +376,7 @@ class TypeBase(InstanceModelMixin):
self._append_raw_children(types)
return types
- def coerce_values(self, container, report_issues):
+ def coerce_values(self, report_issues):
pass
def dump(self):
@@ -237,7 +425,7 @@ class MetadataBase(TemplateModelMixin):
('name', self.name),
('value', self.value)))
- def coerce_values(self, container, report_issues):
+ def coerce_values(self, report_issues):
pass
def instantiate(self, container):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/aria/modeling/service_instance.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py
index ad8e7ed..1efe1e1 100644
--- a/aria/modeling/service_instance.py
+++ b/aria/modeling/service_instance.py
@@ -251,16 +251,16 @@ class ServiceBase(InstanceModelMixin):
utils.validate_dict_values(self.outputs)
utils.validate_dict_values(self.workflows)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(container, self.meta_data, report_issues)
- utils.coerce_dict_values(container, self.nodes, report_issues)
- utils.coerce_dict_values(container, self.groups, report_issues)
- utils.coerce_dict_values(container, self.policies, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.meta_data, report_issues)
+ utils.coerce_dict_values(self.nodes, report_issues)
+ utils.coerce_dict_values(self.groups, report_issues)
+ utils.coerce_dict_values(self.policies, report_issues)
if self.substitution is not None:
- self.substitution.coerce_values(container, report_issues)
- utils.coerce_dict_values(container, self.inputs, report_issues)
- utils.coerce_dict_values(container, self.outputs, report_issues)
- utils.coerce_dict_values(container, self.workflows, report_issues)
+ self.substitution.coerce_values(report_issues)
+ utils.coerce_dict_values(self.inputs, report_issues)
+ utils.coerce_dict_values(self.outputs, report_issues)
+ utils.coerce_dict_values(self.workflows, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -513,6 +513,10 @@ class NodeBase(InstanceModelMixin):
def properties(cls):
return relationship.many_to_many(cls, 'parameter', prefix='properties', dict_key='name')
+ @declared_attr
+ def attributes(cls):
+ return relationship.many_to_many(cls, 'parameter', prefix='attributes', dict_key='name')
+
# endregion
description = Column(Text)
@@ -646,6 +650,7 @@ class NodeBase(InstanceModelMixin):
('name', self.name),
('type_name', self.type.name),
('properties', formatting.as_raw_dict(self.properties)),
+ ('attributes', formatting.as_raw_dict(self.properties)),
('interfaces', formatting.as_raw_list(self.interfaces)),
('artifacts', formatting.as_raw_list(self.artifacts)),
('capabilities', formatting.as_raw_list(self.capabilities)),
@@ -664,17 +669,19 @@ class NodeBase(InstanceModelMixin):
# TODO: validate that node template is of type?
utils.validate_dict_values(self.properties)
+ utils.validate_dict_values(self.attributes)
utils.validate_dict_values(self.interfaces)
utils.validate_dict_values(self.artifacts)
utils.validate_dict_values(self.capabilities)
utils.validate_list_values(self.outbound_relationships)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(self, self.properties, report_issues)
- utils.coerce_dict_values(self, self.interfaces, report_issues)
- utils.coerce_dict_values(self, self.artifacts, report_issues)
- utils.coerce_dict_values(self, self.capabilities, report_issues)
- utils.coerce_list_values(self, self.outbound_relationships, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.properties, report_issues)
+ utils.coerce_dict_values(self.attributes, report_issues)
+ utils.coerce_dict_values(self.interfaces, report_issues)
+ utils.coerce_dict_values(self.artifacts, report_issues)
+ utils.coerce_dict_values(self.capabilities, report_issues)
+ utils.coerce_list_values(self.outbound_relationships, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -683,6 +690,7 @@ class NodeBase(InstanceModelMixin):
console.puts('Type: {0}'.format(context.style.type(self.type.name)))
console.puts('Template: {0}'.format(context.style.node(self.node_template.name)))
utils.dump_dict_values(self.properties, 'Properties')
+ utils.dump_dict_values(self.attributes, 'Attributes')
utils.dump_interfaces(self.interfaces)
utils.dump_dict_values(self.artifacts, 'Artifacts')
utils.dump_dict_values(self.capabilities, 'Capabilities')
@@ -797,9 +805,9 @@ class GroupBase(InstanceModelMixin):
utils.validate_dict_values(self.properties)
utils.validate_dict_values(self.interfaces)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(container, self.properties, report_issues)
- utils.coerce_dict_values(container, self.interfaces, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.properties, report_issues)
+ utils.coerce_dict_values(self.interfaces, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -916,8 +924,8 @@ class PolicyBase(InstanceModelMixin):
def validate(self):
utils.validate_dict_values(self.properties)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(container, self.properties, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.properties, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -1017,8 +1025,8 @@ class SubstitutionBase(InstanceModelMixin):
def validate(self):
utils.validate_dict_values(self.mappings)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(container, self.mappings, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.mappings, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -1121,7 +1129,7 @@ class SubstitutionMappingBase(InstanceModelMixin):
return collections.OrderedDict((
('name', self.name)))
- def coerce_values(self, container, report_issues):
+ def coerce_values(self, report_issues):
pass
def validate(self):
@@ -1311,9 +1319,9 @@ class RelationshipBase(InstanceModelMixin):
utils.validate_dict_values(self.properties)
utils.validate_dict_values(self.interfaces)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(container, self.properties, report_issues)
- utils.coerce_dict_values(container, self.interfaces, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.properties, report_issues)
+ utils.coerce_dict_values(self.interfaces, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -1451,8 +1459,8 @@ class CapabilityBase(InstanceModelMixin):
def validate(self):
utils.validate_dict_values(self.properties)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(container, self.properties, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.properties, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -1598,9 +1606,9 @@ class InterfaceBase(InstanceModelMixin):
utils.validate_dict_values(self.inputs)
utils.validate_dict_values(self.operations)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(container, self.inputs, report_issues)
- utils.coerce_dict_values(container, self.operations, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.inputs, report_issues)
+ utils.coerce_dict_values(self.operations, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -1765,8 +1773,8 @@ class OperationBase(InstanceModelMixin):
# TODO must be associated with interface or service
utils.validate_dict_values(self.inputs)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(container, self.inputs, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.inputs, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -1905,8 +1913,8 @@ class ArtifactBase(InstanceModelMixin):
def validate(self):
utils.validate_dict_values(self.properties)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(container, self.properties, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.properties, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index 7fab4fc..73025e2 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -17,7 +17,6 @@
from __future__ import absolute_import # so we can import standard 'types'
-from types import FunctionType
from datetime import datetime
from sqlalchemy import (
@@ -25,7 +24,8 @@ from sqlalchemy import (
Text,
Integer,
Boolean,
- DateTime
+ DateTime,
+ PickleType
)
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.ext.associationproxy import association_proxy
@@ -346,16 +346,16 @@ class ServiceTemplateBase(TemplateModelMixin):
if self.artifact_types is not None:
self.artifact_types.validate()
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(container, self.meta_data, report_issues)
- utils.coerce_dict_values(container, self.node_templates, report_issues)
- utils.coerce_dict_values(container, self.group_templates, report_issues)
- utils.coerce_dict_values(container, self.policy_templates, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.meta_data, report_issues)
+ utils.coerce_dict_values(self.node_templates, report_issues)
+ utils.coerce_dict_values(self.group_templates, report_issues)
+ utils.coerce_dict_values(self.policy_templates, report_issues)
if self.substitution_template is not None:
- self.substitution_template.coerce_values(container, report_issues)
- utils.coerce_dict_values(container, self.inputs, report_issues)
- utils.coerce_dict_values(container, self.outputs, report_issues)
- utils.coerce_dict_values(container, self.workflow_templates, report_issues)
+ self.substitution_template.coerce_values(report_issues)
+ utils.coerce_dict_values(self.inputs, report_issues)
+ utils.coerce_dict_values(self.outputs, report_issues)
+ utils.coerce_dict_values(self.workflow_templates, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -426,7 +426,7 @@ class NodeTemplateBase(TemplateModelMixin):
:ivar requirement_templates: Potential relationships with other nodes
:vartype requirement_templates: [:class:`RequirementTemplate`]
:ivar target_node_template_constraints: Constraints for filtering relationship targets
- :vartype target_node_template_constraints: [:class:`FunctionType`]
+ :vartype target_node_template_constraints: [:class:`NodeTemplateConstraint`]
:ivar service_template: Containing service template
:vartype service_template: :class:`ServiceTemplate`
:ivar group_templates: We are a member of these groups
@@ -503,6 +503,10 @@ class NodeTemplateBase(TemplateModelMixin):
return relationship.many_to_many(cls, 'parameter', prefix='properties', dict_key='name')
@declared_attr
+ def attributes(cls):
+ return relationship.many_to_many(cls, 'parameter', prefix='attributes', dict_key='name')
+
+ @declared_attr
def interface_templates(cls):
return relationship.one_to_many(cls, 'interface_template', dict_key='name')
@@ -524,12 +528,12 @@ class NodeTemplateBase(TemplateModelMixin):
default_instances = Column(Integer, default=1)
min_instances = Column(Integer, default=0)
max_instances = Column(Integer, default=None)
- target_node_template_constraints = Column(modeling_types.StrictList(FunctionType))
+ target_node_template_constraints = Column(PickleType)
- def is_target_node_valid(self, target_node_template):
+ def is_target_node_template_valid(self, target_node_template):
if self.target_node_template_constraints:
- for node_type_constraint in self.target_node_template_constraints:
- if not node_type_constraint(target_node_template, self):
+ for node_template_constraint in self.target_node_template_constraints:
+ if not node_template_constraint.matches(self, target_node_template):
return False
return True
@@ -543,6 +547,7 @@ class NodeTemplateBase(TemplateModelMixin):
('min_instances', self.min_instances),
('max_instances', self.max_instances),
('properties', formatting.as_raw_dict(self.properties)),
+ ('attributes', formatting.as_raw_dict(self.properties)),
('interface_templates', formatting.as_raw_list(self.interface_templates)),
('artifact_templates', formatting.as_raw_list(self.artifact_templates)),
('capability_templates', formatting.as_raw_list(self.capability_templates)),
@@ -559,24 +564,34 @@ class NodeTemplateBase(TemplateModelMixin):
runtime_properties={},
node_template=self)
utils.instantiate_dict(node, node.properties, self.properties)
+ utils.instantiate_dict(node, node.attributes, self.attributes)
utils.instantiate_dict(node, node.interfaces, self.interface_templates)
utils.instantiate_dict(node, node.artifacts, self.artifact_templates)
utils.instantiate_dict(node, node.capabilities, self.capability_templates)
+
+ # Default attributes
+ if 'tosca_name' in node.attributes:
+ node.attributes['tosca_name'].value = self.name
+ if 'tosca_id' in node.attributes:
+ node.attributes['tosca_id'].value = name
+
return node
def validate(self):
utils.validate_dict_values(self.properties)
+ utils.validate_dict_values(self.attributes)
utils.validate_dict_values(self.interface_templates)
utils.validate_dict_values(self.artifact_templates)
utils.validate_dict_values(self.capability_templates)
utils.validate_list_values(self.requirement_templates)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(self, self.properties, report_issues)
- utils.coerce_dict_values(self, self.interface_templates, report_issues)
- utils.coerce_dict_values(self, self.artifact_templates, report_issues)
- utils.coerce_dict_values(self, self.capability_templates, report_issues)
- utils.coerce_list_values(self, self.requirement_templates, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.properties, report_issues)
+ utils.coerce_dict_values(self.attributes, report_issues)
+ utils.coerce_dict_values(self.interface_templates, report_issues)
+ utils.coerce_dict_values(self.artifact_templates, report_issues)
+ utils.coerce_dict_values(self.capability_templates, report_issues)
+ utils.coerce_list_values(self.requirement_templates, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -592,6 +607,7 @@ class NodeTemplateBase(TemplateModelMixin):
if self.max_instances is not None
else ' or more'))
utils.dump_dict_values(self.properties, 'Properties')
+ utils.dump_dict_values(self.attributes, 'Attributes')
utils.dump_interfaces(self.interface_templates)
utils.dump_dict_values(self.artifact_templates, 'Artifact templates')
utils.dump_dict_values(self.capability_templates, 'Capability templates')
@@ -715,9 +731,9 @@ class GroupTemplateBase(TemplateModelMixin):
utils.validate_dict_values(self.properties)
utils.validate_dict_values(self.interface_templates)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(self, self.properties, report_issues)
- utils.coerce_dict_values(self, self.interface_templates, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.properties, report_issues)
+ utils.coerce_dict_values(self.interface_templates, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -846,8 +862,8 @@ class PolicyTemplateBase(TemplateModelMixin):
def validate(self):
utils.validate_dict_values(self.properties)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(self, self.properties, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.properties, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -940,8 +956,8 @@ class SubstitutionTemplateBase(TemplateModelMixin):
def validate(self):
utils.validate_dict_values(self.mappings)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(self, self.mappings, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.mappings, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -1044,7 +1060,7 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
return collections.OrderedDict((
('name', self.name)))
- def coerce_values(self, container, report_issues):
+ def coerce_values(self, report_issues):
pass
def instantiate(self, container):
@@ -1108,7 +1124,7 @@ class RequirementTemplateBase(TemplateModelMixin):
:ivar target_capability_name: Name of capability in target node (optional)
:vartype target_capability_name: basestring
:ivar target_node_template_constraints: Constraints for filtering relationship targets
- :vartype target_node_template_constraints: [:class:`FunctionType`]
+ :vartype target_node_template_constraints: [:class:`NodeTemplateConstraint`]
:ivar relationship_template: Template for relationships (optional)
:vartype relationship_template: :class:`RelationshipTemplate`
:ivar node_template: Containing node template
@@ -1178,9 +1194,7 @@ class RequirementTemplateBase(TemplateModelMixin):
@declared_attr
def relationship_template(cls):
- return relationship.one_to_one(cls,
- 'relationship_template',
- back_populates=relationship.NO_BACK_POP)
+ return relationship.one_to_one(cls, 'relationship_template')
# endregion
@@ -1210,18 +1224,18 @@ class RequirementTemplateBase(TemplateModelMixin):
# endregion
target_capability_name = Column(Text)
- target_node_template_constraints = Column(modeling_types.StrictList(FunctionType))
+ target_node_template_constraints = Column(PickleType)
def find_target(self, source_node_template):
context = ConsumptionContext.get_thread_local()
# We might already have a specific node template, so we'll just verify it
if self.target_node_template is not None:
- if not source_node_template.is_target_node_valid(self.target_node_template):
+ if not source_node_template.is_target_node_template_valid(self.target_node_template):
context.validation.report('requirement "{0}" of node template "{1}" is for node '
'template "{2}" but it does not match constraints'.format(
self.name,
- self.target_node_template_name,
+ self.target_node_template.name,
source_node_template.name),
level=validation.Issue.BETWEEN_TYPES)
if (self.target_capability_type is not None) \
@@ -1242,7 +1256,7 @@ class RequirementTemplateBase(TemplateModelMixin):
if self.target_node_type.get_descendant(target_node_template.type.name) is None:
continue
- if not source_node_template.is_target_node_valid(target_node_template):
+ if not source_node_template.is_target_node_template_valid(target_node_template):
continue
target_node_capability = self.find_target_capability(source_node_template,
@@ -1279,9 +1293,9 @@ class RequirementTemplateBase(TemplateModelMixin):
if self.relationship_template:
self.relationship_template.validate()
- def coerce_values(self, container, report_issues):
+ def coerce_values(self, report_issues):
if self.relationship_template is not None:
- self.relationship_template.coerce_values(container, report_issues)
+ self.relationship_template.coerce_values(report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -1412,9 +1426,9 @@ class RelationshipTemplateBase(TemplateModelMixin):
utils.validate_dict_values(self.properties)
utils.validate_dict_values(self.interface_templates)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(self, self.properties, report_issues)
- utils.coerce_dict_values(self, self.interface_templates, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.properties, report_issues)
+ utils.coerce_dict_values(self.interface_templates, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -1538,8 +1552,8 @@ class CapabilityTemplateBase(TemplateModelMixin):
# Apply requirement constraints
if requirement.target_node_template_constraints:
- for node_type_constraint in requirement.target_node_template_constraints:
- if not node_type_constraint(target_node_template, source_node_template):
+ for node_template_constraint in requirement.target_node_template_constraints:
+ if not node_template_constraint.matches(source_node_template, target_node_template):
return False
return True
@@ -1569,8 +1583,8 @@ class CapabilityTemplateBase(TemplateModelMixin):
def validate(self):
utils.validate_dict_values(self.properties)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(self, self.properties, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.properties, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -1723,9 +1737,9 @@ class InterfaceTemplateBase(TemplateModelMixin):
utils.validate_dict_values(self.inputs)
utils.validate_dict_values(self.operation_templates)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(container, self.inputs, report_issues)
- utils.coerce_dict_values(container, self.operation_templates, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.inputs, report_issues)
+ utils.coerce_dict_values(self.operation_templates, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -1877,7 +1891,7 @@ class OperationTemplateBase(TemplateModelMixin):
plugin = None
implementation = None
else:
- # using the execution plugin
+ # Using the execution plugin
plugin = None
implementation = self.implementation
@@ -1898,8 +1912,8 @@ class OperationTemplateBase(TemplateModelMixin):
def validate(self):
utils.validate_dict_values(self.inputs)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(container, self.inputs, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.inputs, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -2046,8 +2060,8 @@ class ArtifactTemplateBase(TemplateModelMixin):
def validate(self):
utils.validate_dict_values(self.properties)
- def coerce_values(self, container, report_issues):
- utils.coerce_dict_values(container, self.properties, report_issues)
+ def coerce_values(self, report_issues):
+ utils.coerce_dict_values(self.properties, report_issues)
def dump(self):
context = ConsumptionContext.get_thread_local()
@@ -2123,7 +2137,7 @@ class PluginSpecificationBase(TemplateModelMixin):
('version', self.version),
('enabled', self.enabled)))
- def coerce_values(self, container, report_issues):
+ def coerce_values(self, report_issues):
pass
def resolve(self, model_storage):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/aria/modeling/utils.py
----------------------------------------------------------------------
diff --git a/aria/modeling/utils.py b/aria/modeling/utils.py
index 91d7b9c..c786965 100644
--- a/aria/modeling/utils.py
+++ b/aria/modeling/utils.py
@@ -19,9 +19,6 @@ from StringIO import StringIO
from . import exceptions
from ..parser.consumption import ConsumptionContext
-from ..parser.exceptions import InvalidValueError
-from ..parser.presentation import Value
-from ..utils.collections import OrderedDict
from ..utils.console import puts
from ..utils.type import validate_value_type
@@ -109,39 +106,17 @@ def _merge_and_validate_inputs(inputs, template_inputs):
return merged_inputs
-def coerce_value(container, value, report_issues=False):
- if isinstance(value, Value):
- value = value.value
-
- if isinstance(value, list):
- return [coerce_value(container, v, report_issues) for v in value]
- elif isinstance(value, dict):
- return OrderedDict((k, coerce_value(container, v, report_issues))
- for k, v in value.iteritems())
- elif hasattr(value, '_evaluate'):
- context = ConsumptionContext.get_thread_local()
- try:
- value = value._evaluate(context, container)
- value = coerce_value(container, value, report_issues)
- except exceptions.CannotEvaluateFunctionException:
- pass
- except InvalidValueError as e:
- if report_issues:
- context.validation.report(e.issue)
- return value
-
-
-def coerce_dict_values(container, the_dict, report_issues=False):
+def coerce_dict_values(the_dict, report_issues=False):
if not the_dict:
return
- coerce_list_values(container, the_dict.itervalues(), report_issues)
+ coerce_list_values(the_dict.itervalues(), report_issues)
-def coerce_list_values(container, the_list, report_issues=False):
+def coerce_list_values(the_list, report_issues=False):
if not the_list:
return
for value in the_list:
- value.coerce_values(container, report_issues)
+ value.coerce_values(report_issues)
def validate_dict_values(the_dict):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/aria/parser/consumption/__init__.py
----------------------------------------------------------------------
diff --git a/aria/parser/consumption/__init__.py b/aria/parser/consumption/__init__.py
index 8f6d2b6..76e73be 100644
--- a/aria/parser/consumption/__init__.py
+++ b/aria/parser/consumption/__init__.py
@@ -28,9 +28,11 @@ from .modeling import (
Types,
ServiceInstance,
FindHosts,
+ ValidateServiceInstance,
ConfigureOperations,
SatisfyRequirements,
- ValidateCapabilities
+ ValidateCapabilities,
+ CoerceServiceInstanceValues
)
from .inputs import Inputs
@@ -45,7 +47,10 @@ __all__ = (
'ServiceTemplate',
'Types',
'ServiceInstance',
- 'Inputs',
+ 'FindHosts',
+ 'ValidateServiceInstance',
+ 'ConfigureOperations',
'SatisfyRequirements',
- 'ValidateCapabilities'
+ 'ValidateCapabilities',
+ 'CoerceServiceInstanceValues'
)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/aria/parser/consumption/modeling.py
----------------------------------------------------------------------
diff --git a/aria/parser/consumption/modeling.py b/aria/parser/consumption/modeling.py
index 771fd7f..44027b9 100644
--- a/aria/parser/consumption/modeling.py
+++ b/aria/parser/consumption/modeling.py
@@ -42,7 +42,7 @@ class CoerceServiceTemplateValues(Consumer):
"""
def consume(self):
- self.context.modeling.template.coerce_values(None, True)
+ self.context.modeling.template.coerce_values(True)
class ValidateServiceTemplate(Consumer):
@@ -116,7 +116,7 @@ class CoerceServiceInstanceValues(Consumer):
"""
def consume(self):
- self.context.modeling.instance.coerce_values(None, True)
+ self.context.modeling.instance.coerce_values(True)
class ValidateServiceInstance(Consumer):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/aria/utils/formatting.py
----------------------------------------------------------------------
diff --git a/aria/utils/formatting.py b/aria/utils/formatting.py
index b5e141d..75652a7 100644
--- a/aria/utils/formatting.py
+++ b/aria/utils/formatting.py
@@ -163,8 +163,8 @@ def as_raw(value):
value = value()
elif isinstance(value, list):
value = list(value)
- for i, _ in enumerate(value):
- value[i] = as_raw(value[i])
+ for i, v in enumerate(value):
+ value[i] = as_raw(v)
elif isinstance(value, dict):
value = dict(value)
for k, v in value.iteritems():
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/examples/tosca-simple-1.0/use-cases/block-storage-1/block-storage-1.yaml
----------------------------------------------------------------------
diff --git a/examples/tosca-simple-1.0/use-cases/block-storage-1/block-storage-1.yaml b/examples/tosca-simple-1.0/use-cases/block-storage-1/block-storage-1.yaml
index ff6dc92..b912fb2 100644
--- a/examples/tosca-simple-1.0/use-cases/block-storage-1/block-storage-1.yaml
+++ b/examples/tosca-simple-1.0/use-cases/block-storage-1/block-storage-1.yaml
@@ -65,4 +65,4 @@ topology_template:
value: { get_attribute: [ my_server, private_address ] }
volume_id:
description: The volume id of the block storage instance.
- value: { get_attribute: [ my_storage, volume_id ] }
+ value: { get_property: [ my_storage, volume_id ] } # ARIA NOTE: wrong in spec
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/examples/tosca-simple-1.0/use-cases/block-storage-2/block-storage-2.yaml
----------------------------------------------------------------------
diff --git a/examples/tosca-simple-1.0/use-cases/block-storage-2/block-storage-2.yaml b/examples/tosca-simple-1.0/use-cases/block-storage-2/block-storage-2.yaml
index 09c30a7..ac475cf 100644
--- a/examples/tosca-simple-1.0/use-cases/block-storage-2/block-storage-2.yaml
+++ b/examples/tosca-simple-1.0/use-cases/block-storage-2/block-storage-2.yaml
@@ -72,4 +72,4 @@ topology_template:
volume_id:
description: The volume id of the block storage instance.
- value: { get_attribute: [ my_storage, volume_id ] }
+ value: { get_property: [ my_storage, volume_id ] } # ARIA NOTE: wrong in spec
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/examples/tosca-simple-1.0/use-cases/block-storage-3/block-storage-3.yaml
----------------------------------------------------------------------
diff --git a/examples/tosca-simple-1.0/use-cases/block-storage-3/block-storage-3.yaml b/examples/tosca-simple-1.0/use-cases/block-storage-3/block-storage-3.yaml
index 3018fe9..c3f183e 100644
--- a/examples/tosca-simple-1.0/use-cases/block-storage-3/block-storage-3.yaml
+++ b/examples/tosca-simple-1.0/use-cases/block-storage-3/block-storage-3.yaml
@@ -65,4 +65,4 @@ topology_template:
value: { get_attribute: [ my_server, private_address ] }
volume_id:
description: The volume id of the block storage instance.
- value: { get_attribute: [ my_storage, volume_id ] }
+ value: { get_property: [ my_storage, volume_id ] } # ARIA NOTE: wrong in spec
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/examples/tosca-simple-1.0/use-cases/block-storage-4/block-storage-4.yaml
----------------------------------------------------------------------
diff --git a/examples/tosca-simple-1.0/use-cases/block-storage-4/block-storage-4.yaml b/examples/tosca-simple-1.0/use-cases/block-storage-4/block-storage-4.yaml
index 0693ddd..e2bdb9f 100644
--- a/examples/tosca-simple-1.0/use-cases/block-storage-4/block-storage-4.yaml
+++ b/examples/tosca-simple-1.0/use-cases/block-storage-4/block-storage-4.yaml
@@ -93,4 +93,4 @@ topology_template:
value: { get_attribute: [ my_web_app_tier_2, private_address ] }
volume_id:
description: The volume id of the block storage instance.
- value: { get_attribute: [ my_storage, volume_id ] }
+ value: { get_property: [ my_storage, volume_id ] } # ARIA NOTE: wrong in spec
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/examples/tosca-simple-1.0/use-cases/block-storage-5/block-storage-5.yaml
----------------------------------------------------------------------
diff --git a/examples/tosca-simple-1.0/use-cases/block-storage-5/block-storage-5.yaml b/examples/tosca-simple-1.0/use-cases/block-storage-5/block-storage-5.yaml
index 5f5cf71..a0c2229 100644
--- a/examples/tosca-simple-1.0/use-cases/block-storage-5/block-storage-5.yaml
+++ b/examples/tosca-simple-1.0/use-cases/block-storage-5/block-storage-5.yaml
@@ -100,10 +100,10 @@ topology_template:
outputs:
private_ip_1:
description: The private IP address of the application's first tier.
- value: { get_attribute: [my_web_app_tier_1, private_address] }
+ value: { get_attribute: [ my_web_app_tier_1, private_address ] }
private_ip_2:
description: The private IP address of the application's second tier.
- value: { get_attribute: [my_web_app_tier_2, private_address] }
+ value: { get_attribute: [ my_web_app_tier_2, private_address ] }
volume_id:
description: The volume id of the block storage instance.
- value: { get_attribute: [my_storage, volume_id] }
+ value: { get_property: [ my_storage, volume_id ] } # ARIA NOTE: wrong in spec
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/examples/tosca-simple-1.0/use-cases/block-storage-6/block-storage-6.yaml
----------------------------------------------------------------------
diff --git a/examples/tosca-simple-1.0/use-cases/block-storage-6/block-storage-6.yaml b/examples/tosca-simple-1.0/use-cases/block-storage-6/block-storage-6.yaml
index 808245b..534884a 100644
--- a/examples/tosca-simple-1.0/use-cases/block-storage-6/block-storage-6.yaml
+++ b/examples/tosca-simple-1.0/use-cases/block-storage-6/block-storage-6.yaml
@@ -96,7 +96,7 @@ topology_template:
value: { get_attribute: [ my_server2, private_address ] }
volume_id_1:
description: The volume id of the first block storage instance.
- value: { get_attribute: [my_storage, volume_id] }
+ value: { get_property: [ my_storage, volume_id ] } # ARIA NOTE: wrong in spec
volume_id_2:
description: The volume id of the second block storage instance.
- value: { get_attribute: [ my_storage2, volume_id ] }
+ value: { get_property: [ my_storage2, volume_id ] } # ARIA NOTE: wrong in spec
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/examples/tosca-simple-1.0/use-cases/multi-tier-1/multi-tier-1.yaml
----------------------------------------------------------------------
diff --git a/examples/tosca-simple-1.0/use-cases/multi-tier-1/multi-tier-1.yaml b/examples/tosca-simple-1.0/use-cases/multi-tier-1/multi-tier-1.yaml
index 3485e49..50401ec 100644
--- a/examples/tosca-simple-1.0/use-cases/multi-tier-1/multi-tier-1.yaml
+++ b/examples/tosca-simple-1.0/use-cases/multi-tier-1/multi-tier-1.yaml
@@ -59,7 +59,7 @@ topology_template:
implementation: scripts/nodejs/configure.sh
inputs:
github_url: { get_property: [ SELF, github_url ] }
- mongodb_ip: { get_attribute: [mongo_server, private_address] }
+ mongodb_ip: { get_attribute: [ mongo_server, private_address ] }
start: scripts/nodejs/start.sh
nodejs:
@@ -90,7 +90,7 @@ topology_template:
configure:
implementation: scripts/mongodb/config.sh
inputs:
- mongodb_ip: { get_attribute: [mongo_server, ip_address] }
+ mongodb_ip: { get_attribute: [ mongo_server, private_address ] } # ARIA NOTE: wrong in spec
start: scripts/mongodb/start.sh
elasticsearch:
@@ -115,7 +115,7 @@ topology_template:
pre_configure_source:
implementation: python/logstash/configure_elasticsearch.py
inputs:
- elasticsearch_ip: { get_attribute: [elasticsearch_server, ip_address] }
+ elasticsearch_ip: { get_attribute: [ elasticsearch_server, private_address ] } # ARIA NOTE: wrong in spec
interfaces:
Standard: # ARIA NOTE: wrong in spec
create: scripts/lostash/create.sh
@@ -133,8 +133,8 @@ topology_template:
configure:
implementation: scripts/kibana/config.sh
inputs:
- elasticsearch_ip: { get_attribute: [ elasticsearch_server, ip_address ] }
- kibana_ip: { get_attribute: [ kibana_server, ip_address ] }
+ elasticsearch_ip: { get_attribute: [ elasticsearch_server, private_address ] } # ARIA NOTE: wrong in spec
+ kibana_ip: { get_attribute: [ kibana_server, private_address ] } # ARIA NOTE: wrong in spec
start: scripts/kibana/start.sh
app_collectd:
@@ -155,7 +155,7 @@ topology_template:
configure:
implementation: python/collectd/config.py
inputs:
- logstash_ip: { get_attribute: [ logstash_server, ip_address ] }
+ logstash_ip: { get_attribute: [ logstash_server, private_address ] } # ARIA NOTE: wrong in spec
start: scripts/collectd/start.sh
app_rsyslog:
@@ -176,7 +176,7 @@ topology_template:
configure:
implementation: scripts/rsyslog/config.sh
inputs:
- logstash_ip: { get_attribute: [ logstash_server, ip_address ] }
+ logstash_ip: { get_attribute: [ logstash_server, private_address ] } # ARIA NOTE: wrong in spec
start: scripts/rsyslog/start.sh
app_server:
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/extensions/aria_extension_tosca/simple_v1_0/__init__.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/__init__.py b/extensions/aria_extension_tosca/simple_v1_0/__init__.py
index 29df362..d701a1d 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/__init__.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/__init__.py
@@ -30,8 +30,6 @@ from .types import (ArtifactType, DataType, CapabilityType, InterfaceType, Relat
NodeType, GroupType, PolicyType)
from .data_types import (Timestamp, Version, Range, List, Map, ScalarSize, ScalarTime,
ScalarFrequency)
-from .functions import (Concat, Token, GetInput, GetProperty, GetAttribute, GetOperationOutput,
- GetNodesOfType, GetArtifact)
MODULES = (
'modeling',
@@ -89,12 +87,4 @@ __all__ = (
'Map',
'ScalarSize',
'ScalarTime',
- 'ScalarFrequency',
- 'Concat',
- 'Token',
- 'GetInput',
- 'GetProperty',
- 'GetAttribute',
- 'GetOperationOutput',
- 'GetNodesOfType',
- 'GetArtifact')
+ 'ScalarFrequency')
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7e1836d/extensions/aria_extension_tosca/simple_v1_0/functions.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/functions.py b/extensions/aria_extension_tosca/simple_v1_0/functions.py
deleted file mode 100644
index 405aa8f..0000000
--- a/extensions/aria_extension_tosca/simple_v1_0/functions.py
+++ /dev/null
@@ -1,536 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from cStringIO import StringIO
-
-from aria.utils.collections import FrozenList
-from aria.utils.formatting import as_raw, safe_repr
-from aria.parser import dsl_specification
-from aria.parser.exceptions import InvalidValueError
-from aria.parser.validation import Issue
-from aria.modeling.exceptions import CannotEvaluateFunctionException
-from aria.modeling.functions import Function
-
-#
-# Intrinsic
-#
-
-@dsl_specification('4.3.1', 'tosca-simple-1.0')
-class Concat(Function):
- """
- The :code:`concat` function is used to concatenate two or more string values within a TOSCA
- service template.
- """
-
- def __init__(self, context, presentation, argument):
- self.locator = presentation._locator
-
- if not isinstance(argument, list):
- raise InvalidValueError(
- 'function "concat" argument must be a list of string expressions: %s'
- % safe_repr(argument),
- locator=self.locator)
-
- string_expressions = []
- for index, an_argument in enumerate(argument):
- string_expressions.append(parse_string_expression(context, presentation, 'concat',
- index, None, an_argument))
- self.string_expressions = FrozenList(string_expressions)
-
- @property
- def as_raw(self):
- string_expressions = []
- for string_expression in self.string_expressions:
- if hasattr(string_expression, 'as_raw'):
- string_expression = as_raw(string_expression)
- string_expressions.append(string_expression)
- return {'concat': string_expressions}
-
- def _evaluate(self, context, container):
- value = StringIO()
- for e in self.string_expressions:
- if hasattr(e, '_evaluate'):
- e = e._evaluate(context, container)
- value.write(str(e))
- return value.getvalue()
-
-@dsl_specification('4.3.2', 'tosca-simple-1.0')
-class Token(Function):
- """
- The :code:`token` function is used within a TOSCA service template on a string to parse out
- (tokenize) substrings separated by one or more token characters within a larger string.
- """
-
- def __init__(self, context, presentation, argument):
- self.locator = presentation._locator
-
- if (not isinstance(argument, list)) or (len(argument) != 3):
- raise InvalidValueError('function "token" argument must be a list of 3 parameters: %s'
- % safe_repr(argument),
- locator=self.locator)
-
- self.string_with_tokens = parse_string_expression(context, presentation, 'token', 0,
- 'the string to tokenize', argument[0])
- self.string_of_token_chars = parse_string_expression(context, presentation, 'token', 1,
- 'the token separator characters',
- argument[1])
- self.substring_index = parse_int(context, presentation, 'token', 2,
- 'the 0-based index of the token to return', argument[2])
-
- @property
- def as_raw(self):
- string_with_tokens = self.string_with_tokens
- if hasattr(string_with_tokens, 'as_raw'):
- string_with_tokens = as_raw(string_with_tokens)
- string_of_token_chars = self.string_with_tokens
- if hasattr(string_of_token_chars, 'as_raw'):
- string_of_token_chars = as_raw(string_of_token_chars)
- return {'token': [string_with_tokens, string_of_token_chars, self.substring_index]}
-
- def _evaluate(self, context, container):
- string_with_tokens = self.string_with_tokens
- if hasattr(string_with_tokens, '_evaluate'):
- string_with_tokens = string_with_tokens._evaluate(context, container) # pylint: disable=no-member
-
-#
-# Property
-#
-
-@dsl_specification('4.4.1', 'tosca-simple-1.0')
-class GetInput(Function):
- """
- The :code:`get_input` function is used to retrieve the values of properties declared within the
- inputs section of a TOSCA Service Template.
- """
-
- def __init__(self, context, presentation, argument):
- self.locator = presentation._locator
-
- self.input_property_name = parse_string_expression(context, presentation, 'get_input',
- None, 'the input property name',
- argument)
-
- if isinstance(self.input_property_name, basestring):
- the_input = context.presentation.get_from_dict('service_template', 'topology_template',
- 'inputs', self.input_property_name)
- if the_input is None:
- raise InvalidValueError(
- 'function "get_input" argument is not a valid input name: %s'
- % safe_repr(argument),
- locator=self.locator)
-
- @property
- def as_raw(self):
- return {'get_input': as_raw(self.input_property_name)}
-
- def _evaluate(self, context, container): # pylint: disable=unused-argument
- if not context.modeling.instance:
- raise CannotEvaluateFunctionException()
- the_input = context.modeling.instance.inputs.get(
- self.input_property_name,
- context.modeling.template.inputs.get(self.input_property_name))
- return as_raw(the_input.value) if the_input is not None else None
-
-@dsl_specification('4.4.2', 'tosca-simple-1.0')
-class GetProperty(Function):
- """
- The :code:`get_property` function is used to retrieve property values between modelable entities
- defined in the same service template.
- """
-
- def __init__(self, context, presentation, argument):
- self.locator = presentation._locator
-
- if (not isinstance(argument, list)) or (len(argument) < 2):
- raise InvalidValueError(
- 'function "get_property" argument must be a list of at least 2 string expressions: '
- '%s'
- % safe_repr(argument),
- locator=self.locator)
-
- self.modelable_entity_name = parse_modelable_entity_name(context, presentation,
- 'get_property', 0, argument[0])
- # The first of these will be tried as a req-or-cap name:
- self.nested_property_name_or_index = argument[1:]
-
- @property
- def as_raw(self):
- return {'get_property': [self.modelable_entity_name] + self.nested_property_name_or_index}
-
- def _evaluate(self, context, container):
- modelable_entities = get_modelable_entities(context, container, self.locator,
- self.modelable_entity_name)
- req_or_cap_name = self.nested_property_name_or_index[0]
-
- for modelable_entity in modelable_entities:
- properties = None
-
- if hasattr(modelable_entity, 'requirement_templates') \
- and modelable_entity.requirement_templates \
- and (req_or_cap_name in [v.name for v in modelable_entity.requirement_templates]):
- for requirement_template in modelable_entity.requirement_templates:
- if requirement_template.name == req_or_cap_name:
- # First argument refers to a requirement
- # TODO: should follow to matched capability in other node...
- raise CannotEvaluateFunctionException()
- break
- nested_property_name_or_index = self.nested_property_name_or_index[1:]
- elif hasattr(modelable_entity, 'capability_templates') \
- and modelable_entity.capability_templates \
- and (req_or_cap_name in modelable_entity.capability_templates):
- # First argument refers to a capability
- properties = modelable_entity.capability_templates[req_or_cap_name].properties
- nested_property_name_or_index = self.nested_property_name_or_index[1:]
- else:
- properties = modelable_entity.properties
- nested_property_name_or_index = self.nested_property_name_or_index
-
- if properties:
- found = True
- value = properties
- for name in nested_property_name_or_index:
- if (isinstance(value, dict) and (name in value)) \
- or (isinstance(value, list) and name < len(list)):
- value = value[name]
- if hasattr(value, '_evaluate'):
- value = value._evaluate(context, modelable_entity)
- else:
- found = False
- break
- if found:
- return as_raw(value)
-
- raise InvalidValueError(
- 'function "get_property" could not find "%s" in modelable entity "%s"' \
- % ('.'.join(self.nested_property_name_or_index), self.modelable_entity_name),
- locator=self.locator)
-
-#
-# Attribute
-#
-
-@dsl_specification('4.5.1', 'tosca-simple-1.0')
-class GetAttribute(Function):
- """
- The :code:`get_attribute` function is used to retrieve the values of named attributes declared
- by the referenced node or relationship template name.
- """
-
- def __init__(self, context, presentation, argument):
- self.locator = presentation._locator
-
- if (not isinstance(argument, list)) or (len(argument) < 2):
- raise InvalidValueError(
- 'function "get_attribute" argument must be a list of at least 2 string expressions:'
- ' %s'
- % safe_repr(argument),
- locator=self.locator)
-
- self.modelable_entity_name = parse_modelable_entity_name(context, presentation,
- 'get_attribute', 0, argument[0])
- # The first of these will be tried as a req-or-cap name:
- self.nested_property_name_or_index = argument[1:]
-
- @property
- def as_raw(self):
- return {'get_attribute': [self.modelable_entity_name] + self.nested_property_name_or_index}
-
- def _evaluate(self, context, container): # pylint: disable=no-self-use,unused-argument
- raise CannotEvaluateFunctionException()
-
-#
-# Operation
-#
-
-@dsl_specification('4.6.1', 'tosca-simple-1.0')
-class GetOperationOutput(Function):
- """
- The :code:`get_operation_output` function is used to retrieve the values of variables exposed /
- exported from an interface operation.
- """
-
- def __init__(self, context, presentation, argument):
- self.locator = presentation._locator
-
- if (not isinstance(argument, list)) or (len(argument) != 4):
- raise InvalidValueError(
- 'function "get_operation_output" argument must be a list of 4 parameters: %s'
- % safe_repr(argument),
- locator=self.locator)
-
- self.modelable_entity_name = parse_string_expression(context, presentation,
- 'get_operation_output', 0,
- 'modelable entity name', argument[0])
- self.interface_name = parse_string_expression(context, presentation, 'get_operation_output',
- 1, 'the interface name', argument[1])
- self.operation_name = parse_string_expression(context, presentation, 'get_operation_output',
- 2, 'the operation name', argument[2])
- self.output_variable_name = parse_string_expression(context, presentation,
- 'get_operation_output', 3,
- 'the output name', argument[3])
-
- @property
- def as_raw(self):
- interface_name = self.interface_name
- if hasattr(interface_name, 'as_raw'):
- interface_name = as_raw(interface_name)
- operation_name = self.operation_name
- if hasattr(operation_name, 'as_raw'):
- operation_name = as_raw(operation_name)
- output_variable_name = self.output_variable_name
- if hasattr(output_variable_name, 'as_raw'):
- output_variable_name = as_raw(output_variable_name)
- return {'get_operation_output': [self.modelable_entity_name, interface_name, operation_name,
- output_variable_name]}
-
-#
-# Navigation
-#
-
-@dsl_specification('4.7.1', 'tosca-simple-1.0')
-class GetNodesOfType(Function):
- """
- The :code:`get_nodes_of_type` function can be used to retrieve a list of all known instances of
- nodes of the declared Node Type.
- """
-
- def __init__(self, context, presentation, argument):
- self.locator = presentation._locator
-
- self.node_type_name = parse_string_expression(context, presentation, 'get_nodes_of_type',
- None, 'the node type name', argument)
-
- if isinstance(self.node_type_name, basestring):
- node_types = context.presentation.get('service_template', 'node_types')
- if (node_types is None) or (self.node_type_name not in node_types):
- raise InvalidValueError(
- 'function "get_nodes_of_type" argument is not a valid node type name: %s'
- % safe_repr(argument),
- locator=self.locator)
-
- @property
- def as_raw(self):
- node_type_name = self.node_type_name
- if hasattr(node_type_name, 'as_raw'):
- node_type_name = as_raw(node_type_name)
- return {'get_nodes_of_type': node_type_name}
-
- def _evaluate(self, context, container):
- pass
-
-#
-# Artifact
-#
-
-@dsl_specification('4.8.1', 'tosca-simple-1.0')
-class GetArtifact(Function):
- """
- The :code:`get_artifact` function is used to retrieve artifact location between modelable
- entities defined in the same service template.
- """
-
- def __init__(self, context, presentation, argument):
- self.locator = presentation._locator
-
- if (not isinstance(argument, list)) or (len(argument) < 2) or (len(argument) > 4):
- raise InvalidValueError(
- 'function "get_artifact" argument must be a list of 2 to 4 parameters: %s'
- % safe_repr(argument),
- locator=self.locator)
-
- self.modelable_entity_name = parse_string_expression(context, presentation, 'get_artifact',
- 0, 'modelable entity name',
- argument[0])
- self.artifact_name = parse_string_expression(context, presentation, 'get_artifact', 1,
- 'the artifact name', argument[1])
- self.location = parse_string_expression(context, presentation, 'get_artifact', 2,
- 'the location or "LOCAL_FILE"', argument[2])
- self.remove = parse_bool(context, presentation, 'get_artifact', 3, 'the removal flag',
- argument[3])
-
- @property
- def as_raw(self):
- artifact_name = self.artifact_name
- if hasattr(artifact_name, 'as_raw'):
- artifact_name = as_raw(artifact_name)
- location = self.location
- if hasattr(location, 'as_raw'):
- location = as_raw(location)
- return {'get_artifacts': [self.modelable_entity_name, artifact_name, location, self.remove]}
-
-#
-# Utils
-#
-
-def get_function(context, presentation, value):
- functions = context.presentation.presenter.functions
- if isinstance(value, dict) and (len(value) == 1):
- key = value.keys()[0]
- if key in functions:
- try:
- return True, functions[key](context, presentation, value[key])
- except InvalidValueError as e:
- context.validation.report(issue=e.issue)
- return True, None
- return False, None
-
-def parse_string_expression(context, presentation, name, index, explanation, value): # pylint: disable=unused-argument
- is_function, func = get_function(context, presentation, value)
- if is_function:
- return func
- else:
- value = str(value)
- return value
-
-def parse_int(context, presentation, name, index, explanation, value): # pylint: disable=unused-argument
- if not isinstance(value, int):
- try:
- value = int(value)
- except ValueError:
- raise invalid_value(name, index, 'an integer', explanation, value,
- presentation._locator)
- return value
-
-def parse_bool(context, presentation, name, index, explanation, value): # pylint: disable=unused-argument
- if not isinstance(value, bool):
- raise invalid_value(name, index, 'a boolean', explanation, value, presentation._locator)
- return value
-
-def parse_modelable_entity_name(context, presentation, name, index, value):
- value = parse_string_expression(context, presentation, name, index, 'the modelable entity name',
- value)
- if value == 'SELF':
- the_self, _ = parse_self(presentation)
- if the_self is None:
- raise invalid_modelable_entity_name(name, index, value, presentation._locator,
- 'a node template or a relationship template')
- elif value == 'HOST':
- _, self_variant = parse_self(presentation)
- if self_variant != 'node_template':
- raise invalid_modelable_entity_name(name, index, value, presentation._locator,
- 'a node template')
- elif (value == 'SOURCE') or (value == 'TARGET'):
- _, self_variant = parse_self(presentation)
- if self_variant != 'relationship_template':
- raise invalid_modelable_entity_name(name, index, value, presentation._locator,
- 'a relationship template')
- elif isinstance(value, basestring):
- node_templates = \
- context.presentation.get('service_template', 'topology_template', 'node_templates') \
- or {}
- relationship_templates = \
- context.presentation.get('service_template', 'topology_template',
- 'relationship_templates') \
- or {}
- if (value not in node_templates) and (value not in relationship_templates):
- raise InvalidValueError(
- 'function "%s" parameter %d is not a valid modelable entity name: %s'
- % (name, index + 1, safe_repr(value)),
- locator=presentation._locator, level=Issue.BETWEEN_TYPES)
- return value
-
-def parse_self(presentation):
- from .templates import NodeTemplate, RelationshipTemplate
- from .types import NodeType, RelationshipType
-
- if presentation is None:
- return None, None
- elif isinstance(presentation, NodeTemplate) or isinstance(presentation, NodeType):
- return presentation, 'node_template'
- elif isinstance(presentation, RelationshipTemplate) \
- or isinstance(presentation, RelationshipType):
- return presentation, 'relationship_template'
- else:
- return parse_self(presentation._container)
-
-@dsl_specification('4.1', 'tosca-simple-1.0')
-def get_modelable_entities(context, container, locator, modelable_entity_name):
- """
- The following keywords MAY be used in some TOSCA function in place of a TOSCA Node or
- Relationship Template name.
- """
-
- if modelable_entity_name == 'SELF':
- return get_self(context, container)
- elif modelable_entity_name == 'HOST':
- return get_host(context, container)
- elif modelable_entity_name == 'SOURCE':
- return get_source(context, container)
- elif modelable_entity_name == 'TARGET':
- return get_target(context, container)
- elif isinstance(modelable_entity_name, basestring):
- node_templates = \
- context.presentation.get('service_template', 'topology_template', 'node_templates') \
- or {}
- if modelable_entity_name in node_templates:
- return [node_templates[modelable_entity_name]]
- relationship_templates = \
- context.presentation.get('service_template', 'topology_template',
- 'relationship_templates') \
- or {}
- if modelable_entity_name in relationship_templates:
- return [relationship_templates[modelable_entity_name]]
-
- raise InvalidValueError('function "get_property" could not find modelable entity "%s"'
- % modelable_entity_name,
- locator=locator)
-
-def get_self(context, container): # pylint: disable=unused-argument
- """
- A TOSCA orchestrator will interpret this keyword as the Node or Relationship Template instance
- that contains the function at the time the function is evaluated.
- """
-
- return [container]
-
-def get_host(context, container): # pylint: disable=unused-argument
- """
- A TOSCA orchestrator will interpret this keyword to refer to the all nodes that "host" the node
- using this reference (i.e., as identified by its HostedOn relationship).
-
- Specifically, TOSCA orchestrators that encounter this keyword when evaluating the get_attribute
- or :code:`get_property` functions SHALL search each node along the "HostedOn" relationship chain
- starting at the immediate node that hosts the node where the function was evaluated (and then
- that node's host node, and so forth) until a match is found or the "HostedOn" relationship chain
- ends.
- """
-
- return []
-
-def get_source(context, container): # pylint: disable=unused-argument
- """
- A TOSCA orchestrator will interpret this keyword as the Node Template instance that is at the
- source end of the relationship that contains the referencing function.
- """
-
- return []
-
-def get_target(context, container): # pylint: disable=unused-argument
- """
- A TOSCA orchestrator will interpret this keyword as the Node Template instance that is at the
- target end of the relationship that contains the referencing function.
- """
-
-def invalid_modelable_entity_name(name, index, value, locator, contexts):
- return InvalidValueError('function "%s" parameter %d can be "%s" only in %s'
- % (name, index + 1, value, contexts),
- locator=locator, level=Issue.FIELD)
-
-def invalid_value(name, index, the_type, explanation, value, locator):
- return InvalidValueError(
- 'function "%s" %s is not %s%s: %s'
- % (name, ('parameter %d' % (index + 1)) if index is not None else 'argument',
- the_type, (', %s' % explanation) if explanation is not None else '', safe_repr(value)),
- locator=locator, level=Issue.FIELD)