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]
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
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
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
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])
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
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)