File: components.py

package info (click to toggle)
scap-security-guide 0.1.76-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 110,644 kB
  • sloc: xml: 241,883; sh: 73,777; python: 32,527; makefile: 27
file content (146 lines) | stat: -rw-r--r-- 5,144 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
"""
Common functions for processing Components in SSG
"""

from __future__ import print_function

from collections import defaultdict
import os

import ssg.yaml


def load(components_dir):
    """
    Load components from a specified directory.

    Args:
        components_dir (str): The directory path containing component files.

    Returns:
        dict: A dictionary where the keys are component names and the values are component objects.
    """
    components = {}
    for component_filename in os.listdir(components_dir):
        components_filepath = os.path.join(components_dir, component_filename)
        component = Component(components_filepath)
        components[component.name] = component
    return components


def _reverse_mapping(components, attribute):
    """
    Creates a reverse mapping from the given attribute of components to the component names.

    Args:
        components (dict): A dictionary where keys are component names and values are component objects.
        attribute (str): The attribute of the component object to be used for creating the reverse mapping.

    Returns:
        defaultdict: A dictionary where keys are attribute values and values are lists of
                     component names that have that attribute value.
    """
    mapping = defaultdict(list)
    for component in components.values():
        for item in getattr(component, attribute):
            mapping[item].append(component.name)
    return mapping


def package_component_mapping(components):
    """
    Maps the given components to their respective packages.

    Args:
        components (dict): A dictionary where keys are component names and values are component details.

    Returns:
        dict: A dictionary where keys are package names and values are lists of components
              associated to those packages.
    """
    return _reverse_mapping(components, "packages")


def template_component_mapping(components):
    """
    Maps the given components to their corresponding templates.

    Args:
        components (dict): A dictionary where keys are component names and values are component details.

    Returns:
        dict: A dictionary where keys are template names and values are lists of components that
              use those templates.
    """
    return _reverse_mapping(components, "templates")


def group_component_mapping(components):
    """
    Groups components by their associated groups.

    Args:
        components (dict): A dictionary where keys are component names and values are dictionaries
                           containing component attributes, including a "groups" key.

    Returns:
        dict: A dictionary where keys are group names and values are lists of component names
              that belong to each group.
    """
    return _reverse_mapping(components, "groups")


def rule_component_mapping(components):
    """
    Maps the given components to their corresponding rules.

    Args:
        components (dict): A dictionary where keys are component names and values are component details.

    Returns:
        dict: A dictionary where keys are rule names and values are the corresponding components.
    """
    return _reverse_mapping(components, "rules")


class Component:
    """
    A class to represent a component.
    With regards to the content, a component usually represents a piece of software.

    Attributes:
        name (str): The name of the component.
        rules (list): A list of rules associated with the component.
        packages (list): A list of packages associated with the component.
        templates (list, optional): A list of templates associated with the component. Defaults to an empty list.
        groups (list, optional): A list of groups associated with the component. Defaults to an empty list.
        changelog (list, optional): A list of changelog entries for the component. Defaults to an empty list.
    """
    def __init__(self, filepath):
        yaml_data = ssg.yaml.open_raw(filepath)
        self.name = yaml_data["name"]
        self.rules = yaml_data["rules"]
        self.packages = yaml_data["packages"]
        self.templates = yaml_data.get("templates", [])
        self.groups = yaml_data.get("groups", [])
        self.changelog = yaml_data.get("changelog", [])


def get_rule_to_components_mapping(components):
    """
    Generates a mapping from rule IDs to component names.

    Args:
        components (dict): A dictionary where the keys are component names and the values are component objects.
                           Each component object is expected to have a 'rules' attribute (a list of rule IDs)
                           and a 'name' attribute (the name of the component).

    Returns:
        dict: A dictionary where the keys are rule IDs and the values are lists of component names
              that include the corresponding rule ID.
    """
    rule_to_components = defaultdict(list)
    for component in components.values():
        for rule_id in component.rules:
            rule_to_components[rule_id].append(component.name)
    return rule_to_components