Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(fixer): add Prowler Fixer feature! #3634

Merged
merged 20 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
33 changes: 26 additions & 7 deletions prowler/lib/check/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,14 @@ def import_check(check_path: str) -> ModuleType:


def run_check(check: Check, output_options) -> list:
"""
Run the check and return the findings
Args:
check (Check): check class
output_options (Any): output options
Returns:
list: list of findings
"""
findings = []
if output_options.verbose:
print(
Expand All @@ -419,9 +427,16 @@ def run_check(check: Check, output_options) -> list:
return findings


def run_fixer(check_findings, check_name, c):
def run_fixer(check_findings: list, check_name: str, check_class: Check):
"""
Run the fixer for the check if it exists and there are any FAIL findings
Args:
check_findings (list): list of findings
check_name (str): check name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you don't need the check name here, you can use check.CheckID.

check_class (Check): check class
"""
try:
fixer = getattr(c, "fixer")
fixer = getattr(check_class, "fixer")
# Check if there are any FAIL findings
if any("FAIL" in finding.status for finding in check_findings):
print(
Expand Down Expand Up @@ -593,14 +608,18 @@ def execute(
lib = import_check(check_module_path)
# Recover functions from check
check_to_execute = getattr(lib, check_name)
c = check_to_execute()
check_class = check_to_execute()

# Update check metadata to reflect that in the outputs
if custom_checks_metadata and custom_checks_metadata["Checks"].get(c.CheckID):
c = update_check_metadata(c, custom_checks_metadata["Checks"][c.CheckID])
if custom_checks_metadata and custom_checks_metadata["Checks"].get(
check_class.CheckID
):
check_class = update_check_metadata(
check_class, custom_checks_metadata["Checks"][check_class.CheckID]
)

# Run check
check_findings = run_check(c, global_provider.output_options)
check_findings = run_check(check_class, global_provider.output_options)

# Update Audit Status
services_executed.add(service)
Expand All @@ -621,7 +640,7 @@ def execute(

# Prowler Fixer
if args.fix and args.check:
run_fixer(check_findings, check_name, c)
run_fixer(check_findings, check_name, check_class)

if os.environ.get("PROWLER_REPORT_LIB_PATH"):
try:
Expand Down
16 changes: 16 additions & 0 deletions tests/providers/aws/services/ec2/ec2_service_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,3 +544,19 @@ def test__describe_volumes__(self):
assert ec2.volumes[0].tags == [
{"Key": "test", "Value": "test"},
]

# Test EC2 EBS Enabling Encryption by Default
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lovely!

@mock_aws
def test__describe_ebs_encryption_by_default__(self):
# Generate EC2 Client
ec2_client = client("ec2", region_name=AWS_REGION_US_EAST_1)

# EC2 client for this test class
aws_provider = set_mocked_aws_provider(
[AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1]
)
ec2 = EC2(aws_provider)

assert not ec2.__enable_ebs_encryption_by_default__()
ec2_client.enable_ebs_encryption_by_default()
assert ec2.__enable_ebs_encryption_by_default__()
Loading