Ejemplo n.º 1
0
def check_required_properties(d, path, required):
    if not isinstance(d, dict):
        raise ValidationError(path, "must be an object")

    for key in required:
        if key not in d:
            raise ValidationError(path, "property '%s' is required" % key)
Ejemplo n.º 2
0
def parse_jobs(e, path):
    if not isinstance(e, list):
        raise ValidationError(path, "must be an array")

    for i in range(0, len(e)):
        elem = e[i]
        p = "%s[%s]" % (path, i)

        if 'type' not in elem:
            raise ValidationError(p, "does not contain a 'type'")

        t = elem['type']

        if t == 'git':
            parse_git(elem, p)
        elif t == 'wait':
            parse_wait(elem, p)
        elif t == 'workflow':
            parse_workflow(elem, p)
        elif t == 'docker':
            parse_docker(elem, p)
        elif t == 'docker-image':
            parse_docker_image(elem, p)
        elif t == 'docker-compose':
            parse_docker_compose(elem, p)
        else:
            raise ValidationError(p, "type '%s' not supported" % t)
Ejemplo n.º 3
0
def check_allowed_properties(d, path, allowed):
    if not isinstance(d, dict):
        raise ValidationError(path, "must be an object")

    for key in d:
        if key not in allowed:
            raise ValidationError(path, "invalid property '%s'" % key)
Ejemplo n.º 4
0
def parse_table(d, path):
    check_allowed_properties(d, path, ("type", "rows", "headers"))
    check_required_properties(d, path, ("type", "rows"))

    if 'headers' in d:
        if not isinstance(d['headers'], list):
            raise ValidationError(path + ".headers", "must be an array")

        col_count = len(d['headers'])
        if col_count == 0:
            raise ValidationError(path + ".headers", "must not be empty")

        for i in range(0, col_count):
            h = d['headers'][i]
            parse_text(h, "%s.headers[%s]" % (path, i))

    if not isinstance(d['rows'], list):
        raise ValidationError(path + ".rows", "must be an array")

    if not d['rows']:
        raise ValidationError(path + ".rows", "must not be empty")

    for i in range(0, len(d['rows'])):
        r = d['rows'][i]
        p = "%s.rows[%s]" % (path, i)

        if 'headers' in d:
            if len(r) != col_count:
                raise ValidationError(
                    p, "does not have the correct number of columns")

        parse_elements(r, p)
Ejemplo n.º 5
0
def parse_services(d, path):
    if not isinstance(d, list):
        raise ValidationError(path, "must be an array")

    names = []

    for i in range(0, len(d)):
        elem = d[i]
        p = "%s[%s]" % (path, i)

        check_allowed_properties(elem, p,
                                 ("apiVersion", "kind", "metadata", "spec"))
        check_required_properties(elem, p, ("apiVersion", "kind", "metadata"))
        check_required_properties(elem['metadata'], p + ".metadata",
                                  ("name", ))

        name = elem['metadata']['name']

        if name in names:
            raise ValidationError(p, "duplicate service name found: %s" % name)

        names.append(name)

        if 'spec' in elem:
            parse_service_spec(elem['spec'], p + ".spec")
Ejemplo n.º 6
0
def parse_secret_ref(value, p):
    if not isinstance(value, dict):
        raise ValidationError(p, "must be an object")

    if "$secret" not in value:
        raise ValidationError(p, "must contain a $secret")

    check_text(value['$secret'], p + ".$secret")
Ejemplo n.º 7
0
def check_allowed_properties(d, path, allowed):
    if not isinstance(d, dict):
        raise ValidationError(path, "must be an object")

    for key in d:
        if key not in allowed:
            if 'name' in d.keys():
                raise ValidationError('%s(%s)' % (path, d['name']),
                                      "invalid property '%s'" % key)
            else:
                raise ValidationError(path, "invalid property '%s'" % key)
Ejemplo n.º 8
0
def parse_ts(e, path):
    if not isinstance(e, list):
        raise ValidationError(path, "must be an array")

    if not e:
        raise ValidationError(path, "must not be empty")

    for i in range(0, len(e)):
        elem = e[i]
        path = "%s[%s]" % (path, i)
        parse_t(elem, path)
