Code Coverage

Cobertura Coverage Report > osm_nbi >

validation.py

Trend

Classes100%
 
Lines98%
   
Conditionals100%
 

File Coverage summary

NameClassesLinesConditionals
validation.py
100%
1/1
98%
124/126
100%
0/0

Coverage Breakdown by Class

NameLinesConditionals
validation.py
98%
124/126
N/A

Source

osm_nbi/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 1 from jsonschema import validate as js_v, exceptions as js_e
17 1 from http import HTTPStatus
18 1 from copy import deepcopy
19 1 from uuid import UUID   # To test for valid UUID
20
21 1 __author__ = "Alfonso Tierno <alfonso.tiernosepulveda@telefonica.com>"
22 1 __version__ = "0.1"
23 1 version_date = "Mar 2018"
24
25 """
26 Validator of input data using JSON schemas for those items that not contains an  OSM yang information model
27 """
28
29 # Basis schemas
30 1 patern_name = "^[ -~]+$"
31 1 shortname_schema = {"type": "string", "minLength": 1, "maxLength": 60, "pattern": "^[^,;()\\.\\$'\"]+$"}
32 1 passwd_schema = {"type": "string", "minLength": 1, "maxLength": 60}
33 1 name_schema = {"type": "string", "minLength": 1, "maxLength": 255, "pattern": "^[^,;()'\"]+$"}
34 1 string_schema = {"type": "string", "minLength": 1, "maxLength": 255}
35 1 xml_text_schema = {"type": "string", "minLength": 1, "maxLength": 1000, "pattern": "^[^']+$"}
36 1 description_schema = {"type": ["string", "null"], "maxLength": 255, "pattern": "^[^'\"]+$"}
37 1 id_schema_fake = {"type": "string", "minLength": 2, "maxLength": 36}
38 1 bool_schema = {"type": "boolean"}
39 1 null_schema = {"type": "null"}
40 # "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
41 1 id_schema = {"type": "string", "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"}
42 1 time_schema = {"type": "string", "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]([0-5]:){2}"}
43 1 pci_schema = {"type": "string", "pattern": "^[0-9a-fA-F]{4}(:[0-9a-fA-F]{2}){2}\\.[0-9a-fA-F]$"}
44 # allows [] for wildcards. For that reason huge length limit is set
45 1 pci_extended_schema = {"type": "string", "pattern": "^[0-9a-fA-F.:-\\[\\]]{12,40}$"}
46 1 http_schema = {"type": "string", "pattern": "^(https?|http)://[^'\"=]+$"}
47 1 bandwidth_schema = {"type": "string", "pattern": "^[0-9]+ *([MG]bps)?$"}
48 1 memory_schema = {"type": "string", "pattern": "^[0-9]+ *([MG]i?[Bb])?$"}
49 1 integer0_schema = {"type": "integer", "minimum": 0}
50 1 integer1_schema = {"type": "integer", "minimum": 1}
51 1 path_schema = {"type": "string", "pattern": "^(\\.){0,2}(/[^/\"':{}\\(\\)]+)+$"}
52 1 vlan_schema = {"type": "integer", "minimum": 1, "maximum": 4095}
53 1 vlan1000_schema = {"type": "integer", "minimum": 1000, "maximum": 4095}
54 1 mac_schema = {"type": "string",
55               "pattern": "^[0-9a-fA-F][02468aceACE](:[0-9a-fA-F]{2}){5}$"}  # must be unicast: LSB bit of MSB byte ==0
56 1 dpid_Schema = {"type": "string", "pattern": "^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){7}$"}
57 # mac_schema={"type":"string", "pattern":"^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$"}
58 1 ip_schema = {"type": "string",
59              "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"}
60 1 ip_prefix_schema = {"type": "string",
61                     "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}"
62                                "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/(30|[12]?[0-9])$"}
63 1 port_schema = {"type": "integer", "minimum": 1, "maximum": 65534}
64 1 object_schema = {"type": "object"}
65 1 schema_version_2 = {"type": "integer", "minimum": 2, "maximum": 2}
66 # schema_version_string={"type":"string","enum": ["0.1", "2", "0.2", "3", "0.3"]}
67 1 log_level_schema = {"type": "string", "enum": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]}
68 1 checksum_schema = {"type": "string", "pattern": "^[0-9a-fA-F]{32}$"}
69 1 size_schema = {"type": "integer", "minimum": 1, "maximum": 100}
70 1 array_edition_schema = {
71     "type": "object",
72     "patternProperties": {
73         "^\\$": {}
74     },
75     "additionalProperties": False,
76     "minProperties": 1,
77 }
78 1 nameshort_list_schema = {
79     "type": "array",
80     "minItems": 1,
81     "items": shortname_schema,
82 }
83
84
85 1 ns_instantiate_vdu = {
86     "title": "ns action instantiate input schema for vdu",
87     "$schema": "http://json-schema.org/draft-04/schema#",
88     "type": "object",
89     "properties": {
90         "id": name_schema,
91         "volume": {
92             "type": "array",
93             "minItems": 1,
94             "items": {
95                 "type": "object",
96                 "properties": {
97                     "name": name_schema,
98                     "vim-volume-id": name_schema,
99                 },
100                 "required": ["name", "vim-volume-id"],
101                 "additionalProperties": False
102             }
103         },
104         "interface": {
105             "type": "array",
106             "minItems": 1,
107             "items": {
108                 "type": "object",
109                 "properties": {
110                     "name": name_schema,
111                     "ip-address": ip_schema,
112                     "mac-address": mac_schema,
113                     "floating-ip-required": bool_schema,
114                 },
115                 "required": ["name"],
116                 "additionalProperties": False
117             }
118         }
119     },
120     "required": ["id"],
121     "additionalProperties": False
122 }
123
124 1 ip_profile_dns_schema = {
125     "type": "array",
126     "minItems": 1,
127     "items": {
128         "type": "object",
129         "properties": {
130             "address": ip_schema,
131         },
132         "required": ["address"],
133         "additionalProperties": False
134     }
135 }
136
137 1 ip_profile_dhcp_schema = {
138     "type": "object",
139     "properties": {
140         "enabled": {"type": "boolean"},
141         "count": integer1_schema,
142         "start-address": ip_schema
143     },
144     "additionalProperties": False,
145 }
146
147 1 ip_profile_schema = {
148     "title": "ip profile validation schema",
149     "$schema": "http://json-schema.org/draft-04/schema#",
150     "type": "object",
151     "properties": {
152         "ip-version": {"enum": ["ipv4", "ipv6"]},
153         "subnet-address": ip_prefix_schema,
154         "gateway-address": ip_schema,
155         "dns-server": ip_profile_dns_schema,
156         "dhcp-params": ip_profile_dhcp_schema,
157     }
158 }
159
160 1 ip_profile_update_schema = {
161     "title": "ip profile validation schema",
162     "$schema": "http://json-schema.org/draft-04/schema#",
163     "type": "object",
164     "properties": {
165         "ip-version": {"enum": ["ipv4", "ipv6"]},
166         "subnet-address": {"oneOf": [null_schema, ip_prefix_schema]},
167         "gateway-address": {"oneOf": [null_schema, ip_schema]},
168         "dns-server": {"oneOf": [null_schema, ip_profile_dns_schema]},
169
170         "dhcp-params": {"oneOf": [null_schema, ip_profile_dhcp_schema]},
171     },
172     "additionalProperties": False
173 }
174
175 1 provider_network_schema = {
176     "title": "provider network validation schema",
177     "$schema": "http://json-schema.org/draft-04/schema#",
178     "type": "object",
179     "properties": {
180         "physical-network": name_schema,
181         "segmentation-id": name_schema,
182         "sdn-ports": {  # external ports to append to the SDN-assist network
183             "type": "array",
184             "items": {
185                 "type": "object",
186                 "properties": {
187                     "switch_id": shortname_schema,
188                     "switch_port": shortname_schema,
189                     "mac_address": mac_schema,
190                     "vlan": vlan_schema,
191                 },
192                 "additionalProperties": True
193             }
194         },
195         "network-type": shortname_schema,
196     },
197     "additionalProperties": True
198 }
199
200 1 ns_instantiate_internal_vld = {
201     "title": "ns action instantiate input schema for vdu",
202     "$schema": "http://json-schema.org/draft-04/schema#",
203     "type": "object",
204     "properties": {
205         "name": name_schema,
206         "vim-network-name": name_schema,
207         "vim-network-id": name_schema,
208         "ip-profile": ip_profile_update_schema,
209         "provider-network": provider_network_schema,
210         "internal-connection-point": {
211             "type": "array",
212             "minItems": 1,
213             "items": {
214                 "type": "object",
215                 "properties": {
216                     "id-ref": name_schema,
217                     "ip-address": ip_schema,
218                     # "mac-address": mac_schema,
219                 },
220                 "required": ["id-ref"],
221                 "minProperties": 2,
222                 "additionalProperties": False
223             },
224         }
225     },
226     "required": ["name"],
227     "minProperties": 2,
228     "additionalProperties": False
229 }
230
231 1 additional_params_for_vnf = {
232     "type": "array",
233     "items": {
234         "type": "object",
235         "properties": {
236             "member-vnf-index": name_schema,
237             "additionalParams": object_schema,
238             "k8s-namespace": name_schema,
239             "config-units": integer1_schema,  # number of configuration units of this vnf, by default 1
240             "additionalParamsForVdu": {
241                 "type": "array",
242                 "items": {
243                     "type": "object",
244                     "properties": {
245                         "vdu_id": name_schema,
246                         "additionalParams": object_schema,
247                         "config-units": integer1_schema,   # number of configuration units of this vdu, by default 1
248                     },
249                     "required": ["vdu_id"],
250                     "minProperties": 2,
251                     "additionalProperties": False,
252                 },
253             },
254             "additionalParamsForKdu": {
255                 "type": "array",
256                 "items": {
257                     "type": "object",
258                     "properties": {
259                         "kdu_name": name_schema,
260                         "additionalParams": object_schema,
261                         "kdu_model": name_schema,
262                         "k8s-namespace": name_schema,
263                         "config-units": integer1_schema,    # number of configuration units of this knf, by default 1
264                     },
265                     "required": ["kdu_name"],
266                     "minProperties": 2,
267                     "additionalProperties": False,
268                 },
269             },
270         },
271         "required": ["member-vnf-index"],
272         "minProperties": 2,
273         "additionalProperties": False
274     }
275 }
276
277 1 ns_instantiate = {
278     "title": "ns action instantiate input schema",
279     "$schema": "http://json-schema.org/draft-04/schema#",
280     "type": "object",
281     "properties": {
282         "lcmOperationType": string_schema,
283         "nsInstanceId": id_schema,
284         "netsliceInstanceId": id_schema,
285         "nsName": name_schema,
286         "nsDescription": {"oneOf": [description_schema, null_schema]},
287         "nsdId": id_schema,
288         "vimAccountId": id_schema,
289         "wimAccountId": {"oneOf": [id_schema, bool_schema, null_schema]},
290         "placement-engine": string_schema,
291         "placement-constraints": object_schema,
292         "additionalParamsForNs": object_schema,
293         "additionalParamsForVnf": additional_params_for_vnf,
294         "config-units": integer1_schema,    # number of configuration units of this ns, by default 1
295         "k8s-namespace": name_schema,
296         "ssh_keys": {"type": "array", "items": {"type": "string"}},
297         "timeout_ns_deploy": integer1_schema,
298         "nsr_id": id_schema,
299         "vduImage": name_schema,
300         "vnf": {
301             "type": "array",
302             "minItems": 1,
303             "items": {
304                 "type": "object",
305                 "properties": {
306                     "member-vnf-index": name_schema,
307                     "vimAccountId": id_schema,
308                     "vdu": {
309                         "type": "array",
310                         "minItems": 1,
311                         "items": ns_instantiate_vdu,
312                     },
313                     "internal-vld": {
314                         "type": "array",
315                         "minItems": 1,
316                         "items": ns_instantiate_internal_vld
317                     }
318                 },
319                 "required": ["member-vnf-index"],
320                 "minProperties": 2,
321                 "additionalProperties": False
322             }
323         },
324         "vld": {
325             "type": "array",
326             "minItems": 1,
327             "items": {
328                 "type": "object",
329                 "properties": {
330                     "name": string_schema,
331                     "vim-network-name": {"oneOf": [string_schema, object_schema]},
332                     "vim-network-id": {"oneOf": [string_schema, object_schema]},
333                     "ns-net": object_schema,
334                     "wimAccountId": {"oneOf": [id_schema, bool_schema, null_schema]},
335                     "ip-profile": object_schema,
336                     "provider-network": provider_network_schema,
337                     "vnfd-connection-point-ref": {
338                         "type": "array",
339                         "minItems": 1,
340                         "items": {
341                             "type": "object",
342                             "properties": {
343                                 "member-vnf-index-ref": name_schema,
344                                 "vnfd-connection-point-ref": name_schema,
345                                 "ip-address": ip_schema,
346                                 # "mac-address": mac_schema,
347                             },
348                             "required": ["member-vnf-index-ref", "vnfd-connection-point-ref"],
349                             "minProperties": 3,
350                             "additionalProperties": False
351                         },
352                     }
353                 },
354                 "required": ["name"],
355                 "additionalProperties": False
356             }
357         },
358     },
359     "required": ["nsName", "nsdId", "vimAccountId"],
360     "additionalProperties": False
361 }
362
363 1 ns_terminate = {
364     "title": "ns terminate input schema",
365     "$schema": "http://json-schema.org/draft-04/schema#",
366     "type": "object",
367     "properties": {
368         "lcmOperationType": string_schema,
369         "nsInstanceId": id_schema,
370         "autoremove": bool_schema,
371         "timeout_ns_terminate": integer1_schema,
372         "skip_terminate_primitives": bool_schema,
373         "netsliceInstanceId": id_schema,
374     },
375     "additionalProperties": False
376 }
377
378 1 ns_action = {   # TODO for the moment it is only contemplated the vnfd primitive execution
379     "title": "ns action input schema",
380     "$schema": "http://json-schema.org/draft-04/schema#",
381     "type": "object",
382     "properties": {
383         "lcmOperationType": string_schema,
384         "nsInstanceId": id_schema,
385         "member_vnf_index": name_schema,
386         "vnf_member_index": name_schema,  # TODO for backward compatibility. To remove in future
387         "vdu_id": name_schema,
388         "vdu_count_index": integer0_schema,
389         "kdu_name": name_schema,
390         "primitive": name_schema,
391         "timeout_ns_action": integer1_schema,
392         "primitive_params": {"type": "object"},
393     },
394     "required": ["primitive", "primitive_params"],   # TODO add member_vnf_index
395     "additionalProperties": False
396 }
397 1 ns_scale = {   # TODO for the moment it is only VDU-scaling
398     "title": "ns scale input schema",
399     "$schema": "http://json-schema.org/draft-04/schema#",
400     "type": "object",
401     "properties": {
402         "lcmOperationType": string_schema,
403         "nsInstanceId": id_schema,
404         "scaleType": {"enum": ["SCALE_VNF"]},
405         "timeout_ns_scale": integer1_schema,
406         "scaleVnfData": {
407             "type": "object",
408             "properties": {
409                 "vnfInstanceId": name_schema,
410                 "scaleVnfType": {"enum": ["SCALE_OUT", 'SCALE_IN']},
411                 "scaleByStepData": {
412                     "type": "object",
413                     "properties": {
414                         "scaling-group-descriptor": name_schema,
415                         "member-vnf-index": name_schema,
416                         "scaling-policy": name_schema,
417                     },
418                     "required": ["scaling-group-descriptor", "member-vnf-index"],
419                     "additionalProperties": False
420                 },
421             },
422             "required": ["scaleVnfType", "scaleByStepData"],  # vnfInstanceId
423             "additionalProperties": False
424         },
425         "scaleTime": time_schema,
426     },
427     "required": ["scaleType", "scaleVnfData"],
428     "additionalProperties": False
429 }
430
431
432 1 schema_version = {"type": "string", "enum": ["1.0"]}
433 1 schema_type = {"type": "string"}
434 1 vim_type = shortname_schema  # {"enum": ["openstack", "openvim", "vmware", "opennebula", "aws", "azure", "fos"]}
435
436 1 vim_account_edit_schema = {
437     "title": "vim_account edit input schema",
438     "$schema": "http://json-schema.org/draft-04/schema#",
439     "type": "object",
440     "properties": {
441         "name": name_schema,
442         "description": description_schema,
443         "vim": name_schema,
444         "datacenter": name_schema,
445         "vim_type": vim_type,
446         "vim_url": description_schema,
447         # "vim_url_admin": description_schema,
448         # "vim_tenant": name_schema,
449         "vim_tenant_name": name_schema,
450         "vim_user": shortname_schema,
451         "vim_password": passwd_schema,
452         "config": {"type": "object"}
453     },
454     "additionalProperties": False
455 }
456
457 1 vim_account_new_schema = {
458     "title": "vim_account creation input schema",
459     "$schema": "http://json-schema.org/draft-04/schema#",
460     "type": "object",
461     "properties": {
462         "schema_version": schema_version,
463         "schema_type": schema_type,
464         "name": name_schema,
465         "description": description_schema,
466         "vim": name_schema,
467         "datacenter": name_schema,
468         "vim_type": vim_type,
469         "vim_url": description_schema,
470         # "vim_url_admin": description_schema,
471         # "vim_tenant": name_schema,
472         "vim_tenant_name": name_schema,
473         "vim_user": shortname_schema,
474         "vim_password": passwd_schema,
475         "config": {"type": "object"}
476     },
477     "required": ["name", "vim_url", "vim_type", "vim_user", "vim_password", "vim_tenant_name"],
478     "additionalProperties": False
479 }
480
481 1 wim_type = shortname_schema  # {"enum": ["ietfl2vpn", "onos", "odl", "dynpac", "fake"]}
482
483 1 wim_account_edit_schema = {
484     "title": "wim_account edit input schema",
485     "$schema": "http://json-schema.org/draft-04/schema#",
486     "type": "object",
487     "properties": {
488         "name": name_schema,
489         "description": description_schema,
490         "wim": name_schema,
491         "wim_type": wim_type,
492         "wim_url": description_schema,
493         "user": shortname_schema,
494         "password": passwd_schema,
495         "config": {"type": "object"}
496     },
497     "additionalProperties": False
498 }
499
500 1 wim_account_new_schema = {
501     "title": "wim_account creation input schema",
502     "$schema": "http://json-schema.org/draft-04/schema#",
503     "type": "object",
504     "properties": {
505         "schema_version": schema_version,
506         "schema_type": schema_type,
507         "name": name_schema,
508         "description": description_schema,
509         "wim": name_schema,
510         "wim_type": wim_type,
511         "wim_url": description_schema,
512         "user": shortname_schema,
513         "password": passwd_schema,
514         "config": {
515             "type": "object",
516             "patternProperties": {
517                 ".": {"not": {"type": "null"}}
518             }
519         }
520     },
521     "required": ["name", "wim_url", "wim_type"],
522     "additionalProperties": False
523 }
524
525 1 sdn_properties = {
526     "name": name_schema,
527     "type": {"type": "string"},
528     "url": {"type": "string"},
529     "user": shortname_schema,
530     "password": passwd_schema,
531     "config": {"type": "object"},
532     "description": description_schema,
533     # The folowing are deprecated. Maintanied for backward compatibility
534     "dpid": dpid_Schema,
535     "ip": ip_schema,
536     "port": port_schema,
537     "version": {"type": "string", "minLength": 1, "maxLength": 12},
538 }
539 1 sdn_new_schema = {
540     "title": "sdn controller information schema",
541     "$schema": "http://json-schema.org/draft-04/schema#",
542     "type": "object",
543     "properties": sdn_properties,
544     "required": ["name", 'type'],
545     "additionalProperties": False
546 }
547 1 sdn_edit_schema = {
548     "title": "sdn controller update information schema",
549     "$schema": "http://json-schema.org/draft-04/schema#",
550     "type": "object",
551     "properties": sdn_properties,
552     # "required": ["name", "port", 'ip', 'dpid', 'type'],
553     "additionalProperties": False
554 }
555 1 sdn_port_mapping_schema = {
556     "$schema": "http://json-schema.org/draft-04/schema#",
557     "title": "sdn port mapping information schema",
558     "type": "array",
559     "items": {
560         "type": "object",
561         "properties": {
562             "compute_node": shortname_schema,
563             "ports": {
564                 "type": "array",
565                 "items": {
566                     "type": "object",
567                     "properties": {
568                         "pci": pci_extended_schema,
569                         "switch_port": shortname_schema,
570                         "switch_mac": mac_schema
571                     },
572                     "required": ["pci"]
573                 }
574             }
575         },
576         "required": ["compute_node", "ports"]
577     }
578 }
579 1 sdn_external_port_schema = {
580     "$schema": "http://json-schema.org/draft-04/schema#",
581     "title": "External port information",
582     "type": "object",
583     "properties": {
584         "port": {"type": "string", "minLength": 1, "maxLength": 60},
585         "vlan": vlan_schema,
586         "mac": mac_schema
587     },
588     "required": ["port"]
589 }
590
591 # K8s Clusters
592 1 k8scluster_nets_schema = {
593     "title": "k8scluster nets input schema",
594     "$schema": "http://json-schema.org/draft-04/schema#",
595     "type": "object",
596     "patternProperties": {".": {"oneOf": [name_schema, null_schema]}},
597     "minProperties": 1,
598     "additionalProperties": False
599 }
600 1 k8scluster_new_schema = {
601     "title": "k8scluster creation input schema",
602     "$schema": "http://json-schema.org/draft-04/schema#",
603     "type": "object",
604     "properties": {
605         "schema_version": schema_version,
606         "schema_type": schema_type,
607         "name": name_schema,
608         "description": description_schema,
609         "credentials": object_schema,
610         "vim_account": id_schema,
611         "k8s_version": string_schema,
612         "nets": k8scluster_nets_schema,
613         "namespace": name_schema,
614         "cni": nameshort_list_schema,
615     },
616     "required": ["name", "credentials", "vim_account", "k8s_version", "nets"],
617     "additionalProperties": False
618 }
619 1 k8scluster_edit_schema = {
620     "title": "vim_account edit input schema",
621     "$schema": "http://json-schema.org/draft-04/schema#",
622     "type": "object",
623     "properties": {
624         "name": name_schema,
625         "description": description_schema,
626         "credentials": object_schema,
627         "vim_account": id_schema,
628         "k8s_version": string_schema,
629         "nets": k8scluster_nets_schema,
630         "namespace": name_schema,
631         "cni": nameshort_list_schema,
632     },
633     "additionalProperties": False
634 }
635
636 # K8s Repos
637 1 k8srepo_types = {"enum": ["helm-chart", "juju-bundle"]}
638 1 k8srepo_properties = {
639     "name": name_schema,
640     "description": description_schema,
641     "type": k8srepo_types,
642     "url": description_schema,
643 }
644 1 k8srepo_new_schema = {
645     "title": "k8scluster creation input schema",
646     "$schema": "http://json-schema.org/draft-04/schema#",
647     "type": "object",
648     "properties": k8srepo_properties,
649     "required": ["name", "type", "url"],
650     "additionalProperties": False
651 }
652 1 k8srepo_edit_schema = {
653     "title": "vim_account edit input schema",
654     "$schema": "http://json-schema.org/draft-04/schema#",
655     "type": "object",
656     "properties": k8srepo_properties,
657     "additionalProperties": False
658 }
659
660 # OSM Repos
661 1 osmrepo_types = {"enum": ["osm"]}
662 1 osmrepo_properties = {
663     "name": name_schema,
664     "description": description_schema,
665     "type": osmrepo_types,
666     "url": description_schema
667     # "user": shortname_schema,
668     # "password": passwd_schema
669 }
670 1 osmrepo_new_schema = {
671     "title": "osm repo creation input schema",
672     "$schema": "http://json-schema.org/draft-04/schema#",
673     "type": "object",
674     "properties": osmrepo_properties,
675     "required": ["name", "type", "url"],
676     "additionalProperties": False
677 }
678 1 osmrepo_edit_schema = {
679     "title": "osm repo edit input schema",
680     "$schema": "http://json-schema.org/draft-04/schema#",
681     "type": "object",
682     "properties": osmrepo_properties,
683     "additionalProperties": False
684 }
685
686 # PDUs
687 1 pdu_interface = {
688     "type": "object",
689     "properties": {
690         "name": shortname_schema,
691         "mgmt": bool_schema,
692         "type": {"enum": ["overlay", 'underlay']},
693         "ip-address": ip_schema,
694         # TODO, add user, password, ssh-key
695         "mac-address": mac_schema,
696         "vim-network-name": shortname_schema,  # interface is connected to one vim network, or switch port
697         "vim-network-id": shortname_schema,
698         # # provide this in case SDN assist must deal with this interface
699         # "switch-dpid": dpid_Schema,
700         # "switch-port": shortname_schema,
701         # "switch-mac": shortname_schema,
702         # "switch-vlan": vlan_schema,
703     },
704     "required": ["name", "mgmt", "ip-address"],
705     "additionalProperties": False
706 }
707 1 pdu_new_schema = {
708     "title": "pdu creation input schema",
709     "$schema": "http://json-schema.org/draft-04/schema#",
710     "type": "object",
711     "properties": {
712         "name": shortname_schema,
713         "type": shortname_schema,
714         "description": description_schema,
715         "shared": bool_schema,
716         "vims": nameshort_list_schema,
717         "vim_accounts": nameshort_list_schema,
718         "interfaces": {
719             "type": "array",
720             "items": pdu_interface,
721             "minItems": 1
722         }
723     },
724     "required": ["name", "type", "interfaces"],
725     "additionalProperties": False
726 }
727 1 pdu_edit_schema = {
728     "title": "pdu edit input schema",
729     "$schema": "http://json-schema.org/draft-04/schema#",
730     "type": "object",
731     "properties": {
732         "name": shortname_schema,
733         "type": shortname_schema,
734         "description": description_schema,
735         "shared": bool_schema,
736         "vims": {"oneOf": [array_edition_schema, nameshort_list_schema]},
737         "vim_accounts": {"oneOf": [array_edition_schema, nameshort_list_schema]},
738         "interfaces": {"oneOf": [
739             array_edition_schema,
740             {
741                 "type": "array",
742                 "items": pdu_interface,
743                 "minItems": 1
744             }
745         ]}
746     },
747     "additionalProperties": False,
748     "minProperties": 1
749 }
750
751 # VNF PKG OPERATIONS
752 1 vnfpkgop_new_schema = {
753     "title": "VNF PKG operation creation input schema",
754     "$schema": "http://json-schema.org/draft-04/schema#",
755     "type": "object",
756     "properties": {
757         "lcmOperationType": string_schema,
758         "vnfPkgId": id_schema,
759         "kdu_name": name_schema,
760         "primitive": name_schema,
761         "primitive_params": {"type": "object"},
762     },
763     "required": ["lcmOperationType", "vnfPkgId", "kdu_name", "primitive", "primitive_params"],
764     "additionalProperties": False
765 }
766
767 # USERS
768 1 project_role_mappings = {
769     "title": "list pf projects/roles",
770     "$schema": "http://json-schema.org/draft-04/schema#",
771     "type": "array",
772     "items": {
773         "type": "object",
774         "properties": {
775             "project": shortname_schema,
776             "role": shortname_schema
777         },
778         "required": ["project", "role"],
779         "additionalProperties": False
780     },
781     "minItems": 1
782 }
783 1 project_role_mappings_optional = {
784     "title": "list of projects/roles or projects only",
785     "$schema": "http://json-schema.org/draft-04/schema#",
786     "type": "array",
787     "items": {
788         "type": "object",
789         "properties": {
790             "project": shortname_schema,
791             "role": shortname_schema
792         },
793         "required": ["project"],
794         "additionalProperties": False
795     },
796     "minItems": 1
797 }
798 1 user_new_schema = {
799     "$schema": "http://json-schema.org/draft-04/schema#",
800     "title": "New user schema",
801     "type": "object",
802     "properties": {
803         "username": shortname_schema,
804         "domain_name": shortname_schema,
805         "password": passwd_schema,
806         "projects": nameshort_list_schema,
807         "project_role_mappings": project_role_mappings,
808     },
809     "required": ["username", "password"],
810     "additionalProperties": False
811 }
812 1 user_edit_schema = {
813     "$schema": "http://json-schema.org/draft-04/schema#",
814     "title": "User edit schema for administrators",
815     "type": "object",
816     "properties": {
817         "password": passwd_schema,
818         "username": shortname_schema,     # To allow User Name modification
819         "projects": {
820             "oneOf": [
821                 nameshort_list_schema,
822                 array_edition_schema
823             ]
824         },
825         "project_role_mappings": project_role_mappings,
826         "add_project_role_mappings": project_role_mappings,
827         "remove_project_role_mappings": project_role_mappings_optional,
828     },
829     "minProperties": 1,
830     "additionalProperties": False
831 }
832
833 # PROJECTS
834 1 topics_with_quota = ["vnfds", "nsds", "slice_templates", "pduds", "ns_instances", "slice_instances", "vim_accounts",
835                      "wim_accounts", "sdn_controllers", "k8sclusters", "k8srepos", "osmrepos", "ns_subscriptions"]
836 1 project_new_schema = {
837     "$schema": "http://json-schema.org/draft-04/schema#",
838     "title": "New project schema for administrators",
839     "type": "object",
840     "properties": {
841         "name": shortname_schema,
842         "admin": bool_schema,
843         "domain_name": shortname_schema,
844         "quotas": {
845             "type": "object",
846             "properties": {topic: integer0_schema for topic in topics_with_quota},
847             "additionalProperties": False
848         },
849     },
850     "required": ["name"],
851     "additionalProperties": False
852 }
853 1 project_edit_schema = {
854     "$schema": "http://json-schema.org/draft-04/schema#",
855     "title": "Project edit schema for administrators",
856     "type": "object",
857     "properties": {
858         "admin": bool_schema,
859         "name": shortname_schema,     # To allow Project Name modification
860         "quotas": {
861             "type": "object",
862             "properties": {topic: {"oneOf": [integer0_schema, null_schema]} for topic in topics_with_quota},
863             "additionalProperties": False
864         },
865     },
866     "additionalProperties": False,
867     "minProperties": 1
868 }
869
870 # ROLES
871 1 roles_new_schema = {
872     "$schema": "http://json-schema.org/draft-04/schema#",
873     "title": "New role schema for administrators",
874     "type": "object",
875     "properties": {
876         "name": shortname_schema,
877         "permissions": {
878             "type": "object",
879             "patternProperties": {
880                 ".": bool_schema,
881             },
882             # "minProperties": 1,
883         }
884     },
885     "required": ["name"],
886     "additionalProperties": False
887 }
888 1 roles_edit_schema = {
889     "$schema": "http://json-schema.org/draft-04/schema#",
890     "title": "Roles edit schema for administrators",
891     "type": "object",
892     "properties": {
893         "name": shortname_schema,
894         "permissions": {
895             "type": "object",
896             "patternProperties": {
897                 ".": {
898                     "oneOf": [bool_schema, null_schema]
899                 }
900             },
901             # "minProperties": 1,
902         }
903     },
904     "additionalProperties": False,
905     "minProperties": 1
906 }
907
908 # GLOBAL SCHEMAS
909
910 1 nbi_new_input_schemas = {
911     "users": user_new_schema,
912     "projects": project_new_schema,
913     "vim_accounts": vim_account_new_schema,
914     "sdns": sdn_new_schema,
915     "ns_instantiate": ns_instantiate,
916     "ns_action": ns_action,
917     "ns_scale": ns_scale,
918     "pdus": pdu_new_schema,
919 }
920
921 1 nbi_edit_input_schemas = {
922     "users": user_edit_schema,
923     "projects": project_edit_schema,
924     "vim_accounts": vim_account_edit_schema,
925     "sdns": sdn_edit_schema,
926     "pdus": pdu_edit_schema,
927 }
928
929 # NETSLICE SCHEMAS
930 1 nsi_subnet_instantiate = deepcopy(ns_instantiate)
931 1 nsi_subnet_instantiate["title"] = "netslice subnet instantiation params input schema"
932 1 nsi_subnet_instantiate["properties"]["id"] = name_schema
933 1 del nsi_subnet_instantiate["required"]
934
935 1 nsi_vld_instantiate = {
936     "title": "netslice vld instantiation params input schema",
937     "$schema": "http://json-schema.org/draft-04/schema#",
938     "type": "object",
939     "properties": {
940         "name": string_schema,
941         "vim-network-name": {"oneOf": [string_schema, object_schema]},
942         "vim-network-id": {"oneOf": [string_schema, object_schema]},
943         "ip-profile": object_schema,
944     },
945     "required": ["name"],
946     "additionalProperties": False
947 }
948
949 1 nsi_instantiate = {
950     "title": "netslice action instantiate input schema",
951     "$schema": "http://json-schema.org/draft-04/schema#",
952     "type": "object",
953     "properties": {
954         "lcmOperationType": string_schema,
955         "netsliceInstanceId": id_schema,
956         "nsiName": name_schema,
957         "nsiDescription": {"oneOf": [description_schema, null_schema]},
958         "nstId": string_schema,
959         "vimAccountId": id_schema,
960         "timeout_nsi_deploy": integer1_schema,
961         "ssh_keys": {"type": "array", "items": {"type": "string"}},
962         "nsi_id": id_schema,
963         "additionalParamsForNsi": object_schema,
964         "netslice-subnet": {
965             "type": "array",
966             "minItems": 1,
967             "items": nsi_subnet_instantiate
968         },
969         "netslice-vld": {
970             "type": "array",
971             "minItems": 1,
972             "items": nsi_vld_instantiate
973         },
974     },
975     "required": ["nsiName", "nstId", "vimAccountId"],
976     "additionalProperties": False
977 }
978
979 1 nsi_action = {
980
981 }
982
983 1 nsi_terminate = {
984
985 }
986
987 1 nsinstancesubscriptionfilter_schema = {
988     "title": "instance identifier schema",
989     "$schema": "http://json-schema.org/draft-07/schema#",
990     "type": "object",
991     "properties": {
992         "nsdIds": {"type": "array"},
993         "vnfdIds": {"type": "array"},
994         "pnfdIds": {"type": "array"},
995         "nsInstanceIds": {"type": "array"},
996         "nsInstanceNames": {"type": "array"},
997     },
998 }
999
1000 1 nslcmsub_schema = {
1001     "title": "nslcmsubscription input schema",
1002     "$schema": "http://json-schema.org/draft-07/schema#",
1003     "type": "object",
1004     "properties": {
1005         "nsInstanceSubscriptionFilter": nsinstancesubscriptionfilter_schema,
1006         "notificationTypes": {
1007             "type": "array",
1008             "items": {
1009                 "enum": ['NsLcmOperationOccurrenceNotification', 'NsChangeNotification',
1010                          'NsIdentifierCreationNotification', 'NsIdentifierDeletionNotification']
1011             }
1012         },
1013         "operationTypes": {
1014             "type": "array",
1015             "items": {
1016                 "enum": ['INSTANTIATE', 'SCALE', 'TERMINATE', 'UPDATE', 'HEAL']
1017             }
1018         },
1019         "operationStates": {
1020             "type": "array",
1021             "items": {
1022                 "enum": ['PROCESSING', 'COMPLETED', 'PARTIALLY_COMPLETED', 'FAILED',
1023                          'FAILED_TEMP', 'ROLLING_BACK', 'ROLLED_BACK']
1024             }
1025         },
1026         "nsComponentTypes": {
1027             "type": "array",
1028             "items": {
1029                 "enum": ['VNF', 'NS', 'PNF']
1030             }
1031         },
1032         "lcmOpNameImpactingNsComponent": {
1033             "type": "array",
1034             "items": {
1035                 "enum": ['VNF_INSTANTIATE', 'VNF_SCALE', 'VNF_SCALE_TO_LEVEL', 'VNF_CHANGE_FLAVOUR',
1036                          'VNF_TERMINATE', 'VNF_HEAL', 'VNF_OPERATE', 'VNF_CHANGE_EXT_CONN', 'VNF_MODIFY_INFO',
1037                          'NS_INSTANTIATE', 'NS_SCALE', 'NS_UPDATE', 'NS_TERMINATE', 'NS_HEAL']
1038             }
1039         },
1040         "lcmOpOccStatusImpactingNsComponent": {
1041             "type": "array",
1042             "items": {
1043                 "enum": ['START', 'COMPLETED', 'PARTIALLY_COMPLETED', 'FAILED', 'ROLLED_BACK']
1044             }
1045         },
1046     },
1047     "allOf": [
1048         {
1049             "if": {
1050                 "properties": {
1051                     "notificationTypes": {
1052                         "contains": {"const": "NsLcmOperationOccurrenceNotification"}
1053                     }
1054                 },
1055             },
1056             "then": {
1057                 "anyOf": [
1058                     {"required": ["operationTypes"]},
1059                     {"required": ["operationStates"]},
1060                 ]
1061             } 
1062         },
1063         {
1064             "if": {
1065                 "properties": {
1066                     "notificationTypes": {
1067                         "contains": {"const": "NsChangeNotification"}
1068                     }
1069                 },
1070             },
1071             "then": {
1072                 "anyOf": [
1073                     {"required": ["nsComponentTypes"]},
1074                     {"required": ["lcmOpNameImpactingNsComponent"]},
1075                     {"required": ["lcmOpOccStatusImpactingNsComponent"]},
1076                 ]
1077             }
1078         }
1079     ]
1080 }
1081
1082 1 authentication_schema = {
1083     "title": "authentication schema for subscription",
1084     "$schema": "http://json-schema.org/draft-07/schema#",
1085     "type": "object",
1086     "properties": {
1087         "authType": {"enum": ["basic"]},
1088         "paramsBasic": {
1089             "type": "object",
1090             "properties": {
1091                 "userName": shortname_schema,
1092                 "password": passwd_schema,
1093             },
1094         },
1095     },
1096 }
1097
1098 1 subscription = {
1099     "title": "subscription input schema",
1100     "$schema": "http://json-schema.org/draft-07/schema#",
1101     "type": "object",
1102     "properties": {
1103         "filter": nslcmsub_schema,
1104         "CallbackUri": description_schema,
1105         "authentication": authentication_schema
1106     },
1107     "required": ["CallbackUri"],
1108 }
1109
1110
1111 1 class ValidationError(Exception):
1112 1     def __init__(self, message, http_code=HTTPStatus.UNPROCESSABLE_ENTITY):
1113 1         self.http_code = http_code
1114 1         Exception.__init__(self, message)
1115
1116
1117 1 def validate_input(indata, schema_to_use):
1118     """
1119     Validates input data against json schema
1120     :param indata: user input data. Should be a dictionary
1121     :param schema_to_use: jsonschema to test
1122     :return: None if ok, raises ValidationError exception on error
1123     """
1124 1     try:
1125 1         if schema_to_use:
1126 1             js_v(indata, schema_to_use)
1127 1         return None
1128 1     except js_e.ValidationError as e:
1129 1         if e.path:
1130 1             error_pos = "at '" + ":".join(map(str, e.path)) + "'"
1131         else:
1132 1             error_pos = ""
1133 1         raise ValidationError("Format error {} '{}' ".format(error_pos, e.message))
1134 0     except js_e.SchemaError:
1135 0         raise ValidationError("Bad json schema {}".format(schema_to_use), http_code=HTTPStatus.INTERNAL_SERVER_ERROR)
1136
1137
1138 1 def is_valid_uuid(x):
1139     """
1140     Test for a valid UUID
1141     :param x: string to test
1142     :return: True if x is a valid uuid, False otherwise
1143     """
1144 1     try:
1145 1         if UUID(x):
1146 1             return True
1147 1     except (TypeError, ValueError, AttributeError):
1148 1         return False