| # -*- coding: utf-8 -*- |
| |
| # 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. |
| |
| from http import HTTPStatus |
| |
| from jsonschema import exceptions as js_e, validate as js_v |
| |
| __author__ = "Alfonso Tierno <alfonso.tiernosepulveda@telefonica.com>" |
| __version__ = "0.1" |
| version_date = "Jun 2020" |
| |
| """ |
| Validator of input data using JSON schemas |
| """ |
| |
| # Basis schemas |
| name_schema = { |
| "type": "string", |
| "minLength": 1, |
| "maxLength": 255, |
| "pattern": "^[^,;()'\"]+$", |
| } |
| string_schema = {"type": "string", "minLength": 1, "maxLength": 255} |
| ssh_key_schema = {"type": "string", "minLength": 1} |
| id_schema = { |
| "type": "string", |
| "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$", |
| } |
| bool_schema = {"type": "boolean"} |
| null_schema = {"type": "null"} |
| object_schema = {"type": "object"} |
| |
| deploy_item_schema = { |
| "title": "deploy item validation. Each vld, vdu, flavor, image, ...", |
| "$schema": "http://json-schema.org/draft-04/schema#", |
| "type": "object", |
| "properties": { |
| "id": string_schema, |
| "vim_info": object_schema, |
| "common_id": string_schema, |
| }, |
| "additionalProperties": True, |
| } |
| |
| deploy_item_list = { |
| "type": "array", |
| "items": deploy_item_schema, |
| } |
| |
| deploy_vnf_schema = { |
| "title": "deploy.vnf.item validation", |
| "$schema": "http://json-schema.org/draft-04/schema#", |
| "type": "object", |
| "properties": { |
| "_id": id_schema, |
| "vdur": deploy_item_list, |
| "vld": deploy_item_list, |
| }, |
| "additionalProperties": True, |
| "required": ["_id"], |
| } |
| |
| deploy_action_schema = { |
| "title": "deploy.action validation", |
| "$schema": "http://json-schema.org/draft-04/schema#", |
| "type": "object", |
| "properties": { |
| "action": {"enum": ["inject_ssh_key"]}, |
| "key": ssh_key_schema, |
| "user": string_schema, |
| "password": string_schema, |
| }, |
| "additionalProperties": False, |
| "required": ["action"], |
| } |
| |
| deploy_schema = { |
| "title": "deploy input validation", |
| "$schema": "http://json-schema.org/draft-04/schema#", |
| "type": "object", |
| "properties": { |
| "action_id": string_schema, |
| "cloud_init_content": object_schema, |
| "name": string_schema, |
| "action": deploy_action_schema, |
| "vnf": { |
| "type": "array", |
| "items": deploy_vnf_schema, |
| }, |
| "image": deploy_item_list, |
| "flavor": deploy_item_list, |
| "ns": { |
| "type": "object", |
| "properties": { |
| "vld": deploy_item_list, |
| }, |
| }, |
| "affinity-or-anti-affinity-group": deploy_item_list, |
| }, |
| "additionalProperties": False, |
| } |
| |
| rebuild_schema = { |
| "$schema": "http://json-schema.org/draft-04/schema#", |
| "vm_rebuild": { |
| "type": "array", |
| "items": { |
| "type": "object", |
| "properties": { |
| "vdu-id": id_schema, |
| "vim_name": name_schema, |
| "member-vnf-index": name_schema, |
| }, |
| }, |
| "additionalProperties": True, |
| }, |
| } |
| |
| |
| class ValidationError(Exception): |
| def __init__(self, message, http_code=HTTPStatus.UNPROCESSABLE_ENTITY): |
| self.http_code = http_code |
| Exception.__init__(self, message) |
| |
| |
| def validate_input(indata, schema_to_use): |
| """ |
| Validates input data against json schema |
| :param indata: user input data. Should be a dictionary |
| :param schema_to_use: jsonschema to test |
| :return: None if ok, raises ValidationError exception on error |
| """ |
| try: |
| if schema_to_use: |
| js_v(indata, schema_to_use) |
| |
| return None |
| except js_e.ValidationError as e: |
| if e.path: |
| error_pos = "at '" + ":".join(map(str, e.path)) + "'" |
| else: |
| error_pos = "" |
| |
| raise ValidationError("Format error {} '{}' ".format(error_pos, e.message)) |
| except js_e.SchemaError: |
| raise ValidationError( |
| "Bad json schema {}".format(schema_to_use), |
| http_code=HTTPStatus.INTERNAL_SERVER_ERROR, |
| ) |