Test Failed
Push — master ( 4fce08...e6b395 )
by Jan
02:34 queued 11s
created

utils.compare_disa_xml.check_paths()   A

Complexity

Conditions 5

Size

Total Lines 8
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 7
nop 1
dl 0
loc 8
ccs 0
cts 7
cp 0
crap 30
rs 9.3333
c 0
b 0
f 0
1
#!/usr/bin/env python3
2
3
import argparse
4
import os.path
5
import sys
6
import xml.etree.ElementTree as ET
7
8
try:
9
    import ssg.constants
10
except ImportError:
11
    print("The ssg module could not be found.")
12
    print("Run .pyenv.sh available in the project root directory,"
13
          " or add it to PYTHONPATH manually.")
14
    print("$ source .pyenv.sh")
15
    exit(1)
16
17
18
def parse_args() -> argparse.Namespace:
19
    parser = argparse.ArgumentParser(description="Compare two DISA XML files to find the "
20
                                                 "differences.")
21
    parser.add_argument('base_path', help="The path to older XML document")
22
    parser.add_argument('target_path', help="The path to newer XML document")
23
    return parser.parse_args()
24
25
26
def get_rules(path: str) -> set:
27
    rules = set()
28
    root = ET.parse(path).getroot()
29
    groups = root.findall('xccdf-1.1:Group', ssg.constants.PREFIX_TO_NS)
30
    for group in groups:
31
        for stig in group.findall('xccdf-1.1:Rule', ssg.constants.PREFIX_TO_NS):
32
            stig_id = stig.find('xccdf-1.1:version', ssg.constants.PREFIX_TO_NS).text
33
            rules.add(stig_id)
34
    return rules
35
36
37
def check_paths(args: argparse.Namespace) -> None:
38
    if not os.path.exists(args.base_path) or not os.path.isfile(args.base_path):
39
        sys.stderr.write(f'Base path: {args.base_path} does not exist or is not a file.')
40
        exit(2)
41
    if not os.path.exists(args.target_path) or not os.path.isfile(args.target_path):
42
        sys.stderr.write(f'Target path: {args.target_path} does not exist or is not a file. '
43
                         f'{os.path.exists(args.target_path)}')
44
        exit(3)
45
46
47
def main():
48
    args = parse_args()
49
    check_paths(args)
50
    base_rules = get_rules(args.base_path)
51
    target_rules = get_rules(args.target_path)
52
    new_rules = target_rules - base_rules
53
    removed_rules = base_rules - target_rules
54
    print(f'Base count: {len(base_rules)}')
55
    print(f'Target count: {len(target_rules)}')
56
    print(f"New rules: ({len(new_rules)})")
57
    for rule in new_rules:
58
        print(f'\t{rule}')
59
60
    print(f"Removed rules ({len(removed_rules)})")
61
    for rule in removed_rules:
62
        print(f'\t{rule}')
63
64
65
if __name__ == '__main__':
66
    main()
67