Ejemplo n.º 1
0
    def run_block(self, entities,
                  definition_context,
                  full_file_path, root_folder, report, scanned_file,
                  block_type, runner_filter=None, entity_context_path_header=None):

        registry = self.block_type_registries[block_type]
        if not registry:
            return

        for entity in entities:
            entity_evaluations = None
            context_parser = parser_registry.context_parsers[block_type]
            definition_path = context_parser.get_entity_context_path(entity)
            entity_id = ".".join(definition_path)
            if entity_context_path_header is None:
                entity_context_path = [block_type] + definition_path
            else:
                entity_context_path = entity_context_path_header + block_type + definition_path
            # Entity can exist only once per dir, for file as well
            try:
                entity_context = dict_utils.getInnerDict(definition_context[full_file_path], entity_context_path)
                entity_lines_range = [entity_context.get('start_line'), entity_context.get('end_line')]
                entity_code_lines = entity_context.get('code_lines')
                skipped_checks = entity_context.get('skipped_checks')
            except KeyError:
                # TODO: Context info isn't working for modules
                entity_lines_range = None
                entity_code_lines = None
                skipped_checks = None

            if full_file_path in self.evaluations_context:
                variables_evaluations = {}
                for var_name, context_info in self.evaluations_context.get(full_file_path, {}).items():
                    variables_evaluations[var_name] = dataclasses.asdict(context_info)
                entity_evaluations = BaseVariableEvaluation.reduce_entity_evaluations(variables_evaluations,
                                                                                      entity_context_path)
            results = registry.scan(scanned_file, entity, skipped_checks, runner_filter)
            absolut_scanned_file_path = self._strip_module_referrer(file_path=full_file_path)
            # This duplicates a call at the start of scan, but adding this here seems better than kludging with some tuple return type
            (entity_type, _, entity_config) = registry.extract_entity_details(entity)
            tags = get_resource_tags(entity_type, entity_config)
            for check, check_result in results.items():
                record = Record(check_id=check.id, check_name=check.name, check_result=check_result,
                                code_block=entity_code_lines, file_path=scanned_file,
                                file_line_range=entity_lines_range,
                                resource=entity_id, evaluations=entity_evaluations,
                                check_class=check.__class__.__module__, file_abs_path=absolut_scanned_file_path, entity_tags=tags)
                report.add_record(record=record)
Ejemplo n.º 2
0
    def run_block(self,
                  entities,
                  definition_context,
                  full_file_path,
                  root_folder,
                  report,
                  scanned_file,
                  block_type,
                  runner_filter=None,
                  entity_context_path_header=None,
                  module_referrer: Optional[str] = None):

        registry = self.block_type_registries[block_type]
        if not registry:
            return

        for entity in entities:
            entity_evaluations = None
            context_parser = parser_registry.context_parsers[block_type]
            definition_path = context_parser.get_entity_context_path(entity)
            entity_id = ".".join(
                definition_path)  # example: aws_s3_bucket.my_bucket

            caller_file_path = None
            caller_file_line_range = None

            if module_referrer is not None:
                referrer_id = self._find_id_for_referrer(
                    full_file_path, self.tf_definitions)
                if referrer_id:
                    entity_id = f"{referrer_id}.{entity_id}"  # ex: module.my_module.aws_s3_bucket.my_bucket
                    abs_caller_file = module_referrer[:module_referrer.
                                                      rindex("#")]
                    caller_file_path = f"/{os.path.relpath(abs_caller_file, root_folder)}"

                    try:
                        caller_context = dpath.get(
                            definition_context[abs_caller_file],
                            # HACK ALERT: module data is currently double-nested in
                            #             definition context. If fixed, remove the
                            #             addition of "module." at the beginning.
                            "module." + referrer_id,
                            separator=".")
                    except KeyError:
                        logging.debug("Unable to find caller context for: %s",
                                      abs_caller_file)
                        caller_context = None

                    if caller_context:
                        caller_file_line_range = [
                            caller_context.get('start_line'),
                            caller_context.get('end_line')
                        ]
                else:
                    logging.debug(
                        f"Unable to find referrer ID for full path: %s",
                        full_file_path)

            if entity_context_path_header is None:
                entity_context_path = [block_type] + definition_path
            else:
                entity_context_path = entity_context_path_header + block_type + definition_path
            # Entity can exist only once per dir, for file as well
            try:
                entity_context = dict_utils.getInnerDict(
                    definition_context[full_file_path], entity_context_path)
                entity_lines_range = [
                    entity_context.get('start_line'),
                    entity_context.get('end_line')
                ]
                entity_code_lines = entity_context.get('code_lines')
                skipped_checks = entity_context.get('skipped_checks')
            except KeyError:
                # TODO: Context info isn't working for modules
                entity_lines_range = None
                entity_code_lines = None
                skipped_checks = None

            if full_file_path in self.evaluations_context:
                variables_evaluations = {}
                for var_name, context_info in self.evaluations_context.get(
                        full_file_path, {}).items():
                    variables_evaluations[var_name] = dataclasses.asdict(
                        context_info)
                entity_evaluations = BaseVariableEvaluation.reduce_entity_evaluations(
                    variables_evaluations, entity_context_path)
            results = registry.scan(scanned_file, entity, skipped_checks,
                                    runner_filter)
            absolut_scanned_file_path, _ = self._strip_module_referrer(
                file_path=full_file_path)
            # This duplicates a call at the start of scan, but adding this here seems better than kludging with some tuple return type
            (entity_type, entity_name,
             entity_config) = registry.extract_entity_details(entity)
            tags = get_resource_tags(entity_type, entity_config)
            for check, check_result in results.items():
                record = Record(check_id=check.id,
                                check_name=check.name,
                                check_result=check_result,
                                code_block=entity_code_lines,
                                file_path=scanned_file,
                                file_line_range=entity_lines_range,
                                resource=entity_id,
                                evaluations=entity_evaluations,
                                check_class=check.__class__.__module__,
                                file_abs_path=absolut_scanned_file_path,
                                entity_tags=tags,
                                caller_file_path=caller_file_path,
                                caller_file_line_range=caller_file_line_range)
                breadcrumb = self.breadcrumbs.get(record.file_path, {}).get(
                    '.'.join([entity_type, entity_name]))
                if breadcrumb:
                    record = GraphRecord(record, breadcrumb)
                report.add_record(record=record)