Ejemplo n.º 9
0
def check_string_array(e, path):
    if not isinstance(e, list):
        raise ValidationError(path, "must be an array")

    if not e:
        raise ValidationError(path, "must not be empty")

    for i in range(0, len(e)):
        elem = e[i]
        path = "%s[%s]" % (path, i)
        check_text(elem, path)
Ejemplo n.º 10
0
def check_required_properties(d, path, required):
    if not isinstance(d, dict):
        raise ValidationError(path, "must be an object")

    for key in required:
        if key not in d:
            if 'name' in d.keys():
                raise ValidationError('%s(%s)' % (path, d['name']),
                                      "property '%s' is required" % key)
            else:
                raise ValidationError(path, "property '%s' is required" % key)
Ejemplo n.º 11
0
def parse_limits(d, path):
    check_allowed_properties(d, path, ("memory", "cpu"))
    check_required_properties(d, path, ("memory", "cpu"))

    check_int_or_float(d['cpu'], path + ".cpu")
    check_number(d['memory'], path + ".memory")

    if d['cpu'] <= 0.3:
        raise ValidationError(path + ".cpu", "must be greater than 0.3")

    if d['memory'] <= 255:
        raise ValidationError(path + ".memory", "must be greater than 255")
Ejemplo n.º 12
0
def parse_grid(d, path):
    check_allowed_properties(d, path, ("type", "rows"))
    check_required_properties(d, path, ("type", "rows"))

    if not isinstance(d['rows'], list):
        raise ValidationError(path + ".rows", "must be an array")

    if not d['rows']:
        raise ValidationError(path + ".rows", "must not be empty")

    for i in range(0, len(d['rows'])):
        r = d['rows'][i]
        parse_elements(r, "%s.rows[%s]" % (path, i))
Ejemplo n.º 13
0
def validate_json(d):
    parse_document(d)

    if 'jobs' not in d:
        return True

    jobs = {}
    for i in range(0, len(d['jobs'])):
        job = d['jobs'][i]
        job_name = job['name']

        path = "#jobs[%s]" % i

        if jobs.get(job_name, None):
            raise ValidationError(path + ".name",
                                  "Job name '%s' already exists" % job_name)

        if job_name == 'Create Jobs':
            raise ValidationError(path + ".name",
                                  "Job name may not be 'Create Jobs'")

        jobs[job_name] = job

        if 'depends_on' not in job:
            continue

        deps = {}
        for depends_on in job['depends_on']:
            parent_name = None

            if isinstance(depends_on, dict):
                parent_name = depends_on['job']
            else:
                parent_name = depends_on

            if job_name == parent_name:
                raise ValidationError(
                    path, "Job '%s' may not depend on itself" % parent_name)

            if parent_name not in jobs:
                raise ValidationError(path + ".depends_on",
                                      "Job '%s' not found" % parent_name)

            if parent_name in deps:
                raise ValidationError(
                    path + ".depends_on",
                    "'%s' duplicate dependencies" % parent_name)

            deps[parent_name] = True

    return True
Ejemplo n.º 14
0
def parse_environment(e, path):
    if not isinstance(e, dict):
        raise ValidationError(path, "must be an object")

    for key in e:
        value = e[key]
        p = path + "." + key

        if isinstance(value, dict):
            parse_secret_ref(value, p)
        else:
            try:
                check_text(value, p)
            except:
                raise ValidationError(p, "must be a string or object")
Ejemplo n.º 15
0
def parse_vault_ref(value, p):
    if not isinstance(value, dict):
        raise ValidationError(p, "must be an object")

    if "$vault" not in value:
        raise ValidationError(p, "must contain a $vault")
    check_text(value['$vault'], p + ".$vault")

    if "$vault_secret_path" not in value:
        raise ValidationError(p, "must contain a $vault_secret_path")
    check_text(value['$vault_secret_path'], p + ".$vault_secret_path")

    if "$vault_secret_key" not in value:
        raise ValidationError(p, "must contain a $vault_secret_key")
    check_text(value['$vault_secret_key'], p + ".$vault_secret_key")
