summaryrefslogtreecommitdiff
path: root/validate.py
blob: 12f500034f4a6821fdd10c877b74b8ac509c5aea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/python
#
# Ideally we would use jsonschema.validate but getting useful error
# output has been challenging.  This can be revisited as needed.

import yaml
import sys

def validate_leaves(prefix, vm, l):
    valid_leaves = [ ]

    # first check to make sure we have what we think we should
    for nd in l:
        n = nd[0]
        t = nd[1]
        o = False
        if len(nd)>2:
            o = nd[2]
        try:
            if n not in vm.keys():
                if o:
                    print "[W] Missing leaf:", prefix+n
                else:
                    print "[E] Missing leaf:", prefix+n
                continue
            if type(vm[n]) != type(t):
                print "[E] Wrong type for %s (got '%s' expected '%s')" % (prefix+n, type(vm[n]).__name__, type(t).__name__)
                continue
        except:
            print "[W] Unable to validate leaf:", prefix+n
            continue

        valid_leaves.append(n)

    if type(vm) == type(dict()):
        # now look for things we don't know how to deal with
        for n in vm.keys():
            if n not in [ x[0]  for x in l]:
                print "[W] Unexpected leaf:", prefix+n

    return valid_leaves

def validate_file(filename):
    try:
        yamlgen = list(yaml.safe_load_all(open(filename)))
    except yaml.parser.ParserError:
        print "[E] Invalid yaml"
        return

    if not yamlgen or not yamlgen[0]:
        print "[E] File contains no valid yaml"
        return
    top = list(yamlgen)[0]

    vmlist = top["vmlist"]
    if not vmlist  or  not isinstance(vmlist, dict):
        print "[E] No vmlist dict declared"
        return

    for name in vmlist:
        vm = vmlist[name]
        print "VM:", name

        vl = validate_leaves("", vm, [ ("enabled",bool()), ("vmconfig",dict()), ("netconfig",dict()), ("cloudconfig",dict()) ] )
        if "vmconfig" in vl:
            # validate vmconfig
            vmconfig = vm["vmconfig"]
            vl2 = validate_leaves("vmconfig.", vmconfig, [ ("cpu",dict()), ("rootfs",dict()) ])

            if "cpu" in vl2:
                # validate vmconfig.cpu
                cpu = vmconfig["cpu"]
                vl3 = validate_leaves("vmconfig.cpu.", cpu, [ ("vcpu",int()), ("ram_mb",int()) ])
                if "vcpus" in vl3:
                    vcpu = int(cpu["vcpus"])
                    if vcpu < 1  or  vcpu > 8:
                        print "[W] vmconfig.cpu.vcpu has odd looking value:", vcpu
                if "ram_mb" in vl3:
                    ram_mb = int(cpu["ram_mb"])
                    if ram_mb < 512   or   ram_mb > 32768:
                        print "[W] vmconfig.cpu.ram_mb has odd looking value:", ram_mb

            if "rootfs" in vl2:
                # validate vmconfig.rootfs
                rootfs = vmconfig["rootfs"]
                vl3 = validate_leaves("vmconfig.rootfs.", rootfs, [ ("sourceurl",str()), ("localtarget",str()), ("pvc_size",str()), ("pvc_class",str(), True) ])

                if "sourceurl" in vl3:
                    if not rootfs["sourceurl"].startswith("http"):
                        print "[W] vmconfig.rootfs.sourceurl has odd looking value:", rootfs["sourceurl"]

        if "netconfig" in vl:
            # validate netconfig
            netconfig = vm["netconfig"]
            vm2 = validate_leaves("netconfig.", netconfig, [ ("ports",dict()), ("readinessTcpProbe",int(), True) ])
            # do more?

        if "cloudconfig" in vl:
            # validate cloudconfig
            cloudconfig = vm["cloudconfig"]
            vl2 = validate_leaves("cloudconfig.", cloudconfig, [ ("metadata",str()), ("userdata",str()) ])

            # check things look sane
            for yamlobj in [ "metadata", "userdata" ]:
                if yamlobj in vl2:
                    try:
                        yaml.load(cloudconfig[yamlobj])
                    except:
                        print "[E] Bad yaml for vmconfig.cloudconfig.%s" % yamlobj


if __name__ == "__main__":
    for fn in sys.argv[1:]:
        print "Filename:", fn
        validate_file(fn)
        print