Beispiel #1
0
    def resolve_in_template_dependencies(self):
        """
        TODO think through the logic to replace mentions by id
        Changes all mentions of node_templates by name in requirements, places dictionary with node_filter instead
        :return:
        """
        for node in self.node_templates:
            for req in node.requirements:
                for k, v in req.items():
                    if type(v) is str:
                        # The case when the requirement is a name of node or relationship template

                        # Store the dependencies of nodes
                        self.add_template_dependency(node.name, v)

                        nodetemplate = node.templates.get(v)
                        node_filter = dict()
                        properties = nodetemplate.get(PROPERTIES)
                        props_list = []
                        if properties:
                            for prop_name, prop in properties.items():
                                props_list.append({prop_name: prop})
                        capabilities = nodetemplate.get(CAPABILITIES)
                        caps_list = []
                        if capabilities:
                            for cap_name, cap in capabilities.items():
                                cap_props = cap.get(PROPERTIES, {})
                                cap_props_list = []
                                for prop_name, prop in cap_props.items():
                                    cap_props_list.append({prop_name, prop})
                                caps_list.append({PROPERTIES: cap_props_list})

                        if properties:
                            node_filter[PROPERTIES] = props_list
                        if capabilities:
                            node_filter[CAPABILITIES] = caps_list
                        req[k] = dict(node_filter=node_filter)
                    else:
                        # The case when requirement has parameters.
                        # Valid keys are ('node', 'node_filter', 'relationship', 'capability', 'occurrences')
                        # Only node and relationship might be a template name or a type
                        req_relationship = req[k].get(RELATIONSHIP)
                        req_node = req[k].get(NODE)

                        if req_relationship is not None:
                            _, _, type_name = tosca_type.parse(
                                req_relationship)
                            if type_name is None:
                                self.add_template_dependency(
                                    node.name, req_relationship)

                        if req_node is not None:
                            _, _, type_name = tosca_type.parse(req_node)
                            if type_name is None:
                                self.add_template_dependency(
                                    node.name, req_node)
def translate(tosca_elements_map_to_provider, topology_template):
    """
    Main function of this file, the only which is used outside the file
    :param tosca_elements_map_to_provider: dict from provider specific file
    tosca_elements_map_to_<provider>.yaml
    :param node_templates: input node_templates
    :return: list of new node templates and relationship templates and
    list of artifacts to be used for generating scripts
    """
    node_templates = topology_template.nodetemplates
    relationship_templates = topology_template.relationship_templates
    element_templates = node_templates + relationship_templates

    new_element_templates = {}
    artifacts = []
    conditions = []
    extra = dict()
    self = {}
    self[ARTIFACTS] = []
    self[EXTRA] = dict()

    for element in element_templates:
        (namespace, _, _) = tosca_type.parse(element.type)
        self[NAME] = element.name
        self[KEYNAME] = element.name

        if namespace == TOSCA:
            restructured_mapping = restructure_mapping(
                tosca_elements_map_to_provider, element, self)

            restructured_mapping, extra_mappings, conditions = restructure_mapping_facts(
                restructured_mapping)
            restructured_mapping.extend(extra_mappings)

            tpl_structure = translate_node_from_tosca(restructured_mapping,
                                                      element.name, self)
            for tpl_name, temp_tpl in tpl_structure.items():
                for node_type, tpl in temp_tpl.items():
                    (_, element_type, _) = tosca_type.parse(node_type)
                    tpl[TYPE] = node_type
                    new_element_templates[
                        element_type] = new_element_templates.get(
                            element_type, {})
                    new_element_templates[element_type].update(
                        {tpl_name: copy.deepcopy(tpl)})
        else:
            new_element = translate_element_from_provider(element)
            new_element_templates = deep_update_dict(new_element_templates,
                                                     new_element)

        conditions = set(conditions)

    return new_element_templates, self[ARTIFACTS], conditions, self[EXTRA]
