Ejemplo n.º 1
0
 def evaluate_non_rendered_values(self) -> None:
     for vertex in self.local_graph.vertices:
         changed_attributes = {}
         attributes: Dict[str, Any] = {}
         vertex.get_origin_attributes(attributes)
         for attribute in filter(
                 lambda attr: attr not in reserved_attribute_names and
                 not attribute_has_nested_attributes(
                     attr, vertex.attributes),
                 vertex.attributes,
         ):
             curr_val = vertex.attributes.get(attribute)
             lst_curr_val = curr_val
             if not isinstance(lst_curr_val, list):
                 lst_curr_val = [lst_curr_val]
             if len(lst_curr_val) > 0 and isinstance(lst_curr_val[0], Tree):
                 lst_curr_val[0] = str(lst_curr_val[0])
             evaluated_lst = []
             for inner_val in lst_curr_val:
                 if (isinstance(inner_val, str)
                         and not any(c in inner_val
                                     for c in ["{", "}", "[", "]", "="])
                         or attribute in ATTRIBUTES_NO_EVAL):
                     evaluated_lst.append(inner_val)
                     continue
                 evaluated = self.evaluate_value(inner_val)
                 evaluated_lst.append(evaluated)
             evaluated = evaluated_lst
             if not isinstance(curr_val, list):
                 evaluated = evaluated_lst[0]
             if evaluated != curr_val:
                 vertex.update_inner_attribute(attribute, vertex.attributes,
                                               evaluated)
                 changed_attributes[attribute] = evaluated
         self.local_graph.update_vertex_config(vertex, changed_attributes)
Ejemplo n.º 2
0
 def test__attribute_has_nested_attributes_list(self):
     attributes = {
         'most_recent': [True],
         'filter': [{
             'name': 'name',
             'values': ['amzn-ami-hvm-*-x86_64-gp2']
         }, {
             'name': 'owner-alias',
             'values': ['amazon']
         }],
         'filter.0': {
             'name': 'name',
             'values': ['amzn-ami-hvm-*-x86_64-gp2']
         },
         'filter.0.name':
         'name',
         'filter.0.values': ['amzn-ami-hvm-*-x86_64-gp2'],
         'filter.0.values.0':
         'amzn-ami-hvm-*-x86_64-gp2',
         'filter.1': {
             'name': 'owner-alias',
             'values': ['amazon']
         },
         'filter.1.name':
         'owner-alias',
         'filter.1.values': ['amazon'],
         'filter.1.values.0':
         'amazon'
     }
     self.assertTrue(
         attribute_has_nested_attributes(attribute_key='filter',
                                         attributes=attributes))
     self.assertTrue(
         attribute_has_nested_attributes(attribute_key='filter.1.values',
                                         attributes=attributes))
     self.assertFalse(
         attribute_has_nested_attributes(attribute_key='filter.1.values.0',
                                         attributes=attributes))
Ejemplo n.º 3
0
 def test__attribute_has_nested_attributes_dictionary(self):
     attributes = {
         'name': ['${var.lb_name}'],
         'internal': [True],
         'security_groups': ['${var.lb_security_group_ids}'],
         'subnets': ['${var.subnet_id}'],
         'enable_deletion_protection': [True],
         'tags': {
             'Terraform': True,
             'Environment': 'sophi-staging'
         },
         'resource_type': ['aws_alb'],
         'tags.Terraform': True,
         'tags.Environment': 'sophi-staging'
     }
     self.assertTrue(
         attribute_has_nested_attributes(attribute_key='tags',
                                         attributes=attributes))
     self.assertFalse(
         attribute_has_nested_attributes(attribute_key='name',
                                         attributes=attributes))
     self.assertFalse(
         attribute_has_nested_attributes(attribute_key='tags.Environment',
                                         attributes=attributes))
Ejemplo n.º 4
0
    def _build_edges(self) -> None:
        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 enumerate(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,
                                vertex.module_dependency_num)
                            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,
                                    vertex.module_dependency_num)
                        else:
                            dest_node_index = self._find_vertex_index_relative_to_path(
                                vertex_reference.block_type, reference_name,
                                vertex.path, vertex.module_dependency,
                                vertex.module_dependency_num)
                        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 and vertex.attributes.get(
                    'source'):
                target_path = vertex.path
                if vertex.module_dependency != "":
                    target_path = unify_dependency_path(
                        [vertex.module_dependency, vertex.path])
                dest_module_path = self._get_dest_module_path(
                    curr_module_dir=self.get_dirname(vertex.path),
                    dest_module_source=vertex.attributes["source"][0],
                    dest_module_version=vertex.attributes.get(
                        "version", ["latest"])[0])
                target_variables = [
                    index for index in self.vertices_by_module_dependency.get((
                        target_path,
                        self.module.module_address_map.get((
                            vertex.path,
                            vertex.name))), {}).get(BlockType.VARIABLE, [])
                    if self.get_dirname(self.vertices[index].path) ==
                    dest_module_path
                ]
                for attribute, value in vertex.attributes.items():
                    if attribute in MODULE_RESERVED_ATTRIBUTES:
                        continue
                    target_variable = next(
                        (v for v in target_variables
                         if self.vertices[v].name == attribute), None)
                    if target_variable is not None:
                        self._create_edge(target_variable, origin_node_index,
                                          "default")
            elif vertex.block_type == BlockType.TF_VARIABLE:
                # Assuming the tfvars file is in the same directory as the variables file (best practice)
                target_variables = [
                    index for index in self.vertices_block_name_map.get(
                        BlockType.VARIABLE, {}).get(vertex.name, [])
                    if self.get_dirname(self.vertices[index].path) ==
                    self.get_dirname(vertex.path)
                ]
                if len(target_variables) == 1:
                    self._create_edge(target_variables[0], origin_node_index,
                                      "default")