From 79a699a36029fa0cbd9912195e6ca9ec86a419ca Mon Sep 17 00:00:00 2001 From: Anders Ingemann Date: Sun, 23 Jun 2013 23:37:21 +0200 Subject: [PATCH] Better schema validation and errors --- base/manifest-schema.json | 25 +++++++++++++++++++++++++ base/manifest.py | 24 +++++++++++++----------- common/exceptions.py | 8 ++++++-- manifests/ec2-ebs-pvm.manifest.json | 4 ++-- providers/ec2/manifest-schema.json | 1 + providers/ec2/manifest.py | 3 ++- 6 files changed, 49 insertions(+), 16 deletions(-) create mode 100644 base/manifest-schema.json diff --git a/base/manifest-schema.json b/base/manifest-schema.json new file mode 100644 index 0000000..a5106e1 --- /dev/null +++ b/base/manifest-schema.json @@ -0,0 +1,25 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Generic manifest", + "type": "object", + "properties": { + "provider": { + "type": "string" + }, + "plugins": { + "type": "object", + "patternProperties": { + "^\\w+$": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + }, + "required": ["enabled"] + } + }, + "additionalProperties": false + } + } +} diff --git a/base/manifest.py b/base/manifest.py index 6fe39ae..6eb61f1 100644 --- a/base/manifest.py +++ b/base/manifest.py @@ -23,17 +23,19 @@ class Manifest(object): def __init__(self, path): self.path = path - def validate(self, data, schema_path=None): - if schema_path is not None: - from json_schema_validator.validator import Validator - from json_schema_validator.schema import Schema - from json_schema_validator.errors import ValidationError - schema = Schema(load_json(schema_path)) - try: - Validator.validate(schema, data) - except ValidationError as e: - from common.exceptions import ManifestError - raise ManifestError(e.message, self) + def validate(self, data): + from os import path + schema_path = path.normpath(path.join(path.dirname(__file__), 'manifest-schema.json')) + self.schema_validate(data, schema_path) + + def schema_validate(self, data, schema_path): + import jsonschema + schema = load_json(schema_path) + try: + jsonschema.validate(data, schema) + except jsonschema.ValidationError as e: + from common.exceptions import ManifestError + raise ManifestError(e.message, self, e.path) def parse(self, data): self.provider = data['provider'] diff --git a/common/exceptions.py b/common/exceptions.py index b4b76cb..b85b3df 100644 --- a/common/exceptions.py +++ b/common/exceptions.py @@ -2,11 +2,15 @@ __all__ = ['ManifestError'] class ManifestError(Exception): - def __init__(self, message, manifest): + def __init__(self, message, manifest, json_path=None): self.message = message self.manifest = manifest + self.json_path = json_path def __str__(self): - return "Error in manifest {0}: {1}".format(self.manifest.path, self.message) + if self.json_path is not None: + path = '.'.join(self.json_path) + return "{2}\n\tFile: {0}\n\tJSON path: {1}".format(self.manifest.path, path, self.message) + return "{0}: {1}".format(self.manifest.path, self.message) class TaskListError(Exception): diff --git a/manifests/ec2-ebs-pvm.manifest.json b/manifests/ec2-ebs-pvm.manifest.json index 2596ddd..2686187 100644 --- a/manifests/ec2-ebs-pvm.manifest.json +++ b/manifests/ec2-ebs-pvm.manifest.json @@ -6,7 +6,7 @@ "secret-key": null }, - "bootstrapdir" : "/target", + "bootstrapdir": "/target", "image": { "name" : "debian-{release}-{architecture}-{virtualization}-{year}{month}{day}", "description": "Debian {release} {architecture} AMI ({virtualization})" @@ -29,7 +29,7 @@ "enabled": true }, "build_metadata": { - "enabled": true, + "enabled": false, "path" : "/root/build-metadata-{ami_name}" } } diff --git a/providers/ec2/manifest-schema.json b/providers/ec2/manifest-schema.json index d5ba725..d222b62 100644 --- a/providers/ec2/manifest-schema.json +++ b/providers/ec2/manifest-schema.json @@ -1,4 +1,5 @@ { + "$schema": "http://json-schema.org/draft-04/schema#", "title": "EC2 manifest", "type": "object", "properties": { diff --git a/providers/ec2/manifest.py b/providers/ec2/manifest.py index fa93d28..105fb21 100644 --- a/providers/ec2/manifest.py +++ b/providers/ec2/manifest.py @@ -5,7 +5,8 @@ class Manifest(base.Manifest): def validate(self, data): from os import path schema_path = path.normpath(path.join(path.dirname(__file__), 'manifest-schema.json')) - super(Manifest, self).validate(data, schema_path) + self.schema_validate(data, schema_path) + super(Manifest, self).validate(data) def parse(self, data): super(Manifest, self).parse(data)