utils/profile_tool/most_used_components.py
import sys
import os
from collections import defaultdict
import ssg.components
from .most_used_rules import _sorted_dict_by_num_value
from .common import generate_output, merge_dicts, remove_zero_counts
PYTHON_2 = sys.version_info[0] < 3
if not PYTHON_2:
from .most_used_rules import _get_profiles_for_product
from ..controleval import (
load_controls_manager,
load_product_yaml,
)
def _count_rules_components(component_name, rules, used_rules_of_components_out):
used_rules = used_rules_of_components_out[component_name]
for rule in rules:
used_rules[rule] += 1
def _count_components(components, rules_list, components_out, used_rules_of_components_out):
for component_name, component in components.items():
intersection = set(component.rules).intersection(set(rules_list))
components_out[component_name] += 0
if len(intersection) > 0:
components_out[component_name] += 1
if component_name not in used_rules_of_components_out:
used_rules_of_components_out[component_name] = {
rule_id: 0 for rule_id in component.rules
}
_count_rules_components(component_name, intersection, used_rules_of_components_out)
def load_components(product):
product_yaml = load_product_yaml(product)
product_dir = product_yaml.get("product_dir")
components_root = product_yaml.get("components_root")
if components_root is None:
return None
components_dir = os.path.abspath(os.path.join(product_dir, components_root))
return ssg.components.load(components_dir)
def _process_all_products_from_controls(components_out, used_rules_of_components_out, products):
if PYTHON_2:
raise Exception("This feature is not supported for python2.")
for product in products:
components = load_components(product)
if components is None:
continue
controls_manager = load_controls_manager("./controls/", product)
for profile in _get_profiles_for_product(controls_manager, product):
_count_components(
components, profile.rules, components_out, used_rules_of_components_out
)
def _sort_rules_of_components(used_rules_of_components):
out = {}
for key, value in used_rules_of_components.items():
out[key] = _sorted_dict_by_num_value(value)
return out
def _remove_zero_counts_of(used_rules_of_components):
return {
component_name: remove_zero_counts(rules_dict)
for component_name, rules_dict in used_rules_of_components.items()
}
def command_most_used_components(args):
components = defaultdict(int)
used_rules_of_components = {}
_process_all_products_from_controls(components, used_rules_of_components, args.products)
if not args.all:
components = remove_zero_counts(components)
used_rules_of_components = _remove_zero_counts_of(used_rules_of_components)
sorted_components = _sorted_dict_by_num_value(components)
csv_header = "component_name,count_of_profiles"
if args.rules:
csv_header = "component_name,count_of_profiles,used_rules:count_of_profiles"
delim = " "
if args.format == "csv":
delim = ","
sorted_used_rules_of_components = _sort_rules_of_components(used_rules_of_components)
sorted_components = merge_dicts(sorted_components, sorted_used_rules_of_components, delim)
generate_output(sorted_components, args.format, csv_header)