sahara-tests/sahara_tests/scenario/validation.py

485 lines
19 KiB
Python

# 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
},
"s3_accesskey": {
"type": "string",
},
"s3_secretkey": {
"type": "string",
},
"s3_endpoint": {
"type": "string",
},
"s3_endpoint_ssl": {
"type": "boolean",
},
"s3_bucket_path": {
"type": "boolean",
},
},
"additionalProperties": False
},
"network": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["neutron", "nova-network"]
},
"auto_assignment_floating_ip": {
"type": "boolean"
},
"public_network": {
"type": "string"
},
"private_network": {
"type": "string",
"minLength": 1
}
},
"additionalProperties": False
},
"clusters": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"properties": {
"existing_cluster": {
"type": "string",
"minLength": 1
},
"key_name": {
"type": "string",
"minLength": 1
},
"plugin_name": {
"type": "string",
"minLength": 1
},
"plugin_version": {
"type": "string",
"minLength": 1
},
"image": {
"type": "string",
"minLength": 1
},
"image_username": {
"type": "string",
"minLength": 1
},
"hdfs_username": {
"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": "array",
"items": {
"type": "string",
"minLength": 1
}
}
},
"required": ["node_group_templates"],
"additionalProperties": False
},
"cluster": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"format": "valid_name"
},
"description": {
"type": "string"
},
"is_transient": {
"type": "boolean"
}
},
"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
},
"custom_checks": {
"type": "object",
"properties": {
".*": {
"type": "object",
}
}
},
"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", "array"],
"items": {
"type": ["string", "object"],
"properties": {
"name": {
"type": "string",
},
"features": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
}
},
"required": ["name", "features"],
}
},
"retain_resources": {
"type": "boolean"
},
"edp_batching": {
"type": "integer",
"minimum": 1
}
},
"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",
"s3"]
},
"source": {
"type": "string"
}
},
"required": ["type", "source"],
"additionalProperties": False
},
"output_datasource": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["swift", "hdfs", "maprfs",
"s3"]
},
"destination": {
"type": "string"
}
},
"required": ["type", "destination"],
"additionalProperties": False
},
"main_lib": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["swift", "s3", "database"]
},
"source": {
"type": "string"
}
},
"required": ["type", "source"],
"additionalProperties": False
},
"additional_libs": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["swift", "s3", "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)