Ejemplo n.º 1
0
    def extract_value_from_vertex(self, key_path: List[str],
                                  attributes: Dict[str, Any]) -> Any:
        for i, _ in enumerate(key_path):
            key = join_trimmed_strings(char_to_join=".",
                                       str_lst=key_path,
                                       num_to_trim=i)
            value = attributes.get(key, None)
            if value is not None:
                return value

        reversed_key_path = deepcopy(key_path)
        reversed_key_path.reverse()
        for i, _ in enumerate(reversed_key_path):
            key = join_trimmed_strings(char_to_join=".",
                                       str_lst=reversed_key_path,
                                       num_to_trim=i)
            value = attributes.get(key, None)
            if value is not None:
                return value

        if attributes.get(CustomAttributes.BLOCK_TYPE) in [
                BlockType.VARIABLE.value, BlockType.TF_VARIABLE.value
        ]:
            default_val = attributes.get("default")
            value = None
            if isinstance(default_val, dict):
                value = self.extract_value_from_vertex(key_path, default_val)
            return default_val if not value else value
        if attributes.get(
                CustomAttributes.BLOCK_TYPE) == BlockType.OUTPUT.value:
            return attributes.get("value")
        return None
Ejemplo n.º 2
0
    def update_attribute(self, attribute_key: str, attribute_value: Any,
                         change_origin_id: int,
                         previous_breadcrumbs: List[int]) -> None:
        if not previous_breadcrumbs or previous_breadcrumbs[
                -1] != change_origin_id:
            previous_breadcrumbs.append(change_origin_id)

        self.update_inner_attribute(attribute_key, self.attributes,
                                    attribute_value)
        attribute_key_parts = attribute_key.split(".")
        if len(attribute_key_parts) == 1:
            self.attributes[attribute_key] = attribute_value
            self.changed_attributes[attribute_key] = previous_breadcrumbs
            return
        for i in range(len(attribute_key_parts)):
            key = join_trimmed_strings(char_to_join=".",
                                       str_lst=attribute_key_parts,
                                       num_to_trim=i)
            if key.find(".") > -1:
                self.attributes[key] = attribute_value
                attribute_value = {
                    attribute_key_parts[len(attribute_key_parts) - 1 - i]:
                    attribute_value
                }
                self.changed_attributes[key] = previous_breadcrumbs
Ejemplo n.º 3
0
    def extract_value_from_vertex(self, key_path, attributes):
        for i in range(len(key_path)):
            key = join_trimmed_strings(char_to_join=".", str_lst=key_path, num_to_trim=i)
            value = attributes.get(key, None)
            if value is not None:
                return value

        reversed_key_path = deepcopy(key_path)
        reversed_key_path.reverse()
        for i in range(len(reversed_key_path)):
            key = join_trimmed_strings(char_to_join=".", str_lst=reversed_key_path, num_to_trim=i)
            value = attributes.get(key, None)
            if value is not None:
                return value

        if attributes.get(CustomAttributes.BLOCK_TYPE) in [BlockType.VARIABLE.value, BlockType.TF_VARIABLE.value]:
            default_val = attributes.get('default')
            value = None
            if isinstance(default_val, dict):
                value = self.extract_value_from_vertex(key_path, default_val)
            return default_val if not value else value
        if attributes.get(CustomAttributes.BLOCK_TYPE) == BlockType.OUTPUT.value:
            return attributes.get('value')
        return None
Ejemplo n.º 4
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')