def check_tf_definition(self, report, root_folder, runner_filter, collect_skip_comments=True, external_definitions_context=None): parser_registry.reset_definitions_context() logging.debug('Evaluating string booleans') self.evaluate_string_booleans() logging.debug('Evaluated string booleans') if external_definitions_context: definitions_context = external_definitions_context else: logging.debug('Creating definitions context') definitions_context = {} for definition in self.tf_definitions.items(): definitions_context = parser_registry.enrich_definitions_context( definition, collect_skip_comments) variable_evaluator = ConstVariableEvaluation( root_folder, self.tf_definitions, definitions_context) variable_evaluator.evaluate_variables() self.tf_definitions, self.definitions_context = variable_evaluator.tf_definitions, variable_evaluator.definitions_context logging.debug('Created definitions context') for full_file_path, definition in self.tf_definitions.items(): scanned_file = f"/{os.path.relpath(full_file_path, root_folder)}" logging.debug(f"Scanning file: {scanned_file}") for block_type in definition.keys(): if block_type in ['resource', 'data', 'provider', 'module']: self.run_block(definition[block_type], definitions_context, full_file_path, report, scanned_file, block_type, runner_filter)
def run(self, root_folder, external_checks_dir=None, file=None): report = Report() tf_definitions = {} parsing_errors = {} if external_checks_dir: for directory in external_checks_dir: resource_registry.load_external_checks(directory) if file: Parser().parse_file(file=file, tf_definitions=tf_definitions, parsing_errors=parsing_errors) root_folder = os.path.dirname(file) else: Parser().hcl2(directory=root_folder, tf_definitions=tf_definitions, parsing_errors=parsing_errors) report.add_parsing_errors(parsing_errors.keys()) for definition in tf_definitions.items(): full_file_path = definition[0] definition_context = parser_registry.enrich_definitions_context(definition) scanned_file = definition[0].split(root_folder)[1] logging.debug("Scanning file: %s", scanned_file) for block_type in definition[1].keys(): if block_type in ['resource', 'data']: self.run_block(definition[1][block_type], definition_context, full_file_path, report, scanned_file, block_type) return report
def test_enrich_definition_block(self): mock_parser = MockContextParser() parser_registry.register(mock_parser) definition_context = parser_registry.enrich_definitions_context( mock_definition) self.assertIsNotNone(definition_context[mock_definition[0]]['mock'] ['mock_type']['mock_name'])
def check_tf_definition(self, report, root_folder, runner_filter, collect_skip_comments=True, external_definitions_context=None): parser_registry.reset_definitions_context() if external_definitions_context: definitions_context = external_definitions_context else: definitions_context = {} for definition in self.tf_definitions.items(): definitions_context = parser_registry.enrich_definitions_context( definition, collect_skip_comments) self.definitions_context = definitions_context logging.debug('Created definitions context') for full_file_path, definition in self.tf_definitions.items(): abs_scanned_file, abs_referrer = self._strip_module_referrer( full_file_path) scanned_file = f"/{os.path.relpath(abs_scanned_file, root_folder)}" logging.debug(f"Scanning file: {scanned_file}") self.run_all_blocks(definition, definitions_context, full_file_path, root_folder, report, scanned_file, runner_filter, abs_referrer)
def run(self, root_folder, external_checks_dir=None): report = Report() tf_definitions = {} parsing_errors = {} if external_checks_dir: for directory in external_checks_dir: resource_registry.load_external_checks(directory) Parser().hcl2(directory=root_folder, tf_definitions=tf_definitions, parsing_errors=parsing_errors) report.add_parsing_errors(parsing_errors.keys()) for definition in tf_definitions.items(): full_file_path = definition[0] definition_context = parser_registry.enrich_definitions_context(definition) scanned_file = definition[0].split(root_folder)[1] logging.debug("Scanning file: %s", scanned_file) if 'resource' in definition[1]: for resource in definition[1]['resource']: resource_type = list(resource.keys())[0] resource_name = list(list(resource.values())[0].keys())[0] resource_id = "{}.{}".format(resource_type, resource_name) resource_context = definition_context[full_file_path][resource_type][resource_name] resource_lines_range = [resource_context['start_line'], resource_context['end_line']] resource_code_lines = resource_context['code_lines'] skipped_checks = resource_context.get('skipped_checks') results = resource_registry.scan(resource, scanned_file, skipped_checks) for check, check_result in results.items(): record = Record(check_id=check.id, check_name=check.name, check_result=check_result, code_block=resource_code_lines, file_path=scanned_file, file_line_range=resource_lines_range, resource=resource_id, check_class=check.__class__.__module__) report.add_record(record=record) return report
def test_enrich_definition_block(self): mock_parser = MockContextParser() parser_registry.register(mock_parser) definition_context = parser_registry.enrich_definitions_context(mock_definition) self.assertIsNotNone(definition_context[mock_tf_file]['mock']['mock_type']['mock_name'].get('skipped_checks')) self.assertEqual(len(definition_context[mock_tf_file]['mock']['mock_type']['mock_name'].get('skipped_checks')), 2)
def setUp(self): test_root_dir = os.path.dirname(os.path.realpath(__file__)) + '/../evaluation/resources/default_evaluation/' tf_definitions = {} parsing_errors = {} Parser().parse_directory(directory=test_root_dir, out_definitions=tf_definitions, out_evaluations_context={}, out_parsing_errors=parsing_errors) for definition in tf_definitions.items(): definitions_context = parser_registry.enrich_definitions_context(definition) self.definitions_context = definitions_context
def setUp(self): test_root_dir = 'tests/terraform/evaluation/resources/default_evaluation' tf_definitions = {} parsing_errors = {} Parser().hcl2(directory=test_root_dir, tf_definitions=tf_definitions, parsing_errors=parsing_errors) for definition in tf_definitions.items(): definitions_context = parser_registry.enrich_definitions_context( definition) self.definitions_context = definitions_context
def get_enriched_resources( repo_roots: List[Union[str, os.PathLike]]) -> Dict[str, Dict[str, Any]]: repo_definitions = {} for repo_root in repo_roots: 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, ) repo_definitions[repo_root] = { 'tf_definitions': tf_definitions, 'parsing_errors': parsing_errors } enriched_resources = {} for repo_root, parse_results in repo_definitions.items(): for full_file_path, definition in parse_results[ '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 = data_structures_utils.get_inner_dict( 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 test_enrich_definition_block(self): mock_parser = MockContextParser() parser_registry.register(mock_parser) definition_context = parser_registry.enrich_definitions_context( mock_definition) skipped_checks = definition_context[mock_tf_file]["mock"]["mock_type"][ "mock_name"].get("skipped_checks") self.assertIsNotNone(skipped_checks) self.assertEqual(len(skipped_checks), 3) # Ensure checkov IDs are mapped to BC IDs self.assertEqual(skipped_checks[2]["id"], "CKV_AWS_15")
def setUp(self): test_root_dir = os.path.dirname(os.path.realpath(__file__)) + '/resources/default_evaluation' tf_definitions = {} parsing_errors = {} Parser().hcl2(directory=test_root_dir, tf_definitions=tf_definitions, parsing_errors=parsing_errors) for definition in tf_definitions.items(): definitions_context = parser_registry.enrich_definitions_context(definition) variable_evaluator = ConstVariableEvaluation(test_root_dir, tf_definitions, definitions_context) variable_evaluator.evaluate_variables() self.tf_definitions = variable_evaluator.tf_definitions self.definitions_context = variable_evaluator.definitions_context
def setup_dir(self, rel_path): test_root_dir = os.path.dirname(os.path.realpath(__file__)) + rel_path tf_definitions = {} parsing_errors = {} definitions_context = {} Parser().parse_directory(directory=test_root_dir, out_definitions=tf_definitions, out_parsing_errors=parsing_errors) for definition in tf_definitions.items(): definitions_context = parser_registry.enrich_definitions_context( definition) return definitions_context
def check_tf_definition(self, report, root_folder): definitions_context = {} parser_registry.reset_definitions_context() for definition in self.tf_definitions.items(): definitions_context = parser_registry.enrich_definitions_context(definition) self.evaluate_string_booleans() variable_evaluator = ConstVariableEvaluation(root_folder, self.tf_definitions, definitions_context) variable_evaluator.evaluate_variables() self.tf_definitions, self.definitions_context = variable_evaluator.tf_definitions, variable_evaluator.definitions_context for full_file_path, definition in self.tf_definitions.items(): scanned_file = f"/{os.path.relpath(full_file_path, root_folder)}" logging.debug(f"Scanning file: {scanned_file}") for block_type in definition.keys(): if block_type in ['resource', 'data', 'provider']: self.run_block(definition[block_type], definitions_context, full_file_path, report, scanned_file, block_type)
def check_tf_definition(self, report, root_folder, tf_definitions): for definition in tf_definitions.items(): definitions_context = parser_registry.enrich_definitions_context( definition) variable_evaluator = ConstVariableEvaluation(root_folder, tf_definitions, definitions_context) variable_evaluator.evaluate_variables() tf_definitions, definitions_context = variable_evaluator.tf_definitions, variable_evaluator.definitions_context for definition in tf_definitions.items(): full_file_path = definition[0] scanned_file = definition[0].split(root_folder)[1] logging.debug("Scanning file: %s", scanned_file) for block_type in definition[1].keys(): if block_type in ['resource', 'data']: self.run_block(definition[1][block_type], definitions_context, full_file_path, report, scanned_file, block_type)