#!/usr/bin/python3
from __future__ import print_function
import argparse
import re
import sys
import yaml
COMMENT_KEYS = set((
"platform",
"reboot",
"strategy",
"complexity",
"disruption",
))
TAGS = set((
"strategy",
"complexity",
"disruption",
"severity",
))
[docs]
def make_parser():
parser = argparse.ArgumentParser()
parser.add_argument("input", nargs="+")
parser.add_argument("--verbose", "-v", action="store_true")
parser.add_argument("--cce", action="store_true", help="Require CCEs to be defined as well")
return parser
[docs]
def validate_playbook(playbook, args):
assert "name" in playbook, "playbook doesn't have a name"
assert "hosts" in playbook, "playbook doesn't have the hosts entry"
assert playbook["hosts"] == "@@HOSTS@@", "playbook's hosts is not set to @@HOSTS@@"
assert "become" in playbook, "playbook doesn't have a become key"
assert playbook["become"], "become in the playbook is not set to a true-ish value"
if "vars" in playbook:
assert playbook["vars"], "there are no variables under the 'vars' key of the playbook"
assert "tasks" in playbook, "there are no tasks in the playbook"
first_task = playbook["tasks"][0]
if "block" in first_task:
first_task = first_task["block"][0]
assert "name" in first_task, "The first task doesn't have name"
assert "tags" in playbook, "the playbook doesn't have tags"
if args.verbose:
print("Basic playbook properties OK")
caught_tags = set()
tag_regex = re.compile(
r".*_({keys})"
.format(keys="|".join(TAGS)))
cce_regex = re.compile(r"CCE-[0-9]+-[0-9]+")
for tag in playbook["tags"]:
assert "@" not in tag, \
"A playbook tag {tag} contains @, which is unexpected.".format(tag=tag)
found = re.search(tag_regex, tag)
if found:
caught_tags.add(found.group(1))
if re.search(cce_regex, tag):
caught_tags.add("CCE")
tags_not_caught = TAGS.difference(caught_tags)
assert not tags_not_caught, \
"Missing tags: {stray}".format(stray=", ".join(tags_not_caught))
if args.verbose:
print("Playbook tags OK")
if args.cce:
assert "CCE" in caught_tags, "There is no CCE tag in the playbook"
if args.verbose:
print("Playbook CCE OK")
[docs]
def validate_yaml(fname, args):
stream = open(fname, "r")
data = yaml.load(stream, Loader=yaml.Loader)
for playbook in data:
validate_playbook(playbook, args)
if __name__ == "__main__":
parser = make_parser()
args = parser.parse_args()
ret = 0
for fname in args.input:
current_ret = validate_input(fname, args)
ret = max(current_ret, ret)
sys.exit(ret)