# Copyright (c) 2015 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. import re import jsonschema import rfc3986 SCHEMA = { "type": "object", "properties": { "concurrency": { "type": "integer", "minimum": 1 }, "credentials": { "type": "object", "properties": { "os_username": { "type": "string", "minLength": 1 }, "os_password": { "type": "string", "minLength": 1 }, "os_tenant": { "type": "string", "minLength": 1 }, "os_auth_url": { "type": "string", "format": "uri" }, "sahara_service_type": { "type": "string", "minLength": 1 }, "sahara_url": { "type": "string", "format": "uri" }, "ssl_verify": { "type": "boolean" }, "ssl_cert": { "type": "string", "minLength": 1 } }, "additionalProperties": False }, "network": { "type": "object", "properties": { "type": { "type": "string", "enum": ["neutron", "nova-network"] }, "auto_assignment_floating_ip": { "type": "boolean" }, "public_network": { "type": "string", "minLength": 1 }, "private_network": { "type": "string", "minLength": 1 } }, "additionalProperties": False }, "clusters": { "type": "array", "minItems": 1, "items": { "type": "object", "properties": { "plugin_name": { "type": "string", "minLength": 1 }, "plugin_version": { "type": "string", "minLength": 1 }, "image": { "type": "string", "minLength": 1 }, "node_group_templates": { "type": "array", "minItems": 1, "items": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "format": "valid_name" }, "node_processes": { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 } }, "flavor": { "type": ["object", "string"], "properties": { "name": { "type": "string", "minLength": 1 }, "id": { "type": "string", "minLength": 1 }, "vcpus": { "type": "integer", "minimum": 1 }, "ram": { "type": "integer", "minimum": 1 }, "root_disk": { "type": "integer", "minimum": 0 }, "ephemeral_disk": { "type": "integer", "minimum": 0 }, "swap_disk": { "type": "integer", "minimum": 0 }, }, "additionalProperties": True }, "description": { "type": "string" }, "volumes_per_node": { "type": "integer", "minimum": 0 }, "volumes_size": { "type": "integer", "minimum": 0 }, "node_configs": { "type": "object" }, "security_groups": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "auto_security_group": { "type": "boolean" }, "availability_zone": { "type": "string", "minLength": 1 }, "volumes_availability_zone": { "type": "string", "minLength": 1 }, "volume_type": { "type": "string", "minLength": 1 }, "is_proxy_gateway": { "type": "boolean" } }, "required": ["name", "flavor", "node_processes"], "additionalProperties": False } }, "cluster_template": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "format": "valid_name" }, "description": { "type": "string" }, "cluster_configs": { "type": "object" }, "node_group_templates": { "type": "object", "patternProperties": { ".*": { "type": "integer", "minimum": 1 } } }, "anti_affinity": { "type": "boolean" } }, "required": ["name", "node_group_templates"], "additionalProperties": False }, "cluster": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "format": "valid_name" }, "description": { "type": "string" }, "is_transient": { "type": "boolean" } }, "required": ["name"], "additionalProperties": False, }, "timeout_check_transient": { "type": "integer", "minimum": 1 }, "timeout_delete_resource": { "type": "integer", "minimum": 1 }, "timeout_poll_cluster_status": { "type": "integer", "minimum": 1 }, "timeout_poll_jobs_status": { "type": "integer", "minimum": 1 }, "scaling": { "type": "array", "minItems": 1, "items": { "type": "object", "properties": { "operation": { "type": "string", "enum": ["add", "resize"] }, "node_group": { "type": "string", "minLength": 1 }, "size": { "type": "integer", "minimum": 0 } }, "required": ["operation", "node_group", "size"], "additionalProperties": False } }, "scenario": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "edp_jobs_flow": { "type": "string", "minLength": 1 }, "retain_resources": { "type": "boolean" } }, "required": ["plugin_name", "plugin_version", "image"], "additionalProperties": False } }, "edp_jobs_flow": { "type": "object", "patternProperties": { ".*": { "type": "array", "minItems": 1, "items": { "type": "object", "properties": { "type": { "type": "string", "enum": ["Pig", "Java", "MapReduce", "MapReduce.Streaming", "Hive", "Spark"] }, "input_datasource": { "type": "object", "properties": { "type": { "type": "string", "enum": ["swift", "hdfs", "maprfs"] }, "source": { "type": "string" } }, "required": ["type", "source"], "additionalProperties": False }, "output_datasource": { "type": "object", "properties": { "type": { "type": "string", "enum": ["swift", "hdfs", "maprfs"] }, "destination": { "type": "string" } }, "required": ["type", "destination"], "additionalProperties": False }, "main_lib": { "type": "object", "properties": { "type": { "type": "string", "enum": ["swift", "database"] }, "source": { "type": "string" } }, "required": ["type", "source"], "additionalProperties": False }, "additional_libs": { "type": "array", "items": { "type": "object", "properties": { "type": { "type": "string", "enum": ["swift", "database"] }, "source": { "type": "string" } }, "required": ["type", "source"], "additionalProperties": False } }, "configs": { "type": "object" }, "args": { "type": "array" } }, "required": ["type"], "additionalProperties": False } } } } }, "required": ["clusters"], "additionalProperties": False } @jsonschema.FormatChecker.cls_checks("uri") def validate_uri_format(entry): return rfc3986.is_valid_uri(entry) @jsonschema.FormatChecker.cls_checks('valid_name') def validate_name_hostname_format(entry): res = re.match(r"^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]" r"*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z]" r"[A-Za-z0-9\-]*[A-Za-z0-9])$", entry) return res is not None class Validator(jsonschema.Draft4Validator): def __init__(self, schema): format_checker = jsonschema.FormatChecker() super(Validator, self).__init__( schema, format_checker=format_checker) def validate(config): return Validator(SCHEMA).validate(config)