Example #1
0
 def find_path_from_referenced_vertices(
     referenced_vertices: List[VertexReference], vertex_attributes: Dict[str, Any]
 ) -> Tuple[List[str], str]:
     """
     :param referenced_vertices: an array of VertexReference
     :param vertex_attributes: attributes to search
     :return attribute_path: [] if referenced_vertices does not contain vertex_attributes,
                             else the path to the searched attribute: ['vpc_id']
     :return origin_value
     """
     for vertex_reference in referenced_vertices:
         block_type = vertex_reference.block_type.value
         attribute_path = vertex_reference.sub_parts
         copy_of_attribute_path = deepcopy(attribute_path)
         if vertex_attributes[CustomAttributes.BLOCK_TYPE] == block_type:
             for i in range(len(copy_of_attribute_path)):
                 copy_of_attribute_path[i] = remove_index_pattern_from_str(copy_of_attribute_path[i])
                 name = ".".join(copy_of_attribute_path[: i + 1])
                 if vertex_attributes[CustomAttributes.BLOCK_NAME] == name:
                     return attribute_path, vertex_reference.origin_value
         elif block_type == BlockType.MODULE:
             copy_of_attribute_path.reverse()
             for i in range(len(copy_of_attribute_path)):
                 copy_of_attribute_path[i] = remove_index_pattern_from_str(copy_of_attribute_path[i])
                 name = ".".join(copy_of_attribute_path[: i + 1])
                 if vertex_attributes[CustomAttributes.BLOCK_NAME] == name:
                     return name.split("."), vertex_reference.origin_value
     return [], ""
Example #2
0
    def _build_edges(self):
        logging.info('Creating edges')
        self.get_module_vertices_mapping()
        aliases = self._get_aliases()
        for origin_node_index, vertex in enumerate(self.vertices):
            for attribute_key in vertex.attributes:
                if attribute_key in reserved_attribute_names or attribute_has_nested_attributes(
                        attribute_key, vertex.attributes):
                    continue
                referenced_vertices = get_referenced_vertices_in_value(
                    value=vertex.attributes[attribute_key],
                    aliases=aliases,
                    resources_types=self.get_resources_types_in_graph())
                for vertex_reference in referenced_vertices:
                    # for certain blocks such as data and resource, the block name is composed from several parts.
                    # the purpose of the loop is to avoid not finding the node if the name has several parts
                    sub_values = [
                        remove_index_pattern_from_str(sub_value)
                        for sub_value in vertex_reference.sub_parts
                    ]
                    for i in range(len(sub_values)):
                        reference_name = join_trimmed_strings(
                            char_to_join=".",
                            str_lst=sub_values,
                            num_to_trim=i)
                        if vertex.module_dependency:
                            dest_node_index = self._find_vertex_index_relative_to_path(
                                vertex_reference.block_type, reference_name,
                                vertex.path, vertex.module_dependency)
                            if dest_node_index == -1:
                                dest_node_index = self._find_vertex_index_relative_to_path(
                                    vertex_reference.block_type,
                                    reference_name, vertex.path, vertex.path)
                        else:
                            dest_node_index = self._find_vertex_index_relative_to_path(
                                vertex_reference.block_type, reference_name,
                                vertex.path, vertex.module_dependency)
                        if dest_node_index > -1 and origin_node_index > -1:
                            if vertex_reference.block_type == BlockType.MODULE:
                                try:
                                    self._connect_module(
                                        sub_values, attribute_key,
                                        self.vertices[dest_node_index],
                                        origin_node_index)
                                except Exception as e:
                                    logging.warning(
                                        f'Module {self.vertices[dest_node_index]} does not have source attribute, skipping'
                                    )
                                    logging.warning(e, stack_info=True)
                            else:
                                self._create_edge(origin_node_index,
                                                  dest_node_index,
                                                  attribute_key)
                            break

            if vertex.block_type == BlockType.MODULE:
                target_path = vertex.path
                if vertex.module_dependency != '':
                    target_path = unify_dependency_path(
                        [vertex.module_dependency, vertex.path])
                target_variables = list(
                    filter(
                        lambda v: self.vertices[v].module_dependency ==
                        target_path,
                        self.vertices_by_block_type.get(
                            BlockType.VARIABLE, {})))
                for attribute, value in vertex.attributes.items():
                    if attribute in MODULE_RESERVED_ATTRIBUTES:
                        continue
                    target_variable = None
                    for v in target_variables:
                        if self.vertices[v].name == attribute:
                            target_variable = v
                            break
                    if target_variable is not None:
                        self._create_edge(target_variable, origin_node_index,
                                          'default')
            elif vertex.block_type == BlockType.TF_VARIABLE:
                if vertex.module_dependency != '':
                    target_path = unify_dependency_path(
                        [vertex.module_dependency, vertex.path])
                # Assuming the tfvars file is in the same directory as the variables file (best practice)
                target_variables = list(
                    filter(
                        lambda v: os.path.dirname(self.vertices[v].path) == os.
                        path.dirname(vertex.path),
                        self.vertices_block_name_map.get(
                            BlockType.VARIABLE, {}).get(vertex.name, [])))
                if len(target_variables) == 1:
                    self._create_edge(target_variables[0], origin_node_index,
                                      'default')