Passed
Pull Request — master (#3188)
by Alexander
02:25
created

ssg.rules.find_rule_dirs()   A

Complexity

Conditions 4

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 6
nop 1
dl 0
loc 9
ccs 6
cts 6
cp 1
crap 4
rs 10
c 0
b 0
f 0
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
9
10 1
def get_rule_dir_yaml(dir_path):
11
    """
12
    Returns the path to the yaml metadata for a rule directory,
13
    regardless of if it exists.
14
    """
15 1
    return os.path.join(dir_path, "rule.yml")
16
17
18 1
def get_rule_dir_id(path):
19
    """
20
    Returns the ID of a rule directory; correctly handles being passed
21
    either the directory path or the yaml metadata path.
22
    """
23 1
    dir_path = path
24
25 1
    if path.endswith("rule.yml"):
26 1
        dir_path = os.path.dirname(path)
27
28 1
    return os.path.basename(dir_path)
29
30
31 1
def is_rule_dir(dir_path):
32
    """
33
    Returns True iff dir_path is a valid rule directory which exists
34
35
    To be valid, dir_path must exist and be a directory and the file
36
    returned by get_rule_dir_yaml(dir_path) must exist.
37
    """
38 1
    rule_yaml = get_rule_dir_yaml(dir_path)
39
40 1
    is_dir = os.path.isdir(dir_path)
41 1
    has_rule_yaml = os.path.exists(rule_yaml)
42
43 1
    return is_dir and has_rule_yaml
44
45
46 1
def _applies_to_product(file_name, product):
47
    """
48
    A OVAL or fix is filtered by product iff product is Falsy, file_name is
49
    "shared", or file_name is product. Note that this does not filter by
50
    contents of the fix or check, only by the name of the file.
51
    """
52
53 1
    return not product or (file_name == "shared" or file_name == product)
54
55
56 1
def get_rule_dir_ovals(dir_path, product=None):
57
    """
58
    Gets a list of OVALs contained in a rule directory. If product is
59
    None, returns all OVALs. If product is not None, returns applicable
60
    OVALs in order of priority:
61
62
        {{{ product }}}.xml -> shared.xml
63
64
    Only returns OVALs which exist.
65
    """
66
67 1
    if not is_rule_dir(dir_path):
68
        return []
69
70 1
    oval_dir = os.path.join(dir_path, "oval")
71 1
    has_oval_dir = os.path.isdir(oval_dir)
72 1
    if not has_oval_dir:
73
        return []
74
75 1
    results = []
76 1
    for oval_file in os.listdir(oval_dir):
77 1
        file_name, ext = os.path.splitext(oval_file)
78 1
        oval_path = os.path.join(oval_dir, oval_file)
79
80 1
        if ext == ".xml" and _applies_to_product(file_name, product):
81 1
            if file_name == 'shared':
82 1
                results.append(oval_path)
83
            else:
84 1
                results.insert(0, oval_path)
85
86 1
    return results
87
88
89 1
def get_rule_dir_remediations(dir_path, remediation_type, product=None):
90
    """
91
    Gets a list of remediations of type remediation_type contained in a
92
    rule directory. If product is None, returns all such remediations.
93
    If product is not None, returns applicable remediations in order of
94
    priority:
95
96
        {{{ product }}}.ext -> shared.ext
97
98
    Only returns remediations which exist.
99
    """
100
101 1
    if not is_rule_dir(dir_path):
102
        return []
103
104 1
    remediations_dir = os.path.join(dir_path, remediation_type)
105 1
    has_remediations_dir = os.path.isdir(remediations_dir)
106 1
    ext = REMEDIATION_MAP[remediation_type]
107 1
    if not has_remediations_dir:
108
        return []
109
110 1
    results = []
111 1
    for remediation_file in os.listdir(remediations_dir):
112 1
        file_name, file_ext = os.path.splitext(remediation_file)
113 1
        remediation_path = os.path.join(remediations_dir, remediation_file)
114
115 1
        if file_ext == ext and _applies_to_product(file_name, product):
116 1
            if file_name == 'shared':
117
                results.append(remediation_path)
118
            else:
119 1
                results.insert(0, remediation_path)
120
121 1
    return results
122
123
124 1
def find_rule_dirs(base_dir):
125
    """
126
    Generator which yields all rule_directories within a given base_dir
127
    """
128 1
    for root, dirs, _ in os.walk(base_dir):
129 1
        for dir_name in dirs:
130 1
            dir_path = os.path.join(root, dir_name)
131 1
            if is_rule_dir(dir_path):
132
                yield dir_path
133