Beispiel #3
0
    def translate_to_provider(self):
        new_element_templates, new_artifacts, conditions_set, new_extra = translate_to_provider(
            self.tosca_elements_map_to_provider(),
            self.tosca_topology_template)

        self.used_conditions_set = conditions_set
        dict_tpl = copy.deepcopy(self.tosca_topology_template.tpl)
        if new_element_templates.get(NODES):
            dict_tpl[NODE_TEMPLATES] = new_element_templates[NODES]
        if new_element_templates.get(RELATIONSHIPS):
            dict_tpl[RELATIONSHIP_TEMPLATES] = new_element_templates[
                RELATIONSHIPS]

        rel_types = []
        for k, v in self.provider_defs.items():
            (_, element_type, _) = tosca_type.parse(k)
            if element_type == RELATIONSHIP_TYPES:
                rel_types.append(v)

        topology_tpl = TopologyTemplate(dict_tpl, self.full_provider_defs,
                                        rel_types)
        self.artifacts.extend(new_artifacts)
        self.extra_configuration_tool_params = deep_update_dict(
            self.extra_configuration_tool_params, new_extra)

        return topology_tpl
    def gather_global_operations(self, element_object):

        interfaces = []
        element_template_name = None
        (_, element_type, _) = tosca_type.parse(element_object.type)
        if element_type == NODES:
            interfaces = self.get_interfaces_from_node(element_object)
            element_template_name = element_object.name
            op_required = self.list_get_operation_outputs(
                element_object.nodetemplate.entity_tpl)
            self.manage_operation_output(op_required, element_template_name)
        elif element_type == RELATIONSHIPS:
            # NOTE interfaces can't be used as it contains the error ()
            interfaces = self.get_interfaces_from_relationship(element_object)
            element_template_name = element_object.name

        if not element_template_name:
            return

        operations = {}
        for interface_name, ops in interfaces.items():
            for operation_name, operation_data in ops.items():
                operations['_'.join([interface_name.lower(),
                                     operation_name])] = operation_data

        # Sort operations by dependency
        prev_len = len(operations) + 1
        required_operations = {}
        for op_name, op in operations.items():
            if isinstance(op, six.string_types):
                op = {IMPLEMENTATION: op}
            op_required = self.list_get_operation_outputs(op)
            required_operations[op_name] = op_required
            self.manage_operation_output(op_required, element_template_name)

        while len(operations) > 0 and prev_len > len(operations):
            ops_for_iter = copy.deepcopy(operations)
            prev_len = len(operations)
            for op_name, op in ops_for_iter.items():
                op_required = required_operations[op_name]
                if_executable_now = True
                for i in op_required:
                    if i[0] == SELF:
                        i[0] = element_template_name
                    temp_op_name = '_'.join(i[:3]).lower()
                    if temp_op_name not in self.global_operations_queue:
                        if_executable_now = False
                        break
                if if_executable_now:
                    temp_op_name = '_'.join([element_template_name,
                                             op_name]).lower()
                    self.global_operations_queue.append(temp_op_name)
                    updating_op_info = {temp_op_name: op}
                    utils.deep_update_dict(self.global_operations_info,
                                           updating_op_info)
                    operations.pop(op_name)

        if len(operations) > 0:
            ExceptionCollector.appendException(
                TemplateDependencyError(what=element_template_name))
def translate_element_from_provider(node):
    (_, element_type, _) = tosca_type.parse(node.type)
    node_templates = {
        element_type: {
            node.name: copy.deepcopy(node.entity_tpl)
        }
    }
    return node_templates
Beispiel #6
0
 def _provider_nodes(self):
     """
     Create a list of ProviderResource classes to represent a node in TOSCA
     :return: list of class objects inherited from ProviderResource
     """
     provider_nodes = list()
     for node in self.node_templates:
         (namespace, category, type_name) = tosca_type.parse(node.type)
         if namespace != self.provider or category != NODES:
             ExceptionCollector.appendException(
                 Exception('Unexpected values'))
         provider_node_instance = ProviderResource(
             self.provider, node, self.relationship_templates)
         provider_nodes.append(provider_node_instance)
     return provider_nodes
