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( u'function "get_artifact" argument must be a list of 2 to 4 parameters: {0}' .format(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]) if len(argument) > 2: self.location = parse_string_expression( context, presentation, 'get_artifact', 2, 'the location or "LOCAL_FILE"', argument[2]) else: self.location = None if len(argument) > 3: self.remove = parse_bool(context, presentation, 'get_artifact', 3, 'the removal flag', argument[3]) else: self.remove = None
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_hosts(container_holder, name, locator): """ 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 ``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. """ container = container_holder.container if (not isinstance(container, Node)) and (not isinstance( container, NodeTemplate)): raise InvalidValueError( 'function "{0}" refers to "HOST" but it is not contained in ' 'a node: {1}'.format(name, full_type_name(container)), locator=locator) if not isinstance(container, Node): # NodeTemplate does not have "host"; we'll wait until instantiation raise CannotEvaluateFunctionException() host = container.host if host is None: # We might have a host later raise CannotEvaluateFunctionException() return [host]
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 "{0}" parameter {1:d} is not a valid modelable entity name: {2}' .format(name, index + 1, safe_repr(value)), locator=presentation._locator, level=Issue.BETWEEN_TYPES) return value
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)
def invalid_value(name, index, the_type, explanation, value, locator): return InvalidValueError('function "{0}" {1} is not {2}{3}: {4}'.format( name, 'parameter {0:d}'.format(index + 1) if index is not None else 'argument', the_type, ', {0}'.format(explanation) if explanation is not None else '', safe_repr(value)), locator=locator, level=Issue.FIELD)
def getter(field, presentation, context=None): raw = field.default_get(presentation, context) if raw is not None: try: return cls(None, None, raw, None) except ValueError as e: raise InvalidValueError('%s is not a valid "%s" in "%s": %s' % (field.full_name, field.full_cls_name, presentation._name, safe_repr(raw)), cause=e, locator=field.get_locator(raw))
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: {0}' .format(safe_repr(argument)), locator=self.locator)
def getter(field, presentation, context=None): raw = field.default_get(presentation, context) if (raw is None) or (allow_null and (raw is NULL)): return raw try: return cls(None, None, raw, None) except ValueError as e: raise InvalidValueError( u'{0} is not a valid "{1}" in "{2}": {3}'.format( field.full_name, full_type_name(cls), presentation._name, safe_repr(raw)), cause=e, locator=field.get_locator(raw))
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:' ' {0}'.format(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_attribute_name_or_index = argument[1:]
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: {0}' .format(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)
def __evaluate__(self, container_holder): service = container_holder.service if service is None: raise CannotEvaluateFunctionException() value = service.inputs.get(self.input_property_name) if value is not None: value = value.value return Evaluation(value, False) # We never return final evaluations! raise InvalidValueError( 'function "get_input" argument is not a valid input name: {0}' .format(safe_repr(self.input_property_name)), locator=self.locator)
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: {0}' .format(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])
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: {0}' .format(safe_repr(argument)), locator=self.locator)
def check_if_input_value_is_valid(context, presentation, input_value): check_input_property = _get_input(context, input_value) substitution_node_type = presentation._container._get_type(context) if check_input_property is None: context.validation.report( u'field {0} is not a valid input name referred in substitution mapping property ' u'in node type "{substitution_type}"'.format( input_value, substitution_type=substitution_node_type._name), locator=presentation._locator, level=Issue.BETWEEN_TYPES) raise InvalidValueError( u'function "get_input" argument does not contain a valid input name: {0} in substitution_mappings section' .format(safe_repr(input_value), locator=presentation._locator))
def __evaluate__(self, container_holder): modelable_entities = get_modelable_entities(container_holder, 'get_property', 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 # First argument refers to a requirement template? 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 in modelable_entity.requirement_templates: if requirement.name == req_or_cap_name: # TODO raise CannotEvaluateFunctionException() # First argument refers to a capability? elif hasattr(modelable_entity, 'capabilities') \ and modelable_entity.capabilities \ and (req_or_cap_name in modelable_entity.capabilities): properties = modelable_entity.capabilities[ req_or_cap_name].properties nested_property_name_or_index = self.nested_property_name_or_index[ 1:] # First argument refers to a capability template? elif hasattr(modelable_entity, 'capability_templates') \ and modelable_entity.capability_templates \ and (req_or_cap_name in modelable_entity.capability_templates): 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 evaluation = get_modelable_entity_parameter( properties, nested_property_name_or_index) if evaluation is not None: return evaluation raise InvalidValueError( u'function "get_property" could not find "{0}" in modelable entity "{1}"' .format(u'.'.join(self.nested_property_name_or_index), self.modelable_entity_name), locator=self.locator)
def __evaluate__(self, container_holder): modelable_entities = get_modelable_entities(container_holder, 'get_attribute', self.locator, self.modelable_entity_name) for modelable_entity in modelable_entities: attributes = modelable_entity.attributes nested_attribute_name_or_index = self.nested_attribute_name_or_index evaluation = get_modelable_entity_parameter(modelable_entity, attributes, nested_attribute_name_or_index) if evaluation is not None: evaluation.final = False # We never return final evaluations! return evaluation raise InvalidValueError( 'function "get_attribute" could not find "{0}" in modelable entity "{1}"' .format('.'.join(self.nested_attribute_name_or_index), self.modelable_entity_name), locator=self.locator)
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: if hasattr(modelable_entity, 'requirement_templates') \ and modelable_entity.requirement_templates \ and (req_or_cap_name in modelable_entity.requirement_templates): # First argument refers to a requirement properties = modelable_entity.requirement_templates[ req_or_cap_name].properties 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 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)
def get_self(container_holder, name, locator): """ 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. """ container = container_holder.container if (not isinstance(container, Node)) and \ (not isinstance(container, NodeTemplate)) and \ (not isinstance(container, Relationship)) and \ (not isinstance(container, RelationshipTemplate)): raise InvalidValueError('function "{0}" refers to "SELF" but it is not contained in ' 'a node or a relationship: {1}'.format(name, full_type_name(container)), locator=locator) return [container]
def get_target(container_holder, name, locator): """ 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. """ container = container_holder.container if (not isinstance(container, Relationship)) and \ (not isinstance(container, RelationshipTemplate)): raise InvalidValueError('function "{0}" refers to "TARGET" but it is not contained in ' 'a relationship: {1}'.format(name, full_type_name(container)), locator=locator) if not isinstance(container, RelationshipTemplate): # RelationshipTemplate does not have "target_node"; we'll wait until instantiation raise CannotEvaluateFunctionException() return [container.target_node]
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: {0}' .format(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])
def get_modelable_entities(container_holder, name, 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(container_holder, name, locator) elif modelable_entity_name == 'HOST': return get_hosts(container_holder, name, locator) elif modelable_entity_name == 'SOURCE': return get_source(container_holder, name, locator) elif modelable_entity_name == 'TARGET': return get_target(container_holder, name, locator) elif isinstance(modelable_entity_name, basestring): modelable_entities = [] service = container_holder.service if service is not None: for node in service.nodes.itervalues(): if node.node_template.name == modelable_entity_name: modelable_entities.append(node) else: service_template = container_holder.service_template if service_template is not None: for node_template in service_template.node_templates.itervalues( ): if node_template.name == modelable_entity_name: modelable_entities.append(node_template) if not modelable_entities: raise CannotEvaluateFunctionException() return modelable_entities raise InvalidValueError( 'function "{0}" could not find modelable entity "{1}"'.format( name, modelable_entity_name), locator=locator)
def invalid_modelable_entity_name(name, index, value, locator, contexts): return InvalidValueError( 'function "{0}" parameter {1:d} can be "{2}" only in {3}'.format( name, index + 1, value, contexts), locator=locator, level=Issue.FIELD)
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)