-
Notifications
You must be signed in to change notification settings - Fork 684
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
Tool for identifying the most used components #11730
Changes from 4 commits
e76069c
f269129
0b3652a
271693b
e7095b8
6f2e505
585a0e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
from .sub import command_sub | ||
from .stats import command_stats | ||
from .most_used_rules import command_most_used_rules | ||
from .most_used_components import command_most_used_components |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import json | ||
import sys | ||
import os | ||
from ssg.components import Component | ||
from .most_used_rules import _sorted_dict_by_num_value | ||
|
||
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, | ||
get_available_products, | ||
) | ||
|
||
|
||
def _count_components(components, rules_list, components_out): | ||
for rule in rules_list: | ||
component = get_component_name_by_rule_id(rule, components) | ||
if component in components_out: | ||
components_out[component] += 1 | ||
else: | ||
components_out[component] = 1 | ||
|
||
|
||
def get_component_name_by_rule_id(rule_id, components): | ||
for component in components.values(): | ||
if rule_id in component.rules: | ||
return component.name | ||
return "without_component" | ||
|
||
|
||
def load_components(components_dir): | ||
components = {} | ||
for component_file in os.listdir(os.path.abspath(components_dir)): | ||
component_path = os.path.join(components_dir, component_file) | ||
component = Component(component_path) | ||
components[component.name] = component | ||
return components | ||
|
||
|
||
def _process_all_products_from_controls(components_out): | ||
components = load_components("./components/") | ||
if PYTHON_2: | ||
raise Exception("This feature is not supported for python2.") | ||
|
||
for product in get_available_products(): | ||
controls_manager = load_controls_manager("./controls/", product) | ||
for profile in _get_profiles_for_product(controls_manager, product): | ||
_count_components(components, profile.rules, components_out) | ||
|
||
|
||
def command_most_used_components(args): | ||
components = {} | ||
|
||
_process_all_products_from_controls(components) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it doesn't make sense to combine results from all products to a single number. Currently from the output we can see that the selinux component is used 1660 times. But this number is the count of rules multiplied by their occurence in profiles multiplied by their occurence in products. I think that a product ID should be a parameter of this script and the results should be produced for the given product. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Limitation on product will be done by #11733 . |
||
|
||
sorted_components = _sorted_dict_by_num_value(components) | ||
|
||
f_string = "{}: {}" | ||
|
||
if args.format == "json": | ||
print(json.dumps(sorted_components, indent=4)) | ||
return | ||
elif args.format == "csv": | ||
print("component_name,count_of_rules") | ||
f_string = "{},{}" | ||
|
||
for rule_id, rule_count in sorted_components.items(): | ||
print(f_string.format(rule_id, rule_count)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this moment, we use "components" only for Fedora, RHEL 7, RHEL 8, RHEL 9 and RHEL 10 products. It doesn't make sense to include into stats any other products or any controls used in the products that don't use components.
One of consequences of this behavior is that we have
without_component: 12125
which involves all rules that aren't part of linux_os benchmark.If a product is using the "components" feature it sets the
components_root
key in its product.yml.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. I have improved the product selection to those with
components_root
.