From d7bde02b0ded47810f4cdf981ee00832ceb46eb4 Mon Sep 17 00:00:00 2001 From: Sindhur Malleni Date: Wed, 30 Mar 2016 18:43:03 -0400 Subject: [PATCH] Adding functionality to check validity of configuration file Change-Id: Icaf5fecb6e77351c23273e6c888924de1a55d596 --- browbeat.py | 28 +++++- lib/validate.yaml | 227 ++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 3 + 3 files changed, 254 insertions(+), 4 deletions(-) create mode 100644 lib/validate.yaml diff --git a/browbeat.py b/browbeat.py index 4b8a5d59d..b7bb260f2 100755 --- a/browbeat.py +++ b/browbeat.py @@ -6,17 +6,37 @@ import argparse import logging import sys import yaml +from pykwalify import core as pykwalify_core +from pykwalify import errors as pykwalify_errors _workload_opts = ['perfkit', 'rally', 'shaker'] _config_file = 'browbeat-config.yaml' debug_log_file = 'log/debug.log' -def _load_config(config_file): - with open(config_file, 'r') as stream_conf_file: - config = yaml.load(stream_conf_file) + +def _load_config(path, _logger): + try: + stream = open(path, 'r') + except IOError: + _logger.error("Configuration file {} passed is missing".format(path)) + exit(1) + config=yaml.load(stream) + stream.close() + validate_yaml(config, _logger) return config +def validate_yaml(config, _logger): + _logger.info("Validating the configuration file passed by the user") + stream = open("lib/validate.yaml", 'r') + schema = yaml.load(stream) + check = pykwalify_core.Core(source_data=config, schema_data=schema) + try: + check.validate(raise_exception=True) + _logger.info("Validation successful") + except pykwalify_errors.SchemaError as e: + _logger.error("Schema Validation failed") + raise Exception('File does not conform to schema: {}'.format(e)) def _run_workload_provider(provider, config): _logger = logging.getLogger('browbeat') @@ -61,7 +81,7 @@ def main(): _logger.debug("CLI Args: {}".format(_cli_args)) # Load Browbeat yaml config file: - _config = _load_config(_cli_args.setup) + _config = _load_config(_cli_args.setup, _logger) # Default to all workloads if _cli_args.workloads == []: diff --git a/lib/validate.yaml b/lib/validate.yaml new file mode 100644 index 000000000..523e67939 --- /dev/null +++ b/lib/validate.yaml @@ -0,0 +1,227 @@ +name: Browbeat configuration schema +type: map +allowempty: True +mapping: + browbeat: + required: True + type: map + mapping: + results: + type: str + required: True + rerun: + type: int + required: True + ansible: + required: True + type: map + mapping: + hosts: + type: str + adjust: + type: map + mapping: + keystone_token: + type: str + neutron_l3: + type: str + nova_db: + type: str + workers: + type: str + grafana_snapshot: + type: str + required: True + shaker_build: + type: str + connmon: + type: map + allowempty: True + mapping: + enabled: + type: bool + required: True + + grafana: + required: True + type: map + mapping: + enabled: + type: bool + required: True + cloud_name: + type: str + grafana_ip: + type: str + pattern: (?:[0-9]{1,3}\.){3}[0-9]{1,3} + grafana_port: + type: int + dashboards: + type: seq + sequence: + - type: str + snapshot: + type: map + mapping: + enabled: + type: bool + required: True + snapshot_compute: + type: bool + required: True + + perfkit: + required: False + type: map + allowempty: True + mapping: + enabled: + type: bool + required: True + sleep_before: + type: number + required: True + sleep_after: + type: number + required: True + venv: + type: str + required: True + default: + type: map + required: True + mapping: + image: + type: str + required: True + machine_type: + type: str + required: True + os_type: + type: str + required: True + enum: ['rhel', 'debian', 'ubuntu_container', 'windows'] + openstack_image_username: + type: str + required: True + openstack_public_network: + type: str + required: True + openstack_private_network: + type: str + required: True + benchmarks: + type: seq + sequence: + - type: map + allowempty: True + mapping: + name: + type: str + required: True + enabled: + type: bool + required: True + benchmarks: + type: str + required: True + shaker: + required: False + allowempty: True + type: map + mapping: + enabled: + type: bool + required: True + server: + type: str + required: True + pattern: (?:[0-9]{1,3}\.){3}[0-9]{1,3} + port: + type: int + required: True + flavor: + type: str + required: True + join_timeout: + type: int + required: True + sleep_before: + type: number + required: True + sleep_after: + type: number + required: True + venv: + type: str + required: True + shaker_region: + type: str + required: true + scenarios: + type: seq + sequence: + - type: map + allowempty: True + mapping: + name: + type: str + required: True + enabled: + type: bool + required: True + file: + type: str + required: True + rally: + required: False + type: map + allowempty: True + mapping: + enabled: + type: bool + required: True + sleep_before: + type: number + required: True + sleep_after: + type: number + required: True + venv: + type: str + required: True + benchmarks: + type: seq + required: True + sequence: + - type: map + mapping: + name: + type: str + required: True + enabled: + required: True + type: bool + concurrency: + type: seq + required: True + sequence: + - type: int + times: + type: int + required: True + scenarios: + type: seq + sequence: + - type: map + allowempty: True + mapping: + name: + type: str + required: True + enabled: + type: bool + required: True + file: + type: str + required: True diff --git a/requirements.txt b/requirements.txt index 89008b75d..2187169fb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,5 @@ ansible matplotlib +python-dateutil==2.4.2 +pykwalify +