Ejemplo n.º 16
0
def parse_docker(d, path):
    check_allowed_properties(d, path, ("type", "name", "docker_file", "depends_on", "resources", "build_only", "security", "commit_after_run", "keep", "environment", "build_arguments", "deployments"))
    check_required_properties(d, path, ("type", "name", "docker_file", "resources"))
    check_name(d['name'], path + ".name")
    check_text(d['docker_file'], path + ".docker_file")
    parse_resources(d['resources'], path + ".resources")

    if 'build_only' in d:
        check_boolean(d['build_only'], path + ".build_only")

    if 'keep' in d:
        check_boolean(d['keep'], path + ".keep")

    if 'depends_on' in d:
        check_name_array(d['depends_on'], path + ".depends_on")

    if 'security' in d:
        parse_security(d['security'], path + ".security")

    if 'commit_after_run' in d:
        if not isinstance(d['commit_after_run'], bool):
            raise ValidationError(path + ".commit_after_run", "Must be boolean")

    if 'environment' in d:
        parse_environment(d['environment'], path + ".environment")

    if 'build_arguments' in d:
        parse_build_args(d['build_arguments'], path + ".build_arguments")

    if 'deployments' in d:
        parse_deployments(d['deployments'], path + ".deployments")
Ejemplo n.º 17
0
def parse_document(d):
    check_allowed_properties(d, "#", ("version", "jobs", "generator"))
    check_required_properties(d, "#", ("version", ))

    check_version(d['version'], "#version")

    if 'generator' not in d and 'jobs' not in d:
        raise ValidationError("#", "Either 'jobs' or 'generator' must be set")

    if 'generator' in d and 'jobs' in d:
        raise ValidationError("#", "Either 'jobs' or 'generator' must be set, not both")

    if 'jobs' in d:
        parse_jobs(d['jobs'], "#jobs")

    if 'generator' in d:
        parse_generator(d['generator'], "#generator")
Ejemplo n.º 18
0
def parse_depends_on(a, path):
    if not isinstance(a, list):
        raise ValidationError(path, "must be an list")

    if not a:
        raise ValidationError(path, "must not be empty")

    for i in range(0, len(a)):
        n = a[i]
        p = '[%s]' % i

        if isinstance(n, dict):
            # contains conditions
            parse_depends_on_condition(n, path + p)
        else:
            # no conditions, default to 'finished'
            check_name(n, path + p)
Ejemplo n.º 19
0
def parse_build_args(e, path):
    if not isinstance(e, dict):
        raise ValidationError(path, "must be an object")

    for key in e:
        value = e[key]
        p = path + "." + key
        check_text(value, p)
Ejemplo n.º 20
0
def parse_deployments(e, path):
    if not isinstance(e, list):
        raise ValidationError(path, "must be an array")

    if not e:
        raise ValidationError(path, "must not be empty")

    for i in range(0, len(e)):
        elem = e[i]
        p = "%s[%s]" % (path, i)

        if 'type' not in elem:
            raise ValidationError(p, "does not contain a 'type'")

        t = elem['type']

        if t == 'docker-registry':
            parse_deployment_docker_registry(elem, p)
        else:
            raise ValidationError(p, "type '%s' not supported" % t)
Ejemplo n.º 21
0
def parse_text(d, path):
    check_allowed_properties(d, path, ("type", "text", "emphasis", "color"))
    check_required_properties(d, path, ("type", "text"))

    check_text(d['text'], path + ".text")

    if 'emphasis' in d:
        if d['emphasis'] not in ("bold", "italic"):
            raise ValidationError(path + ".emphasis", "not a valid value")

    if 'color' in d:
        check_color(d['color'], path + ".color")
Ejemplo n.º 22
0
def parse_depends_on_condition(d, path):
    check_allowed_properties(d, path, ("job", "on"))
    check_required_properties(d, path, ("job", "on"))
    check_name(d['job'], path + '.job')

    on = d['on']
    if not isinstance(on, list):
        raise ValidationError(path + ".on", "must be a list")

    if not on:
        raise ValidationError(path + ".on", "must not be empty")

    on_used = {}
    for i in on:
        if i not in ('finished', 'error', 'failure', 'unstable', '*'):
            raise ValidationError(path + ".on", "%s is not a valid value" % i)

        if i in on_used:
            raise ValidationError(path + ".on", "%s used twice" % i)

        on_used[i] = True
