Ejemplo n.º 1
0
    def test_load_inner_registry_module(self):
        parser = Parser()
        directory = os.path.join(self.resources_dir, "registry_security_group_inner_module")
        self.external_module_path = os.path.join(self.tmp_path, DEFAULT_EXTERNAL_MODULES_DIR)
        out_definitions = {}
        parser.parse_directory(directory=directory, out_definitions=out_definitions,
                               out_evaluations_context={},
                               download_external_modules=True,
                               external_modules_download_path=self.external_module_path)
        self.assertEqual(11, len(list(out_definitions.keys())))
        expected_remote_module_path = f'{self.external_module_path}/github.com/terraform-aws-modules/terraform-aws-security-group/v4.0.0'
        expected_inner_remote_module_path = f'{expected_remote_module_path}/modules/http-80'
        expected_main_file = os.path.join(directory, 'main.tf')
        expected_inner_main_file = os.path.join(directory, expected_inner_remote_module_path, 'main.tf')
        expected_file_names = [
            expected_main_file,
            os.path.join(directory, expected_inner_remote_module_path, f'auto_values.tf[{expected_main_file}#0]'),
            os.path.join(directory, expected_inner_remote_module_path, f'main.tf[{expected_main_file}#0]'),
            os.path.join(directory, expected_inner_remote_module_path, f'outputs.tf[{expected_main_file}#0]'),
            os.path.join(directory, expected_inner_remote_module_path, f'variables.tf[{expected_main_file}#0]'),
            os.path.join(directory, expected_inner_remote_module_path, f'versions.tf[{expected_main_file}#0]'),

            os.path.join(directory, expected_remote_module_path, f'main.tf[{expected_inner_main_file}#0]'),
            os.path.join(directory, expected_remote_module_path, f'outputs.tf[{expected_inner_main_file}#0]'),
            os.path.join(directory, expected_remote_module_path, f'rules.tf[{expected_inner_main_file}#0]'),
            os.path.join(directory, expected_remote_module_path, f'variables.tf[{expected_inner_main_file}#0]'),
            os.path.join(directory, expected_remote_module_path, f'versions.tf[{expected_inner_main_file}#0]'),
        ]

        for expected_file_name in expected_file_names:
            if expected_file_name not in list(out_definitions.keys()):
                self.fail(f"expected file {expected_file_name} to be in out_definitions")
Ejemplo n.º 2
0
    def go(dir_name):
        dir_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                f"resources/parser_scenarios/{dir_name}")
        assert os.path.exists(dir_path)

        expected_data = TestParserScenarios.load_expected_data("expected.json", dir_path)
        assert expected_data is not None, f"{dir_name}: expected.json file not found"

        evaluation_data = TestParserScenarios.load_expected_data("eval.json", dir_path)

        actual_data = {}
        actual_eval_data = {}
        errors = {}
        parser = Parser()
        parser.parse_directory(dir_path, actual_data, actual_eval_data, errors, download_external_modules=True)
        assert not errors, f"{dir_name}: Unexpected errors: {errors}"
        definition_string = json.dumps(actual_data, indent=2, default=json_encoder)
        definition_encoded = json.loads(definition_string)
        assert definition_encoded == expected_data, \
            f"{dir_name}: Data mismatch:\n" \
            f"  Expected: \n{json.dumps(expected_data, indent=2, default=json_encoder)}\n\n" \
            f"  Actual: \n{definition_string}"

        if evaluation_data is not None:
            definition_string = json.dumps(actual_eval_data, indent=2, default=json_encoder)
            definition_encoded = json.loads(definition_string)
            assert definition_encoded == evaluation_data, \
                f"{dir_name}: Evaluation data mismatch:\n" \
                f"  Expected: \n{json.dumps(evaluation_data, indent=2, default=json_encoder)}\n\n" \
                f"  Actual: \n{definition_string}"
Ejemplo n.º 3
0
 def test_malformed_output_blocks(self):
     parser = Parser()
     directory = os.path.join(self.resources_dir, "malformed_outputs")
     self.external_module_path = os.path.join(directory, DEFAULT_EXTERNAL_MODULES_DIR)
     out_definitions = {}
     parser.parse_directory(directory=directory, out_definitions=out_definitions,
                            out_evaluations_context={},
                            download_external_modules=True,
                            external_modules_download_path=DEFAULT_EXTERNAL_MODULES_DIR)
     file_path, entity_definitions = next(iter(out_definitions.items()))
     self.assertEqual(2, len(list(out_definitions[file_path]['output'])))