Beispiel #7
0
 def compute_node_priorities(self, node_type_definitions):
     """
     Use node type definitions to count priority of the node_type
     :param node_type_definitions: dict of node type definitions
     :return:
     """
     ProviderResource.MAX_NUM_PRIORITIES = 1
     node_priorities_by_type = {}
     for node_type_name, node_type_def in node_type_definitions.items():
         (namespace, element_type,
          type_short) = tosca_type.parse(node_type_name)
         if type_short != ROOT and element_type == NODES and namespace == self.provider:
             node_priorities_by_type[
                 node_type_name] = self.get_node_type_priority(
                     node_type_definitions, node_type_name)
     return node_priorities_by_type
def translate_node_from_tosca(restructured_mapping, tpl_name, self):
    """
    Translator from TOSCA definitions in provider definitions using rules from element_map_to_provider
    :param restructured_mapping: list of dicts(parameter, map, value)
    :param tpl_name: str
    :return: entity_tpl as dict
    """
    resulted_structure = {}

    for item in restructured_mapping:
        ExceptionCollector.start()
        self[PARAMETER] = item[PARAMETER]
        self[VALUE] = item[VALUE]
        mapped_param = restructure_value(mapping_value=item[MAP_KEY],
                                         self=self)
        ExceptionCollector.stop()
        if ExceptionCollector.exceptionsCaught():
            raise ValidationError(
                message='\nTranslating to provider failed: '.join(
                    ExceptionCollector.getExceptionsReport()))
        structures, keyname = get_structure_of_mapped_param(
            mapped_param, item[VALUE])

        for structure in structures:
            r = retrieve_node_templates(structure)
            for node_type, tpl in r.items():
                if not keyname:
                    (_, _, type_name) = tosca_type.parse(node_type)
                    if not type_name:
                        ExceptionCollector.appendException()
                    keyname = self[KEYNAME] + "_" + snake_case.convert(
                        type_name)
                node_tpl_with_name = {keyname: {node_type: tpl}}
                resulted_structure = deep_update_dict(resulted_structure,
                                                      node_tpl_with_name)

    for keyname, node in resulted_structure.items():
        for node_type, tpl in node.items():
            if tpl.get(REQUIREMENTS):
                reqs = []
                for req_name, req in tpl[REQUIREMENTS].items():
                    reqs.append({req_name: req})
                resulted_structure[keyname][node_type][REQUIREMENTS] = reqs
    return resulted_structure
Beispiel #9
0
    def __init__(self, requirement_definitions, provider):
        """
        Get the requirements of type list from requirement definitions
        :param requirement_definitions: list of requirement definitions with name added
        """
        self.provider = provider
        self.requirement_definitions = requirement_definitions
        self.requirement_names_of_type_list = set()
        self.node_name_by_requirement_name = dict()

        # NOTE generate the dictionary, where the keys are the name of requirement and
        # the values are the node_types of requirement
        for req_def in self.requirement_definitions:
            req_name = req_def[NAME]
            req_node = req_def.get(NODE)
            if req_node:
                (_, _, type_name) = tosca_type.parse(req_node)
                node_name = snake_case.convert(type_name)
                if node_name == 'root':
                    continue
                temp_req_val = self.node_name_by_requirement_name.get(req_name)
                if temp_req_val is None:
                    temp_req_val = node_name
                elif isinstance(temp_req_val, str):
                    temp_req_val = (temp_req_val, node_name)
                else:
                    temp_req_val = temp_req_val + (node_name)
                self.node_name_by_requirement_name[req_name] = temp_req_val

        # NOTE set the list required requirements and the list of multiple requirements (of type list)
        self.required_requirement_keys = set()
        for req_def in self.requirement_definitions:
            occurrences = req_def.get(OCCURRENCES)  # list
            min_ocs = occurrences[0]
            max_ocs = occurrences[1]
            if int(min_ocs) > 0:
                self.required_requirement_keys.add(req_def[NAME])
            if str(max_ocs) == 'UNBOUNDED':
                self.requirement_names_of_type_list.add(req_def[NAME])
            elif int(max_ocs) > 1:
                self.requirement_names_of_type_list.add(req_def[NAME])