Ejemplo n.º 23
0
def parse_elements(e, path):
    if not isinstance(e, list):
        raise ValidationError(path, "must be an array")

    if not e:
        raise ValidationError(path, "must not be empty")

    for i in range(0, len(e)):
        elem = e[i]
        p = "%s[%s]" % (path, i)

        if 'type' not in elem:
            raise ValidationError(p, "does not contain a 'type'")

        t = elem['type']

        if t == 'h1' or t == 'h2' or t == 'h3' or t == 'h4' or t == 'h5':
            parse_heading(elem, p)
        elif t == 'hline':
            parse_hline(elem, p)
        elif t == 'paragraph':
            parse_paragraph(elem, p)
        elif t == 'text':
            parse_text(elem, p)
        elif t == 'ordered_list':
            parse_ordered_list(elem, p)
        elif t == 'unordered_list':
            parse_unordered_list(elem, p)
        elif t == 'group':
            parse_group(elem, p)
        elif t == 'pie':
            parse_pie(elem, p)
        elif t == 'grid':
            parse_grid(elem, p)
        elif t == 'table':
            parse_table(elem, p)
        elif t == 'icon':
            parse_icon(elem, p)
        else:
            raise ValidationError(p, "type '%s' not supported" % t)
Ejemplo n.º 24
0
def check_color(d, path):
    if d not in ("red", "green", "blue", "yellow", "orange", "white", "black",
                 "grey"):
        raise ValidationError(path, "not a valid value")
Ejemplo n.º 25
0
def check_text(t, path, allowEmpty=False):
    if not isinstance(t, str):
        raise ValidationError(path, "is not a string")

    if not allowEmpty and not t:
        raise ValidationError(path, "empty string not allowed")
Ejemplo n.º 26
0
def check_version(v, path):
    if not isinstance(v, int):
        raise ValidationError(path, "must be an int")

    if v != 1:
        raise ValidationError(path, "unsupported version")
Ejemplo n.º 27
0
def validate_json(d):
    parse_document(d)

    if 'jobs' not in d:
        return True

    jobs = {}
    all_job_names = set([j['name'] for j in d['jobs']])
    all_deps = {}
    for i in range(0, len(d['jobs'])):
        job = d['jobs'][i]
        job_name = job['name']

        path = "#jobs[%s]" % i

        if jobs.get(job_name, None):
            raise ValidationError(path + ".name",
                                  "Job name '%s' already exists" % job_name)

        if job_name == 'Create Jobs':
            raise ValidationError(path + ".name",
                                  "Job name may not be 'Create Jobs'")

        jobs[job_name] = job

        if 'depends_on' not in job:
            continue

        deps = {}
        for depends_on in job['depends_on']:
            parent_name = None

            if isinstance(depends_on, dict):
                parent_name = depends_on['job']
            else:
                parent_name = depends_on

            if job_name == parent_name:
                raise ValidationError(
                    path, "Job '%s' may not depend on itself" % parent_name)

            if parent_name not in all_job_names:
                raise ValidationError(path + ".depends_on",
                                      "Job '%s' not found" % parent_name)

            if parent_name in deps:
                raise ValidationError(
                    path + ".depends_on",
                    "'%s' duplicate dependencies" % parent_name)

            deps[parent_name] = True

        if deps:
            all_deps[job_name] = deps

    for job_name, deps in all_deps.items():
        queue = list(deps.keys())
        for dep_job in queue:
            if dep_job == job_name:
                raise ValidationError("Jobs", "Circular dependency detected.")
            if dep_job in all_deps:
                queue.extend(all_deps[dep_job].keys())

    return True
Ejemplo n.º 28
0
def check_number(d, path):
    if not isinstance(d, int):
        raise ValidationError(path, "must be a number")
Ejemplo n.º 29
0
def check_boolean(d, path):
    if not isinstance(d, bool):
        raise ValidationError(path, "must be a boolean")
Ejemplo n.º 30
0
def check_name(n, path):
    check_text(n, path)
    if not special_match(n):
        raise ValidationError(path, "'%s' not a valid value" % n)