feat(list-groups): List available groups (#1213)

This commit is contained in:
Pepe Fagoaga
2022-06-22 09:59:48 +02:00
committed by GitHub
parent ecefda11c7
commit b07b7f3f26
5 changed files with 115 additions and 27 deletions

View File

@@ -1,12 +1,18 @@
{
"aws": {
"gdpr": [
"check11",
"check12"
],
"iam": [
"iam_disable_30_days_credentials",
"iam_disable_90_days_credentials"
]
"gdpr": {
"checks": [
"check11",
"check12"
],
"description": "GDPR Readiness"
},
"iam": {
"checks": [
"iam_disable_30_days_credentials",
"iam_disable_90_days_credentials"
],
"description": "Identity and Access Management"
}
}
}

View File

@@ -3,6 +3,7 @@ import pkgutil
from abc import ABC, abstractmethod
from dataclasses import dataclass
from types import ModuleType
from typing import Any
from colorama import Fore, Style
@@ -24,8 +25,10 @@ def exclude_groups_to_run(
checks_to_execute: set, excluded_groups: list, provider: str
) -> set:
# Recover checks from the input groups
checks_from_groups = parse_groups_from_file(groups_file, excluded_groups, provider)
available_groups = parse_groups_from_file(groups_file)
checks_from_groups = load_checks_to_execute_from_groups(
available_groups, excluded_groups, provider
)
for check_name in checks_from_groups:
checks_to_execute.discard(check_name)
return checks_to_execute
@@ -61,15 +64,32 @@ def parse_checks_from_file(input_file: str, provider: str) -> set:
return checks_to_execute
# Load checks from groups.json
def parse_groups_from_file(group_file: str, group_list: list, provider: str) -> set:
checks_to_execute = set()
# List available groups
def list_groups(provider: str) -> list:
groups = parse_groups_from_file(groups_file)
print(f"Available Groups:")
for group, value in groups[provider].items():
group_description = value["description"]
print(f"\t - {group_description} -- [{group}] ")
# Parse groups from groups.json
def parse_groups_from_file(group_file: str) -> Any:
f = open_file(group_file)
available_groups = parse_json_file(f)
return available_groups
# Parse checks from groups to execute
def load_checks_to_execute_from_groups(
available_groups: Any, group_list: list, provider: str
) -> set:
checks_to_execute = set()
for group in group_list:
if group in available_groups[provider]:
for check_name in available_groups[provider][group]:
for check_name in available_groups[provider][group]["checks"]:
checks_to_execute.add(check_name)
else:
logger.error(
@@ -120,8 +140,9 @@ def load_checks_to_execute(
# Handle if there are groups passed using -g/--groups
elif group_list:
try:
checks_to_execute = parse_groups_from_file(
groups_file, group_list, provider
available_groups = parse_groups_from_file(groups_file)
checks_to_execute = load_checks_to_execute_from_groups(
available_groups, group_list, provider
)
except Exception as e:
logger.error(f"{e.__class__.__name__} -- {e}")

View File

@@ -4,6 +4,7 @@ from lib.check.check import (
exclude_checks_to_run,
exclude_groups_to_run,
exclude_services_to_run,
load_checks_to_execute_from_groups,
parse_checks_from_file,
parse_groups_from_file,
)
@@ -19,7 +20,35 @@ class Test_Check:
# }
# ]
# for test in test_cases:
# assert importlib.import_module(test["input"]).__name__ == test["expected"]
# assert importlib.import_module(test["input"]).__name__ == test["expected"
def test_parse_groups_from_file(self):
test_cases = [
{
"input": {
"path": f"{os.path.dirname(os.path.realpath(__file__))}/fixtures/groupsA.json",
"provider": "aws",
},
"expected": {
"aws": {
"gdpr": {
"description": "GDPR Readiness",
"checks": ["check11", "check12"],
},
"iam": {
"description": "Identity and Access Management",
"checks": [
"iam_disable_30_days_credentials",
"iam_disable_90_days_credentials",
],
},
}
},
}
]
for test in test_cases:
check_file = test["input"]["path"]
assert parse_groups_from_file(check_file) == test["expected"]
def test_parse_checks_from_file(self):
test_cases = [
@@ -36,23 +65,40 @@ class Test_Check:
provider = test["input"]["provider"]
assert parse_checks_from_file(check_file, provider) == test["expected"]
def test_parse_groups_from_file(self):
def test_load_checks_to_execute_from_groups(self):
test_cases = [
{
"input": {
"groups": ["gdpr"],
"groups_json": {
"aws": {
"gdpr": {
"description": "GDPR Readiness",
"checks": ["check11", "check12"],
},
"iam": {
"description": "Identity and Access Management",
"checks": [
"iam_disable_30_days_credentials",
"iam_disable_90_days_credentials",
],
},
}
},
"provider": "aws",
"group_file": f"{os.path.dirname(os.path.realpath(__name__))}/groups.json",
"groups": ["gdpr"],
},
"expected": {"check11", "check12"},
}
]
for test in test_cases:
provider = test["input"]["provider"]
groups = test["input"]["groups"]
group_file = test["input"]["group_file"]
group_file = test["input"]["groups_json"]
assert (
parse_groups_from_file(group_file, groups, provider) == test["expected"]
load_checks_to_execute_from_groups(group_file, groups, provider)
== test["expected"]
)
def test_exclude_checks_to_run(self):

View File

@@ -1,8 +1,18 @@
{
"aws": {
"gdpr": [
"check11",
"check12"
]
"gdpr": {
"checks": [
"check11",
"check12"
],
"description": "GDPR Readiness"
},
"iam": {
"checks": [
"iam_disable_30_days_credentials",
"iam_disable_90_days_credentials"
],
"description": "Identity and Access Management"
}
}
}

View File

@@ -9,6 +9,7 @@ from lib.check.check import (
exclude_groups_to_run,
exclude_services_to_run,
import_check,
list_groups,
load_checks_to_execute,
run_check,
set_output_options,
@@ -28,7 +29,7 @@ if __name__ == "__main__":
group.add_argument("-C", "--checks-file", nargs="?", help="List of checks")
group.add_argument("-s", "--services", nargs="+", help="List of services")
group.add_argument("-g", "--groups", nargs="+", help="List of groups")
group.add_argument("-L", "--list-groups", action="store_true", help="List groups")
parser.add_argument("-e", "--excluded-checks", nargs="+", help="Checks to exclude")
parser.add_argument("-E", "--excluded-groups", nargs="+", help="Groups to exclude")
parser.add_argument(
@@ -123,6 +124,10 @@ if __name__ == "__main__":
if args.no_banner:
print_banner()
if args.list_groups:
list_groups(provider)
quit()
# Setting output options
set_output_options(args.quiet)