mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 14:55:00 +00:00
feat(list-groups): List available groups (#1213)
This commit is contained in:
22
groups.json
22
groups.json
@@ -1,12 +1,18 @@
|
|||||||
{
|
{
|
||||||
"aws": {
|
"aws": {
|
||||||
"gdpr": [
|
"gdpr": {
|
||||||
"check11",
|
"checks": [
|
||||||
"check12"
|
"check11",
|
||||||
],
|
"check12"
|
||||||
"iam": [
|
],
|
||||||
"iam_disable_30_days_credentials",
|
"description": "GDPR Readiness"
|
||||||
"iam_disable_90_days_credentials"
|
},
|
||||||
]
|
"iam": {
|
||||||
|
"checks": [
|
||||||
|
"iam_disable_30_days_credentials",
|
||||||
|
"iam_disable_90_days_credentials"
|
||||||
|
],
|
||||||
|
"description": "Identity and Access Management"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import pkgutil
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from colorama import Fore, Style
|
from colorama import Fore, Style
|
||||||
|
|
||||||
@@ -24,8 +25,10 @@ def exclude_groups_to_run(
|
|||||||
checks_to_execute: set, excluded_groups: list, provider: str
|
checks_to_execute: set, excluded_groups: list, provider: str
|
||||||
) -> set:
|
) -> set:
|
||||||
# Recover checks from the input groups
|
# Recover checks from the input groups
|
||||||
|
available_groups = parse_groups_from_file(groups_file)
|
||||||
checks_from_groups = parse_groups_from_file(groups_file, excluded_groups, provider)
|
checks_from_groups = load_checks_to_execute_from_groups(
|
||||||
|
available_groups, excluded_groups, provider
|
||||||
|
)
|
||||||
for check_name in checks_from_groups:
|
for check_name in checks_from_groups:
|
||||||
checks_to_execute.discard(check_name)
|
checks_to_execute.discard(check_name)
|
||||||
return checks_to_execute
|
return checks_to_execute
|
||||||
@@ -61,15 +64,32 @@ def parse_checks_from_file(input_file: str, provider: str) -> set:
|
|||||||
return checks_to_execute
|
return checks_to_execute
|
||||||
|
|
||||||
|
|
||||||
# Load checks from groups.json
|
# List available groups
|
||||||
def parse_groups_from_file(group_file: str, group_list: list, provider: str) -> set:
|
def list_groups(provider: str) -> list:
|
||||||
checks_to_execute = set()
|
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)
|
f = open_file(group_file)
|
||||||
available_groups = parse_json_file(f)
|
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:
|
for group in group_list:
|
||||||
if group in available_groups[provider]:
|
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)
|
checks_to_execute.add(check_name)
|
||||||
else:
|
else:
|
||||||
logger.error(
|
logger.error(
|
||||||
@@ -120,8 +140,9 @@ def load_checks_to_execute(
|
|||||||
# Handle if there are groups passed using -g/--groups
|
# Handle if there are groups passed using -g/--groups
|
||||||
elif group_list:
|
elif group_list:
|
||||||
try:
|
try:
|
||||||
checks_to_execute = parse_groups_from_file(
|
available_groups = parse_groups_from_file(groups_file)
|
||||||
groups_file, group_list, provider
|
checks_to_execute = load_checks_to_execute_from_groups(
|
||||||
|
available_groups, group_list, provider
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{e.__class__.__name__} -- {e}")
|
logger.error(f"{e.__class__.__name__} -- {e}")
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from lib.check.check import (
|
|||||||
exclude_checks_to_run,
|
exclude_checks_to_run,
|
||||||
exclude_groups_to_run,
|
exclude_groups_to_run,
|
||||||
exclude_services_to_run,
|
exclude_services_to_run,
|
||||||
|
load_checks_to_execute_from_groups,
|
||||||
parse_checks_from_file,
|
parse_checks_from_file,
|
||||||
parse_groups_from_file,
|
parse_groups_from_file,
|
||||||
)
|
)
|
||||||
@@ -19,7 +20,35 @@ class Test_Check:
|
|||||||
# }
|
# }
|
||||||
# ]
|
# ]
|
||||||
# for test in test_cases:
|
# 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):
|
def test_parse_checks_from_file(self):
|
||||||
test_cases = [
|
test_cases = [
|
||||||
@@ -36,23 +65,40 @@ class Test_Check:
|
|||||||
provider = test["input"]["provider"]
|
provider = test["input"]["provider"]
|
||||||
assert parse_checks_from_file(check_file, provider) == test["expected"]
|
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 = [
|
test_cases = [
|
||||||
{
|
{
|
||||||
"input": {
|
"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",
|
"provider": "aws",
|
||||||
"group_file": f"{os.path.dirname(os.path.realpath(__name__))}/groups.json",
|
"groups": ["gdpr"],
|
||||||
},
|
},
|
||||||
"expected": {"check11", "check12"},
|
"expected": {"check11", "check12"},
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
for test in test_cases:
|
for test in test_cases:
|
||||||
provider = test["input"]["provider"]
|
provider = test["input"]["provider"]
|
||||||
groups = test["input"]["groups"]
|
groups = test["input"]["groups"]
|
||||||
group_file = test["input"]["group_file"]
|
group_file = test["input"]["groups_json"]
|
||||||
|
|
||||||
assert (
|
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):
|
def test_exclude_checks_to_run(self):
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
{
|
{
|
||||||
"aws": {
|
"aws": {
|
||||||
"gdpr": [
|
"gdpr": {
|
||||||
"check11",
|
"checks": [
|
||||||
"check12"
|
"check11",
|
||||||
]
|
"check12"
|
||||||
|
],
|
||||||
|
"description": "GDPR Readiness"
|
||||||
|
},
|
||||||
|
"iam": {
|
||||||
|
"checks": [
|
||||||
|
"iam_disable_30_days_credentials",
|
||||||
|
"iam_disable_90_days_credentials"
|
||||||
|
],
|
||||||
|
"description": "Identity and Access Management"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from lib.check.check import (
|
|||||||
exclude_groups_to_run,
|
exclude_groups_to_run,
|
||||||
exclude_services_to_run,
|
exclude_services_to_run,
|
||||||
import_check,
|
import_check,
|
||||||
|
list_groups,
|
||||||
load_checks_to_execute,
|
load_checks_to_execute,
|
||||||
run_check,
|
run_check,
|
||||||
set_output_options,
|
set_output_options,
|
||||||
@@ -28,7 +29,7 @@ if __name__ == "__main__":
|
|||||||
group.add_argument("-C", "--checks-file", nargs="?", help="List of checks")
|
group.add_argument("-C", "--checks-file", nargs="?", help="List of checks")
|
||||||
group.add_argument("-s", "--services", nargs="+", help="List of services")
|
group.add_argument("-s", "--services", nargs="+", help="List of services")
|
||||||
group.add_argument("-g", "--groups", nargs="+", help="List of groups")
|
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-checks", nargs="+", help="Checks to exclude")
|
||||||
parser.add_argument("-E", "--excluded-groups", nargs="+", help="Groups to exclude")
|
parser.add_argument("-E", "--excluded-groups", nargs="+", help="Groups to exclude")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
@@ -123,6 +124,10 @@ if __name__ == "__main__":
|
|||||||
if args.no_banner:
|
if args.no_banner:
|
||||||
print_banner()
|
print_banner()
|
||||||
|
|
||||||
|
if args.list_groups:
|
||||||
|
list_groups(provider)
|
||||||
|
quit()
|
||||||
|
|
||||||
# Setting output options
|
# Setting output options
|
||||||
set_output_options(args.quiet)
|
set_output_options(args.quiet)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user