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)
def run_block(self, entities, definition_context, full_file_path, report, scanned_file, block_type, runner_filter=None): registry = self.block_type_registries[block_type] if registry: 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) entity_context_path = [block_type] + definition_path # Entity can exist only once per dir, for file as well 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') variables_evaluations = definition_context[full_file_path].get( 'evaluations') if variables_evaluations: entity_evaluations = BaseVariableEvaluation.reduce_entity_evaluations( variables_evaluations, entity_context_path) results = registry.scan(scanned_file, entity, skipped_checks, runner_filter) 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__) report.add_record(record=record)
def get_enriched_resources(repo_root): tf_definitions = {} parsing_errors = {} Parser().parse_directory( directory=repo_root, # assume plan file is in the repo-root out_definitions=tf_definitions, out_parsing_errors=parsing_errors, ) enriched_resources = {} for full_file_path, definition in tf_definitions.items(): definitions_context = parser_registry.enrich_definitions_context( (full_file_path, definition)) abs_scanned_file, _ = tf_runner._strip_module_referrer( full_file_path) scanned_file = os.path.relpath(abs_scanned_file, repo_root) for block_type, block_value in definition.items(): if block_type in CHECK_BLOCK_TYPES: for entity in block_value: context_parser = parser_registry.context_parsers[ block_type] definition_path = context_parser.get_entity_context_path( entity) entity_id = ".".join(definition_path) entity_context_path = [block_type] + definition_path entity_context = dict_utils.getInnerDict( definitions_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") enriched_resources[entity_id] = { "entity_code_lines": entity_code_lines, "entity_lines_range": entity_lines_range, "scanned_file": scanned_file, "skipped_checks": skipped_checks } return enriched_resources
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)