Passed
Pull Request — master (#3193)
by Alexander
02:07
created

ssg.rules   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Test Coverage

Coverage 92.42%

Importance

Changes 0
Metric Value
eloc 68
dl 0
loc 156
ccs 61
cts 66
cp 0.9242
rs 10
c 0
b 0
f 0
wmc 29

8 Functions

Rating   Name   Duplication   Size   Complexity  
B get_rule_dir_ovals() 0 31 7
A is_rule_dir() 0 13 1
B get_rule_dir_remediations() 0 33 7
A find_rule_dirs() 0 9 4
A get_rule_dir_yaml() 0 6 1
A get_rule_dir_id() 0 11 2
A _applies_to_product() 0 8 1
B is_applicable() 0 20 6
1 1
from __future__ import absolute_import
0 ignored issues
show
Coding Style introduced by
This module should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
2 1
from __future__ import print_function
3
4 1
import os
5
6
7 1
from .build_remediations import REMEDIATION_TO_EXT_MAP as REMEDIATION_MAP
8 1
from .build_remediations import is_applicable_for_product
9
10
11 1
def is_applicable(platform, product):
12
    """
13
    Function to check if a platform is applicable for the product.
14
    Handles when a platform is really a list of products, i.e., a
15
    prodtype field from a rule.yml.
16
17
    Returns true iff product is applicable for the platform or list
18
    of products
19
    """
20
21 1
    if platform == 'all' or platform == 'multi_platform_all':
22 1
        return True
23
24 1
    if is_applicable_for_product(platform, product):
25 1
        return True
26
27 1
    if 'osp7' in product and 'osp7' in platform:
28 1
        return True
29
30 1
    return product in platform.split(',')
31
32
33 1
def get_rule_dir_yaml(dir_path):
34
    """
35
    Returns the path to the yaml metadata for a rule directory,
36
    regardless of if it exists.
37
    """
38 1
    return os.path.join(dir_path, "rule.yml")
39
40
41 1
def get_rule_dir_id(path):
42
    """
43
    Returns the ID of a rule directory; correctly handles being passed
44
    either the directory path or the yaml metadata path.
45
    """
46 1
    dir_path = path
47
48 1
    if path.endswith("rule.yml"):
49 1
        dir_path = os.path.dirname(path)
50
51 1
    return os.path.basename(dir_path)
52
53
54 1
def is_rule_dir(dir_path):
55
    """
56
    Returns True iff dir_path is a valid rule directory which exists
57
58
    To be valid, dir_path must exist and be a directory and the file
59
    returned by get_rule_dir_yaml(dir_path) must exist.
60
    """
61 1
    rule_yaml = get_rule_dir_yaml(dir_path)
62
63 1
    is_dir = os.path.isdir(dir_path)
64 1
    has_rule_yaml = os.path.exists(rule_yaml)
65
66 1
    return is_dir and has_rule_yaml
67
68
69 1
def _applies_to_product(file_name, product):
70
    """
71
    A OVAL or fix is filtered by product iff product is Falsy, file_name is
72
    "shared", or file_name is product. Note that this does not filter by
73
    contents of the fix or check, only by the name of the file.
74
    """
75
76 1
    return not product or (file_name == "shared" or file_name == product)
77
78
79 1
def get_rule_dir_ovals(dir_path, product=None):
80
    """
81
    Gets a list of OVALs contained in a rule directory. If product is
82
    None, returns all OVALs. If product is not None, returns applicable
83
    OVALs in order of priority:
84
85
        {{{ product }}}.xml -> shared.xml
86
87
    Only returns OVALs which exist.
88
    """
89
90 1
    if not is_rule_dir(dir_path):
91
        return []
92
93 1
    oval_dir = os.path.join(dir_path, "oval")
94 1
    has_oval_dir = os.path.isdir(oval_dir)
95 1
    if not has_oval_dir:
96
        return []
97
98 1
    results = []
99 1
    for oval_file in os.listdir(oval_dir):
100 1
        file_name, ext = os.path.splitext(oval_file)
101 1
        oval_path = os.path.join(oval_dir, oval_file)
102
103 1
        if ext == ".xml" and _applies_to_product(file_name, product):
104 1
            if file_name == 'shared':
105 1
                results.append(oval_path)
106
            else:
107 1
                results.insert(0, oval_path)
108
109 1
    return results
110
111
112 1
def get_rule_dir_remediations(dir_path, remediation_type, product=None):
113
    """
114
    Gets a list of remediations of type remediation_type contained in a
115
    rule directory. If product is None, returns all such remediations.
116
    If product is not None, returns applicable remediations in order of
117
    priority:
118
119
        {{{ product }}}.ext -> shared.ext
120
121
    Only returns remediations which exist.
122
    """
123
124 1
    if not is_rule_dir(dir_path):
125
        return []
126
127 1
    remediations_dir = os.path.join(dir_path, remediation_type)
128 1
    has_remediations_dir = os.path.isdir(remediations_dir)
129 1
    ext = REMEDIATION_MAP[remediation_type]
130 1
    if not has_remediations_dir:
131
        return []
132
133 1
    results = []
134 1
    for remediation_file in os.listdir(remediations_dir):
135 1
        file_name, file_ext = os.path.splitext(remediation_file)
136 1
        remediation_path = os.path.join(remediations_dir, remediation_file)
137
138 1
        if file_ext == ext and _applies_to_product(file_name, product):
139 1
            if file_name == 'shared':
140
                results.append(remediation_path)
141
            else:
142 1
                results.insert(0, remediation_path)
143
144 1
    return results
145
146
147 1
def find_rule_dirs(base_dir):
148
    """
149
    Generator which yields all rule_directories within a given base_dir
150
    """
151 1
    for root, dirs, _ in os.walk(base_dir):
152 1
        for dir_name in dirs:
153 1
            dir_path = os.path.join(root, dir_name)
154 1
            if is_rule_dir(dir_path):
155
                yield dir_path
156