Skip to content

Commit

Permalink
Create profile per rule
Browse files Browse the repository at this point in the history
  • Loading branch information
Honny1 committed Feb 9, 2024
1 parent e626604 commit 28fb558
Showing 1 changed file with 53 additions and 4 deletions.
57 changes: 53 additions & 4 deletions build-scripts/compile_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import ssg.environment
from ssg.build_cpe import ProductCPEs
from ssg.constants import BENCHMARKS
from ssg.entities.profile import ProfileWithInlinePolicies


def create_parser():
parser = argparse.ArgumentParser()
Expand Down Expand Up @@ -41,6 +43,11 @@ def create_parser():
parser.add_argument(
"--stig-references", help="DISA STIG Reference XCCDF file"
)
parser.add_argument(
"--rule-id",
type=str,
help="Creates a profile with the specified rule and does not use other profiles.",
)
return parser


Expand Down Expand Up @@ -110,9 +117,11 @@ def save_everything(base_dir, loader, controls_manager, profiles):
dump_compiled_profile(base_dir, p)


def find_existing_rules(project_root):
def find_existing_rules(project_root, relevant_benchmarks=None):
rules = set()
for benchmark in BENCHMARKS:
if relevant_benchmarks is None:
relevant_benchmarks = BENCHMARKS
for benchmark in relevant_benchmarks:
benchmark = os.path.join(project_root, benchmark)
for dirpath, _, filenames in os.walk(benchmark):
if "rule.yml" in filenames:
Expand All @@ -121,6 +130,40 @@ def find_existing_rules(project_root):
return rules


def get_relevant_benchmarks(env_yaml, product_yaml):
benchmark_paths = get_all_content_directories(env_yaml, product_yaml)
out = set()
for benchmark in BENCHMARKS:
for path in benchmark_paths:
if benchmark in path:
out.add(benchmark)
return out


def get_minimal_profiles_by_id(rules, variables):
out = {}
for rule in rules:
data = {
'documentation_complete': True,
'variables': variables,
'selected': [rule],
'id_': 'thin_ds_{}'.format(rule),
}
profile = ProfileWithInlinePolicies.get_instance_from_full_dict(data)
out[profile.id_] = profile
return out


def get_profiles_per_rule_by_id(rule_id, project_root_abspath, env_yaml, product_yaml):
relevant_benchmarks = get_relevant_benchmarks(env_yaml, product_yaml)
rules = find_existing_rules(project_root_abspath, relevant_benchmarks)
if rule_id not in rules and "ALL_RULES" not in rule_id:
raise Exception("Rule ID: {} not found!".format(rule_id))
if "ALL_RULES" not in rule_id:
rules = [rule_id]
return get_minimal_profiles_by_id(rules, {})


def main():
parser = create_parser()
args = parser.parse_args()
Expand Down Expand Up @@ -158,8 +201,14 @@ def main():
controls_manager.remove_selections_not_known(loader.all_rules)
controls_manager.add_references(loader.all_rules)

profiles_by_id = get_all_resolved_profiles_by_id(
env_yaml, product_yaml, loader, product_cpes, controls_manager, controls_dir)
if args.rule_id is None or args.rule_id == "off":
profiles_by_id = get_all_resolved_profiles_by_id(
env_yaml, product_yaml, loader, product_cpes, controls_manager, controls_dir
)
else:
profiles_by_id = get_profiles_per_rule_by_id(
args.rule_id, project_root_abspath, env_yaml, product_yaml
)

save_everything(
args.resolved_base, loader, controls_manager, profiles_by_id.values())
Expand Down

0 comments on commit 28fb558

Please sign in to comment.