Beispiel #10
0
    def get_node_type_priority(self, node_type_definitions, node_type_name):
        """

        :param node_type_definitions:
        :param node_type_name:
        :return:
        """
        (_, _, type_short) = tosca_type.parse(node_type_name)
        if type_short == ROOT:
            return 0
        requirement_definitions = node_type_definitions.get(
            node_type_name, {}).get(REQUIREMENTS, [])
        max_dependency_priority = 0
        for i in requirement_definitions:
            for k, v in i.items():
                req_node_type = v.get(NODE)
                if not req_node_type == ROOT and not req_node_type == node_type_name:
                    p = self.get_node_type_priority(node_type_definitions,
                                                    req_node_type)
                    if p > max_dependency_priority or max_dependency_priority == 0:
                        max_dependency_priority = p + 1
        if max_dependency_priority >= self.MAX_NUM_PRIORITIES:
            ProviderResource.MAX_NUM_PRIORITIES = max_dependency_priority + 1
        return max_dependency_priority
Beispiel #11
0
    def __init__(self, provider, node, relationship_templates):
        """

        :param node: class NodeTemplate from toscaparser
        :param relationship_templates: list of RelationshipTemplate from toscaparser
        """
        # NOTE: added as a parameter in toscatranslator.providers.common.tosca_template:ProviderToscaTemplate

        self.provider = provider
        self.nodetemplate = node
        self.name = node.name
        self.type = node.type
        (_, _, type_name) = tosca_type.parse(self.type)
        self.type_name = type_name
        # NOTE: filling the parameters from openstack definition to parse from input template
        node_type = node.type_definition  # toscaparser.elements.nodetype.NodeType
        self.definitions_by_name = None
        self.requirement_definitions = None
        self.set_definitions_by_name(node_type)
        self.attribute_keys = list(self.attribute_definitions_by_name().keys())
        self.property_keys = list(self.property_definitions_by_name().keys())
        self.requirement_keys = list(
            self.requirement_definitions_by_name().keys())
        self.artifact_keys = list(self.artifact_definitions_by_name().keys())
        self.capability_keys = list(
            self.capability_definitions_by_name().keys())
        self.relationship_templates = list()
        self.dependency_order = 0

        # NOTE: Get the parameters from template using provider definition
        self.configuration_args = dict()
        # NOTE: node is NodeTemplate instance
        for key in self.property_keys:
            value = node.get_property_value(key)
            if value is not None:
                self.configuration_args[key] = value

        for key in self.attribute_keys:
            value = node.entity_tpl.get(ATTRIBUTES, {}).get(key)
            if value is not None:
                self.configuration_args[key] = value

        capability_defs = self.capability_definitions_by_name()
        for cap_key, cap_def in capability_defs.items():
            properties = node.get_capabilities().get(cap_key)
            definition_property_keys = cap_def.get(PROPERTIES, {}).keys()
            if properties:
                for def_prop_key in definition_property_keys:
                    value = properties.get_property_value(def_prop_key)
                    if value:
                        self.configuration_args[def_prop_key] = value

        if hasattr(node, ARTIFACTS):
            # TODO: oneliner
            for key, value in node.artifacts:
                self.configuration_args[key] = value

        relationship_template_names = set()
        provider_requirements = ProviderRequirements(
            self.requirement_definitions, self.provider)
        self.requirements = provider_requirements.get_requirements(node)
        self.node_filter_artifacts = []
        for key, req in self.requirements.items():
            if type(req) is list:
                self.configuration_args[key] = list(v.get_value() for v in req)
                temp_req = req
            else:
                self.configuration_args[key] = req.get_value()
                temp_req = [req]
            for v in temp_req:
                relation = v.relationship
                if relation is not None:
                    _, _, type_name = tosca_type.parse(relation)
                    if type_name is None:
                        relationship_template_names.add(relation)

        for relation in relationship_templates:
            if relation.name in relationship_template_names:
                self.relationship_templates.append(relation)

        self.node_priority = self.compute_node_priorities(node.custom_def)