def _parse_implementation(context, implementation): plugins = [] for plugin in context.modeling.plugins: if implementation.startswith(plugin['name'] + '.'): plugins.append(plugin) length = len(plugins) if length > 1: raise InvalidValueError('ambiguous plugin name in implementation: %s' % safe_repr(implementation), level=Issue.BETWEEN_TYPES) elif length == 1: plugin = plugins[0] operation = implementation[len(plugin['name']) + 1:] if not operation: raise InvalidValueError('no operation name in implementation: %s' % safe_repr(implementation), level=Issue.BETWEEN_TYPES) return plugin, operation elif context.modeling.plugins: plugin = context.modeling.plugins[0] return plugin, implementation raise InvalidValueError('unknown plugin for implementation: %s' % safe_repr(implementation), level=Issue.BETWEEN_TYPES)
def get_property(value, nested_property_name_or_index, function_name): for name_or_index in nested_property_name_or_index: try: value = value[name_or_index] except KeyError as e: raise InvalidValueError( 'function "%s" refers to an unknown nested property name: %s' % (function_name, safe_repr(name_or_index)), cause=e) except IndexError as e: raise InvalidValueError( 'function "%s" refers to an unknown nested index: %s' % (function_name, safe_repr(name_or_index)), cause=e) return value
def convert_group_template(context, group_template, policy_template=None): # Members node_members = set(group_template.member_node_template_names) group_members = set(group_template.member_group_template_names) prune_redundant_members(context, node_members, group_members) members = list(node_members | group_members) if not members: raise InvalidValueError('group "%s" has no members' % group_template.name, level=Issue.BETWEEN_TYPES) r = OrderedDict( (('members', members), ('policies', OrderedDict( (k, convert_group_policy(context, v)) for k, v in group_template.policy_templates.iteritems())))) # For scaling groups if policy_template is not None: r['properties'] = convert_properties(context, policy_template.properties) return r
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 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 get_node(context, modelable_entity_name, function_name): node = None def get_node(node_id): try: return context.get_node(node_id) except Exception as e: raise InvalidValueError( 'function "%s" refers to an unknown node: %s' % (function_name, safe_repr(node_id)), cause=e) if modelable_entity_name == 'SELF': node = get_node(context.self_node_id) elif modelable_entity_name == 'SOURCE': node = get_node(context.source_node_id) elif modelable_entity_name == 'TARGET': node = get_node(context.target_node_id) else: try: nodes = context.get_nodes(modelable_entity_name) node = nodes[0] except Exception as e: raise InvalidValueError( 'function "%s" refers to an unknown modelable entity: %s' % (function_name, safe_repr(modelable_entity_name)), cause=e) node_template = context.get_node_template(node['node_id']) return node, node_template
def get_node(node_id): try: return context.get_node(node_id) except Exception as e: raise InvalidValueError( 'function "%s" refers to an unknown node: %s' % (function_name, safe_repr(node_id)), cause=e)
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 evaluate(self, context): inputs = context.deployment_plan['inputs'] if self.input_property_name not in inputs: raise InvalidValueError( 'input does not exist for function "get_input": %s' % safe_repr(self.input_property_name), locator=self.locator) the_input = inputs[self.input_property_name] value = the_input.get('value', the_input.get('default')) return deepcopy_with_locators(value)
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 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:]
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 n in nested_property_name_or_index: if (isinstance(value, dict) and (n in value)) or (isinstance(value, list) and n < len(list)): value = value[n] 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 __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)
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)
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)
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])
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])
def convert_operation(context, operation): plugin_name, plugin_executor, operation_name, inputs = parse_implementation( context, operation.implementation) inputs = merge(inputs, convert_inputs(context, operation.inputs)) if plugin_name == SCRIPT_PLUGIN_NAME: script_path = inputs.get('script_path') if script_path and (not is_file(context, script_path)): raise InvalidValueError( '"script_path" input for "script" plugin does not refer to a file: %s' % safe_repr(script_path), level=Issue.BETWEEN_TYPES) return OrderedDict( (('plugin', plugin_name), ('operation', operation_name), ('inputs', inputs), ('has_intrinsic_functions', has_intrinsic_functions(context, operation.inputs)), ('executor', operation.executor or plugin_executor), ('max_retries', operation.max_retries), ('retry_interval', operation.retry_interval)))
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])
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 convert_node_template(context, node_template): node_type = context.modeling.node_types.get_descendant( node_template.type_name) # Host host_node_template = find_host_node_template(context, node_template) is_a_host = is_host(context, node_template) # Count instances current_instances = 0 for node in context.modeling.instance.nodes.itervalues(): if node.template_name == node_template.name: current_instances += 1 # Plugins to install plugins_to_install = [] deployment_plugins_to_install = [] add_plugins_to_install_for_node_template(context, node_template, plugins_to_install, deployment_plugins_to_install) if plugins_to_install and not is_a_host: raise InvalidValueError( 'node template "%s" has plugins to install but is not a host: %s' % (node_template.name, string_list_as_string(v['name'] for v in plugins_to_install)), level=Issue.BETWEEN_TYPES) # Relationships relationships = [] contained_in = 0 for requirement in node_template.requirement_templates: if requirement.relationship_template is not None: if is_contained_in(context, requirement.relationship_template): contained_in += 1 relationships.append( convert_relationship_template(context, requirement)) if contained_in > 1: raise InvalidValueError( 'node template "%s" has more than one contained-in relationship' % node_template.name, level=Issue.BETWEEN_TYPES) for relationship in relationships: if relationship['target_id'] == node_template.name: raise InvalidValueError( 'node template "%s" has a "%s" relationship to itself' % (node_template.name, relationship['type']), level=Issue.BETWEEN_TYPES) r = OrderedDict( (('name', node_template.name), ('id', node_template.name), ('type', node_type.name), ('type_hierarchy', convert_type_hierarchy(context, node_type, context.modeling.node_types)), ('properties', convert_properties(context, node_template.properties)), ('capabilities', OrderedDict( (('scalable', OrderedDict( (('properties', OrderedDict( (('current_instances', current_instances), ('default_instances', node_template.default_instances), ('min_instances', node_template.min_instances), ('max_instances', node_template.max_instances if node_template.max_instances is not None else -1)))), ))), ))), ('operations', convert_operations(context, node_template.interface_templates)), ('relationships', relationships), ('host_id', host_node_template.name if host_node_template is not None else None), ('plugins', context.modeling.plugins), ('plugins_to_install', plugins_to_install), ('deployment_plugins_to_install', deployment_plugins_to_install))) # Prune some fields if host_node_template is None: del r['host_id'] if not is_a_host: del r['plugins_to_install'] return r
def _find_plugin(context, name): for plugin in context.modeling.plugins: if plugin['name'] == name: return plugin raise InvalidValueError('can\'t find plugin: %s' % safe_repr(name), level=Issue.BETWEEN_TYPES)