Ejemplo n.º 4
0
 def test_invalid_module_sources(self):
     parser = Parser()
     directory = os.path.join(self.resources_dir, "failing_module_address")
     self.external_module_path = os.path.join(directory, DEFAULT_EXTERNAL_MODULES_DIR)
     out_definitions = {}
     parser.parse_directory(directory=directory, out_definitions=out_definitions,
                            out_evaluations_context={},
                            download_external_modules=True,
                            external_modules_download_path=DEFAULT_EXTERNAL_MODULES_DIR)
     # check that only the original file was parsed successfully without getting bad external modules
     self.assertEqual(1, len(list(out_definitions.keys())))
Ejemplo n.º 5
0
    def test_load_registry_module(self):
        parser = Parser()
        directory = os.path.join(self.resources_dir, "registry_security_group")
        self.external_module_path = os.path.join(directory, DEFAULT_EXTERNAL_MODULES_DIR)
        out_definitions = {}
        parser.parse_directory(directory=directory, out_definitions=out_definitions,
                               out_evaluations_context={},
                               download_external_modules=True,
                               external_modules_download_path=DEFAULT_EXTERNAL_MODULES_DIR)

        external_aws_modules_path = os.path.join(self.external_module_path, 'github.com/terraform-aws-modules/terraform-aws-security-group/v3.18.0')
        assert os.path.exists(external_aws_modules_path)
Ejemplo n.º 6
0
    def test_load_local_module(self):
        # given
        parser = Parser()
        directory = os.path.join(self.resources_dir, "local_module")
        out_definitions = {}

        # when
        parser.parse_directory(
            directory=directory, out_definitions=out_definitions, out_evaluations_context={}
        )

        # then
        self.assertEqual(len(out_definitions), 3)  # root file + 2x module file
        self.assertEqual(len(parser.loaded_files_map), 2)  # root file + 1x module file
