Test Failed
Push — master ( 5f96f0...be9a44 )
by Jan
02:37 queued 15s
created

utils.controleval.print_options()   A

Complexity

Conditions 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 4
nop 1
dl 0
loc 5
ccs 0
cts 4
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
#!/usr/bin/env python3
2
import collections
3
import argparse
4
5
from ssg import controls
6
7
8
def print_options(opts):
9
    if len(opts) > 0:
10
        print("Available options are:\n - " + "\n - ".join(opts))
11
    else:
12
        print("The controls file is not written appropriately.")
13
14
15
def validate_args(ctrlmgr, args):
16
    """ Validates that the appropriate args were given
17
        and that they're valid entries in the control manager."""
18
19
    policy = None
20
    try:
21
        policy = ctrlmgr._get_policy(args.id)
22
    except ValueError as e:
23
        print("Error: ", e)
24
        print_options(ctrlmgr.policies.keys())
25
        exit(1)
26
27
    try:
28
        policy.get_level_with_ancestors_sequence(args.level)
29
    except ValueError as e:
30
        print("Error: ", e)
31
        print_options(policy.levels_by_id.keys())
32
        exit(1)
33
34
35
def calculate_stats(ctrls):
36
    total = len(ctrls)
37
    ctrlstats = collections.defaultdict(int)
38
39
    for ctrl in ctrls:
40
        ctrlstats[str(ctrl.status)] += 1
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable str does not seem to be defined.
Loading history...
41
42
    applicable = total - ctrlstats[controls.Status.NOT_APPLICABLE]
43
    assessed = ctrlstats[controls.Status.AUTOMATED] + ctrlstats[controls.Status.SUPPORTED] + \
44
        ctrlstats[controls.Status.DOCUMENTATION] + ctrlstats[controls.Status.INHERENTLY_MET] + \
45
        ctrlstats[controls.Status.PARTIAL]
46
47
    print("Total controls = {total}".format(total=total))
48
    print_specific_stat("Applicable", applicable, total)
49
    print_specific_stat("Assessed", assessed, applicable)
50
    print()
51
    print_specific_stat("Automated", ctrlstats[controls.Status.AUTOMATED], applicable)
52
    print_specific_stat("Supported", ctrlstats[controls.Status.SUPPORTED], applicable)
53
    print_specific_stat("Documentation", ctrlstats[controls.Status.DOCUMENTATION], applicable)
54
    print_specific_stat("Inherently Met", ctrlstats[controls.Status.INHERENTLY_MET], applicable)
55
    print_specific_stat("Partial", ctrlstats[controls.Status.PARTIAL], applicable)
56
57
58
def print_specific_stat(stat, current, total):
59
    print("{stat} = {percent}% -- {current} / {total}".format(
60
        stat=stat,
61
        percent=round((current / total) * 100.00, 2),
62
        current=current,
63
        total=total))
64
65
66
def stats(ctrlmgr, args):
67
    validate_args(ctrlmgr, args)
68
    ctrls = set(ctrlmgr.get_all_controls_of_level(args.id, args.level))
69
    calculate_stats(ctrls)
70
71
72
subcmds = dict(
73
    stats=stats
74
)
75
76
77
def create_parser():
78
    parser = argparse.ArgumentParser()
79
    parser.add_argument(
80
        "--controls-dir",
81
        help=("Directory that contains control files with policy controls. "
82
              "e.g.: ~/scap-security-guide/controls"),
83
        default="./controls/",
84
    )
85
    subparsers = parser.add_subparsers(dest="subcmd", required=True)
86
    statsparser = subparsers.add_parser(
87
        'stats',
88
        help="outputs statistics for the given benchmark and level.")
89
    statsparser.add_argument("-i", "--id", dest="id", help="id of the controls file.",
90
                             required=True)
91
    statsparser.add_argument("-l", "--level", dest="level", help="level to display statistics of.",
92
                             required=True)
93
    return parser
94
95
96
def main():
97
    parser = create_parser()
98
    args = parser.parse_args()
99
    controls_manager = controls.ControlsManager(args.controls_dir)
100
    controls_manager.load()
101
    subcmds[args.subcmd](controls_manager, args)
102
103
104
if __name__ == "__main__":
105
    main()
106