Tools/validate_yaml: add schema validation for module yaml config files

This commit is contained in:
Beat Küng 2018-08-27 11:40:32 +02:00
parent b5e552924a
commit 52967bd654
2 changed files with 138 additions and 0 deletions

65
Tools/validate_yaml.py Executable file
View File

@ -0,0 +1,65 @@
#! /usr/bin/env python
""" Script to validate YAML file(s) against a YAML schema file """
from __future__ import print_function
import argparse
import os
import sys
try:
import yaml
except:
print("Failed to import yaml.")
print("You may need to install it with 'sudo pip install pyyaml'")
print("")
raise
try:
import cerberus
except:
print("Failed to import cerberus.")
print("You may need to install it with 'sudo pip install cerberus'")
print("")
raise
parser = argparse.ArgumentParser(description='Validate YAML file(s) against a schema')
parser.add_argument('yaml_file', nargs='+', help='YAML config file(s)')
parser.add_argument('--schema-file', type=str, action='store',
help='YAML schema file', required=True)
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true',
help='Verbose Output')
args = parser.parse_args()
schema_file = args.schema_file
yaml_files = args.yaml_file
verbose = args.verbose
def load_yaml_file(file_name):
with open(file_name, 'r') as stream:
try:
return yaml.load(stream)
except yaml.YAMLError as exc:
print(exc)
raise
# load the schema
schema = load_yaml_file(schema_file)
validator = cerberus.Validator(schema)
# validate yaml files
for yaml_file in yaml_files:
if verbose: print("Validating {:}".format(yaml_file))
document = load_yaml_file(yaml_file)
# ignore top-level entries prefixed with __
for key in document.keys():
if key.startswith('__'): del document[key]
if not validator.validate(document):
print("Validation Errors:")
print(validator.errors)
print("")
raise Exception("Validation of {:} failed".format(yaml_file))

73
test/module_schema.yaml Normal file
View File

@ -0,0 +1,73 @@
# Cerberus Validation Schema for module configuration files.
# See http://docs.python-cerberus.org/en/stable/validation-rules.html
module_name:
# human-readable module name (used for descriptions, can contain spaces)
type: string
required: true
serial_config:
# UART configuration (optional)
# A module can register autostart command(s) that are associated with a
# configuration parameter, so that a user can select on which serial port to
# run the command.
# One or several commands can be defined.
type: list
minlength: 1
schema:
type: dict
schema:
command:
# script command that is executed on autostart.
# These variables can be used:
# ${SERIAL_DEV} Serial device (e.g. /dev/ttyS1)
# ${BAUD_PARAM} param name for the baudrate
# ${i} instance in [0, N-1] (for multi-instance commands)
# It's possible to use multiple lines.
type: string
required: true
port_config_param:
# Parameter definition to configure on which port to run the
# command
type: dict
required: true
schema:
name:
# Parameter name (e.g. TEL_FRSKY_CONFIG, MAV_${i}_CONFIG)
type: string
regex: '[0-9A-Z_]+(\$\{i\}[0-9A-Z_]*)?'
required: true
group:
# Associated parameter group (e.g. GPS)
type: string
required: true
default:
# Default value(s). This can be a string to specify the
# serial tag (e.g. GPS1, TEL1, ...) or a list of strings
# for multiple instances.
# If omitted, the command is disabled by default.
anyof:
- type: string
- type: list
minlength: 1
schema:
type: string
label:
# Optional command label (e.g. used in the autostart script).
# If omitted, module_name is used.
type: string
num_instances:
# Allow to configure and run multiple instances of a command.
# For multiple instances, '${i}' can be used to refer to
# an instance, for example in the parameter name or script
# command.
# Default: 1
type: integer
min: 1
parameters:
type: list
# TODO