Ejemplo n.º 7
0
    def test_external_definitions_context(self):
        current_dir = os.path.dirname(os.path.realpath(__file__))

        tf_dir_path = current_dir + "/resources/valid_tf_only_passed_checks"
        external_definitions_context = {
            f'{current_dir}/resources/valid_tf_only_passed_checks/example.tf':
            {
                'resource': {
                    'aws_s3_bucket': {
                        'foo-bucket': {
                            'start_line':
                            1,
                            'end_line':
                            34,
                            'code_lines':
                            [(1, 'resource "aws_s3_bucket" "foo-bucket" {\n'),
                             (2, '  region        = var.region\n'),
                             (3, '  bucket        = local.bucket_name\n'),
                             (4, '  force_destroy = true\n'),
                             (5, '  tags = {\n'),
                             (6,
                              '    Name = "foo-${data.aws_caller_identity.current.account_id}"\n'
                              ), (7, '  }\n'), (8, '  versioning {\n'),
                             (9, '    enabled = true\n'),
                             (10, '    mfa_delete = true\n'), (11, '  }\n'),
                             (12, '  logging {\n'),
                             (13,
                              '    target_bucket = "${aws_s3_bucket.log_bucket.id}"\n'
                              ), (14, '    target_prefix = "log/"\n'),
                             (15, '  }\n'),
                             (16,
                              '  server_side_encryption_configuration {\n'),
                             (17, '    rule {\n'),
                             (18,
                              '      apply_server_side_encryption_by_default {\n'
                              ),
                             (19,
                              '        kms_master_key_id = "${aws_kms_key.mykey.arn}"\n'
                              ),
                             (20, '        sse_algorithm     = "aws:kms"\n'),
                             (21, '      }\n'), (22, '    }\n'), (23, '  }\n'),
                             (24, '  acl           = "private"\n'),
                             (25, '  tags = "${merge\n'), (26, '    (\n'),
                             (27, '      var.common_tags,\n'),
                             (28, '      map(\n'),
                             (29, '        "name", "VM Virtual Machine",\n'),
                             (30, '        "group", "foo"\n'), (31,
                                                                '      )\n'),
                             (32, '    )\n'), (33, '  }"\n'), (34, '}\n')],
                            'skipped_checks': []
                        }
                    },
                    'null_resource': {
                        'example': {
                            'start_line':
                            36,
                            'end_line':
                            46,
                            'code_lines':
                            [(36, 'resource "null_resource" "example" {\n'),
                             (37, '  tags = "${merge\n'), (38, '(\n'),
                             (39, 'var.common_tags,\n'), (40, 'map(\n'),
                             (41,
                              '"name", "VM Base Post Provisioning Library",\n'
                              ), (42, '"group", "aut",\n'),
                             (43,
                              '"dependency", "${var.input_dependency_value}")\n'
                              ), (44, ')\n'), (45, '}"\n'), (46, '}\n')],
                            'skipped_checks': []
                        }
                    }
                },
                'data': {
                    'aws_caller_identity': {
                        'current': {
                            'start_line': 47,
                            'end_line': 0,
                            'code_lines': [],
                            'skipped_checks': []
                        }
                    }
                },
                'provider': {
                    'kubernetes': {
                        'default': {
                            'start_line':
                            49,
                            'end_line':
                            55,
                            'code_lines':
                            [(49, 'provider "kubernetes" {\n'),
                             (50, '  version                = "1.10.0"\n'),
                             (51,
                              '  host                   = module.aks_cluster.kube_config.0.host\n'
                              ),
                             (52,
                              '  client_certificate     = base64decode(module.aks_cluster.kube_config.0.client_certificate)\n'
                              ),
                             (53,
                              'client_key             = base64decode(module.aks_cluster.kube_config.0.client_key)\n'
                              ),
                             (54,
                              'cluster_ca_certificate = base64decode(module.aks_cluster.kube_config.0.cluster_ca_certificate)\n'
                              ), (55, '}\n')],
                            'skipped_checks': []
                        }
                    }
                },
                'module': {
                    'module': {
                        'new_relic': {
                            'start_line':
                            57,
                            'end_line':
                            67,
                            'code_lines':
                            [(57, 'module "new_relic" {\n'),
                             (58,
                              'source                            = "s3::https://s3.amazonaws.com/my-artifacts/new-relic-k8s-0.2.5.zip"\n'
                              ),
                             (59,
                              'kubernetes_host                   = module.aks_cluster.kube_config.0.host\n'
                              ),
                             (60,
                              'kubernetes_client_certificate     = base64decode(module.aks_cluster.kube_config.0.client_certificate)\n'
                              ),
                             (61,
                              'kubernetes_client_key             = base64decode(module.aks_cluster.kube_config.0.client_key)\n'
                              ),
                             (62,
                              'kubernetes_cluster_ca_certificate = base64decode(module.aks_cluster.kube_config.0.cluster_ca_certificate)\n'
                              ),
                             (63,
                              'cluster_name                      = module.naming_conventions.aks_name\n'
                              ),
                             (64,
                              'new_relic_license                 = data.vault_generic_secret.new_relic_license.data["license"]\n'
                              ),
                             (65,
                              'cluster_ca_bundle_b64             = module.aks_cluster.kube_config.0.cluster_ca_certificate\n'
                              ),
                             (66,
                              'module_depends_on                 = [null_resource.delay_aks_deployments]\n'
                              ), (67, '}')],
                            'skipped_checks': []
                        }
                    }
                }
            },
            f'{current_dir}/resources/valid_tf_only_passed_checks/example_skip_acl.tf':
            {
                'resource': {
                    'aws_s3_bucket': {
                        'foo-bucket': {
                            'start_line':
                            1,
                            'end_line':
                            26,
                            'code_lines':
                            [(1, 'resource "aws_s3_bucket" "foo-bucket" {\n'),
                             (2, '  region        = var.region\n'),
                             (3, '  bucket        = local.bucket_name\n'),
                             (4, '  force_destroy = true\n'),
                             (5,
                              '  #checkov:skip=CKV_AWS_20:The bucket is a public static content host\n'
                              ), (6, '  #bridgecrew:skip=CKV_AWS_52: foo\n'),
                             (7, '  tags = {\n'),
                             (8,
                              '    Name = "foo-${data.aws_caller_identity.current.account_id}"\n'
                              ), (9, '  }\n'), (10, '  versioning {\n'),
                             (11, '    enabled = true\n'), (12, '  }\n'),
                             (13, '  logging {\n'),
                             (14,
                              '    target_bucket = "${aws_s3_bucket.log_bucket.id}"\n'
                              ), (15, '    target_prefix = "log/"\n'),
                             (16, '  }\n'),
                             (17,
                              '  server_side_encryption_configuration {\n'),
                             (18, '    rule {\n'),
                             (19,
                              '      apply_server_side_encryption_by_default {\n'
                              ),
                             (20,
                              '        kms_master_key_id = "${aws_kms_key.mykey.arn}"\n'
                              ),
                             (21, '        sse_algorithm     = "aws:kms"\n'),
                             (22, '      }\n'), (23, '    }\n'), (24, '  }\n'),
                             (25, '  acl           = "public-read"\n'),
                             (26, '}\n')],
                            'skipped_checks': [{
                                'id':
                                'CKV_AWS_20',
                                'suppress_comment':
                                'The bucket is a public static content host'
                            }, {
                                'id': 'CKV_AWS_52',
                                'suppress_comment': ' foo'
                            }]
                        }
                    }
                },
                'data': {
                    'aws_caller_identity': {
                        'current': {
                            'start_line': 27,
                            'end_line': 0,
                            'code_lines': [],
                            'skipped_checks': []
                        }
                    }
                }
            }
        }
        tf_definitions = {
            '/Users/nkor/dev/checkov_v2/tests/terraform/runner/resources/valid_tf_only_passed_checks/example.tf':
            {
                'resource': [{
                    'aws_s3_bucket': {
                        'foo-bucket': {
                            'region': ['${var.region}'],
                            'bucket': ['${local.bucket_name}'],
                            'force_destroy': [True],
                            'versioning': [{
                                'enabled': [True],
                                'mfa_delete': [True]
                            }],
                            'logging': [{
                                'target_bucket':
                                ['${aws_s3_bucket.log_bucket.id}'],
                                'target_prefix': ['log/']
                            }],
                            'server_side_encryption_configuration': [{
                                'rule': [{
                                    'apply_server_side_encryption_by_default':
                                    [{
                                        'kms_master_key_id':
                                        ['${aws_kms_key.mykey.arn}'],
                                        'sse_algorithm': ['aws:kms']
                                    }]
                                }]
                            }],
                            'acl': ['private'],
                            'tags': [
                                '${merge\n    (\n      var.common_tags,\n      map(\n        "name", "VM Virtual Machine",\n        "group", "foo"\n      )\n    )\n  }'
                            ]
                        }
                    }
                }],
                'data': [{
                    'aws_caller_identity': {
                        'current': {}
                    }
                }],
                'provider': [{
                    'kubernetes': {
                        'version': ['1.10.0'],
                        'host': ['${module.aks_cluster.kube_config[0].host}'],
                        'client_certificate': [
                            '${base64decode(module.aks_cluster.kube_config[0].client_certificate)}'
                        ],
                        'client_key': [
                            '${base64decode(module.aks_cluster.kube_config[0].client_key)}'
                        ],
                        'cluster_ca_certificate': [
                            '${base64decode(module.aks_cluster.kube_config[0].cluster_ca_certificate)}'
                        ]
                    }
                }],
                'module': [{
                    'new_relic': {
                        'source': [
                            's3::https://s3.amazonaws.com/my-artifacts/new-relic-k8s-0.2.5.zip'
                        ],
                        'kubernetes_host':
                        ['${module.aks_cluster.kube_config[0].host}'],
                        'kubernetes_client_certificate': [
                            '${base64decode(module.aks_cluster.kube_config[0].client_certificate)}'
                        ],
                        'kubernetes_client_key': [
                            '${base64decode(module.aks_cluster.kube_config[0].client_key)}'
                        ],
                        'kubernetes_cluster_ca_certificate': [
                            '${base64decode(module.aks_cluster.kube_config[0].cluster_ca_certificate)}'
                        ],
                        'cluster_name':
                        ['${module.naming_conventions.aks_name}'],
                        'new_relic_license': [
                            '${data.vault_generic_secret.new_relic_license.data["license"]}'
                        ],
                        'cluster_ca_bundle_b64': [
                            '${module.aks_cluster.kube_config[0].cluster_ca_certificate}'
                        ],
                        'module_depends_on':
                        [['${null_resource.delay_aks_deployments}']]
                    }
                }]
            },
            '/Users/nkor/dev/checkov_v2/tests/terraform/runner/resources/valid_tf_only_passed_checks/example_skip_acl.tf':
            {
                'resource': [{
                    'aws_s3_bucket': {
                        'foo-bucket': {
                            'region': ['${var.region}'],
                            'bucket': ['${local.bucket_name}'],
                            'force_destroy': [True],
                            'tags': [{
                                'Name':
                                'foo-${data.aws_caller_identity.current.account_id}'
                            }],
                            'versioning': [{
                                'enabled': [True]
                            }],
                            'logging': [{
                                'target_bucket':
                                ['${aws_s3_bucket.log_bucket.id}'],
                                'target_prefix': ['log/']
                            }],
                            'server_side_encryption_configuration': [{
                                'rule': [{
                                    'apply_server_side_encryption_by_default':
                                    [{
                                        'kms_master_key_id':
                                        ['${aws_kms_key.mykey.arn}'],
                                        'sse_algorithm': ['aws:kms']
                                    }]
                                }]
                            }],
                            'acl': ['public-read']
                        }
                    }
                }],
                'data': [{
                    'aws_caller_identity': {
                        'current': {}
                    }
                }]
            }
        }
        runner = Runner()
        parser = Parser()
        runner.tf_definitions = tf_definitions
        runner.set_external_data(tf_definitions,
                                 external_definitions_context,
                                 breadcrumbs={})
        parser.parse_directory(tf_dir_path, tf_definitions)
        report = Report('terraform')
        runner.check_tf_definition(root_folder=tf_dir_path,
                                   report=report,
                                   runner_filter=RunnerFilter())
        self.assertGreaterEqual(len(report.passed_checks), 1)