Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions checkov/common/checks_infra/checks_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ def validate_check_config(self, file_path: str, raw_check: dict[str, dict[str, A
def parse_raw_check(self, raw_check: Dict[str, Dict[str, Any]], **kwargs: Any) -> BaseGraphCheck:
providers = self._get_check_providers(raw_check)
policy_definition = raw_check.get("definition", {})
if isinstance(policy_definition, list):
# a list of conditions is treated as an implicit AND
policy_definition = {"and": policy_definition}
check = self._parse_raw_check(policy_definition, kwargs.get("resources_types"), providers)
check.id = raw_check.get("metadata", {}).get("id", "")
check.name = raw_check.get("metadata", {}).get("name", "")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
metadata:
name: "Ensure S3 bucket has versioning and encryption"
id: CUSTOM_LIST_DEF
category: "GENERAL_SECURITY"
definition:
- cond_type: attribute
resource_types:
- aws_s3_bucket
attribute: versioning.enabled
operator: equals
value: "true"
- cond_type: attribute
resource_types:
- aws_s3_bucket
attribute: server_side_encryption_configuration
operator: exists
47 changes: 47 additions & 0 deletions tests/common/checks_infra/test_checks_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from checkov.common.checks_infra.checks_parser import GraphCheckParser
from checkov.common.checks_infra.resources_types import resources_types as raw_resources_types
from checkov.common.graph.checks_infra.enums import SolverType

EXAMPLES_DIR = Path(__file__).parent / "examples"

Expand Down Expand Up @@ -91,3 +92,49 @@ def test_parse_taggable_resource_list():
providers = ["azure"]
check = parser._parse_raw_check(raw_check, [], providers)
assert check.resource_types == raw_resources_types.get("azure_taggable")


def test_validate_check_config_list_definition(caplog: LogCaptureFixture):
"""A definition that is a list should pass validation."""
# given
file_path = EXAMPLES_DIR / "valid_check_list_definition.yaml"
check_yaml = yaml.safe_load(file_path.read_text())

# when
valid = GraphCheckParser().validate_check_config(file_path=str(file_path), raw_check=check_yaml)

# then
assert valid
assert len(caplog.messages) == 0


def test_parse_raw_check_list_definition():
"""A list-type definition should be treated as an implicit AND of its elements."""
parser = GraphCheckParser()
raw_check = {
"metadata": {"id": "TEST_LIST", "name": "Test List Def", "category": "GENERAL_SECURITY"},
"definition": [
{
"cond_type": "attribute",
"resource_types": ["aws_s3_bucket"],
"attribute": "versioning.enabled",
"operator": "equals",
"value": "true",
},
{
"cond_type": "attribute",
"resource_types": ["aws_s3_bucket"],
"attribute": "server_side_encryption_configuration",
"operator": "exists",
},
],
}

check = parser.parse_raw_check(raw_check)

assert check.id == "TEST_LIST"
assert check.type == SolverType.COMPLEX
assert check.operator == "and"
assert len(check.sub_checks) == 2
assert check.sub_checks[0].attribute == "versioning.enabled"
assert check.sub_checks[1].attribute == "server_side_encryption_configuration"
Loading