Reformatting RO
[osm/RO.git] / NG-RO / osm_ng_ro / validation.py
1 # -*- coding: utf-8 -*-
2
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 # implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 from jsonschema import validate as js_v, exceptions as js_e
17 from http import HTTPStatus
18
19 __author__ = "Alfonso Tierno <alfonso.tiernosepulveda@telefonica.com>"
20 __version__ = "0.1"
21 version_date = "Jun 2020"
22
23 """
24 Validator of input data using JSON schemas
25 """
26
27 # Basis schemas
28 name_schema = {
29 "type": "string",
30 "minLength": 1,
31 "maxLength": 255,
32 "pattern": "^[^,;()'\"]+$",
33 }
34 string_schema = {"type": "string", "minLength": 1, "maxLength": 255}
35 ssh_key_schema = {"type": "string", "minLength": 1}
36 id_schema = {
37 "type": "string",
38 "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$",
39 }
40 bool_schema = {"type": "boolean"}
41 null_schema = {"type": "null"}
42 object_schema = {"type": "object"}
43
44 deploy_item_schema = {
45 "title": "deploy item validation. Each vld, vdu, flavor, image, ...",
46 "$schema": "http://json-schema.org/draft-04/schema#",
47 "type": "object",
48 "properties": {
49 "id": string_schema,
50 "vim_info": object_schema,
51 "common_id": string_schema,
52 },
53 "additionalProperties": True,
54 }
55
56 deploy_item_list = {
57 "type": "array",
58 "items": deploy_item_schema,
59 }
60
61 deploy_vnf_schema = {
62 "title": "deploy.vnf.item validation",
63 "$schema": "http://json-schema.org/draft-04/schema#",
64 "type": "object",
65 "properties": {
66 "_id": id_schema,
67 "vdur": deploy_item_list,
68 "vld": deploy_item_list,
69 },
70 "additionalProperties": True,
71 "required": ["_id"],
72 }
73
74 deploy_action_schema = {
75 "title": "deploy.action validation",
76 "$schema": "http://json-schema.org/draft-04/schema#",
77 "type": "object",
78 "properties": {
79 "action": {"enum": ["inject_ssh_key"]},
80 "key": ssh_key_schema,
81 "user": string_schema,
82 "password": string_schema,
83 },
84 "additionalProperties": False,
85 "required": ["action"],
86 }
87
88 deploy_schema = {
89 "title": "deploy input validation",
90 "$schema": "http://json-schema.org/draft-04/schema#",
91 "type": "object",
92 "properties": {
93 "action_id": string_schema,
94 "cloud_init_content": object_schema,
95 "name": string_schema,
96 "action": deploy_action_schema,
97 "vnf": {
98 "type": "array",
99 "items": deploy_vnf_schema,
100 },
101 "image": deploy_item_list,
102 "flavor": deploy_item_list,
103 "ns": {
104 "type": "object",
105 "properties": {
106 "vld": deploy_item_list,
107 },
108 },
109 },
110 "additionalProperties": False,
111 }
112
113
114 class ValidationError(Exception):
115 def __init__(self, message, http_code=HTTPStatus.UNPROCESSABLE_ENTITY):
116 self.http_code = http_code
117 Exception.__init__(self, message)
118
119
120 def validate_input(indata, schema_to_use):
121 """
122 Validates input data against json schema
123 :param indata: user input data. Should be a dictionary
124 :param schema_to_use: jsonschema to test
125 :return: None if ok, raises ValidationError exception on error
126 """
127 try:
128 if schema_to_use:
129 js_v(indata, schema_to_use)
130
131 return None
132 except js_e.ValidationError as e:
133 if e.path:
134 error_pos = "at '" + ":".join(map(str, e.path)) + "'"
135 else:
136 error_pos = ""
137
138 raise ValidationError("Format error {} '{}' ".format(error_pos, e.message))
139 except js_e.SchemaError:
140 raise ValidationError(
141 "Bad json schema {}".format(schema_to_use),
142 http_code=HTTPStatus.INTERNAL_SERVER_ERROR,
143 )