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                         "kdu-deployment-name": name_schema,
265                     },
266                     "required": ["kdu_name"],
267                     "minProperties": 2,
268                     "additionalProperties": False,
269                 },
270             },
271         },
272         "required": ["member-vnf-index"],
273         "minProperties": 2,
274         "additionalProperties": False
275     }
276 }
277
278 1 ns_instantiate = {
279     "title": "ns action instantiate input schema",
280     "$schema": "http://json-schema.org/draft-04/schema#",
281     "type": "object",
282     "properties": {
283         "lcmOperationType": string_schema,
284         "nsInstanceId": id_schema,
285         "netsliceInstanceId": id_schema,
286         "nsName": name_schema,
287         "nsDescription": {"oneOf": [description_schema, null_schema]},
288         "nsdId": id_schema,
289         "vimAccountId": id_schema,
290         "wimAccountId": {"oneOf": [id_schema, bool_schema, null_schema]},
291         "placement-engine": string_schema,
292         "placement-constraints": object_schema,
293         "additionalParamsForNs": object_schema,
294         "additionalParamsForVnf": additional_params_for_vnf,
295         "config-units": integer1_schema,    # number of configuration units of this ns, by default 1
296         "k8s-namespace": name_schema,
297         "ssh_keys": {"type": "array", "items": {"type": "string"}},
298         "timeout_ns_deploy": integer1_schema,
299         "nsr_id": id_schema,
300         "vduImage": name_schema,
301         "vnf": {
302             "type": "array",
303             "minItems": 1,
304             "items": {
305                 "type": "object",
306                 "properties": {
307                     "member-vnf-index": name_schema,
308                     "vimAccountId": id_schema,
309                     "vdu": {
310                         "type": "array",
311                         "minItems": 1,
312                         "items": ns_instantiate_vdu,
313                     },
314                     "internal-vld": {
315                         "type": "array",
316                         "minItems": 1,
317                         "items": ns_instantiate_internal_vld
318                     }
319                 },
320                 "required": ["member-vnf-index"],
321                 "minProperties": 2,
322                 "additionalProperties": False
323             }
324         },
325         "vld": {
326             "type": "array",
327             "minItems": 1,
328             "items": {
329                 "type": "object",
330                 "properties": {
331                     "name": string_schema,
332                     "vim-network-name": {"oneOf": [string_schema, object_schema]},
333                     "vim-network-id": {"oneOf": [string_schema, object_schema]},
334                     "ns-net": object_schema,
335                     "wimAccountId": {"oneOf": [id_schema, bool_schema, null_schema]},
336                     "ip-profile": object_schema,
337                     "provider-network": provider_network_schema,
338                     "vnfd-connection-point-ref": {
339                         "type": "array",
340                         "minItems": 1,
341                         "items": {
342                             "type": "object",
343                             "properties": {
344                                 "member-vnf-index-ref": name_schema,
345                                 "vnfd-connection-point-ref": name_schema,
346                                 "ip-address": ip_schema,
347                                 # "mac-address": mac_schema,
348                             },
349                             "required": ["member-vnf-index-ref", "vnfd-connection-point-ref"],
350                             "minProperties": 3,
351                             "additionalProperties": False
352                         },
353                     }
354                 },
355                 "required": ["name"],
356                 "additionalProperties": False
357             }
358         },
359     },
360     "required": ["nsName", "nsdId", "vimAccountId"],
361     "additionalProperties": False
362 }
363
364 1 ns_terminate = {
365     "title": "ns terminate input schema",
366     "$schema": "http://json-schema.org/draft-04/schema#",
367     "type": "object",
368     "properties": {
369         "lcmOperationType": string_schema,
370         "nsInstanceId": id_schema,
371         "autoremove": bool_schema,
372         "timeout_ns_terminate": integer1_schema,
373         "skip_terminate_primitives": bool_schema,
374         "netsliceInstanceId": id_schema,
375     },
376     "additionalProperties": False
377 }
378
379 1 ns_action = {   # TODO for the moment it is only contemplated the vnfd primitive execution
380     "title": "ns action input schema",
381     "$schema": "http://json-schema.org/draft-04/schema#",
382     "type": "object",
383     "properties": {
384         "lcmOperationType": string_schema,
385         "nsInstanceId": id_schema,
386         "member_vnf_index": name_schema,
387         "vnf_member_index": name_schema,  # TODO for backward compatibility. To remove in future
388         "vdu_id": name_schema,
389         "vdu_count_index": integer0_schema,
390         "kdu_name": name_schema,
391         "primitive": name_schema,
392         "timeout_ns_action": integer1_schema,
393         "primitive_params": {"type": "object"},
394     },
395     "required": ["primitive", "primitive_params"],   # TODO add member_vnf_index
396     "additionalProperties": False
397 }
398 1 ns_scale = {   # TODO for the moment it is only VDU-scaling
399     "title": "ns scale input schema",
400     "$schema": "http://json-schema.org/draft-04/schema#",
401     "type": "object",
402     "properties": {
403         "lcmOperationType": string_schema,
404         "nsInstanceId": id_schema,
405         "scaleType": {"enum": ["SCALE_VNF"]},
406         "timeout_ns_scale": integer1_schema,
407         "scaleVnfData": {
408             "type": "object",
409             "properties": {
410                 "vnfInstanceId": name_schema,
411                 "scaleVnfType": {"enum": ["SCALE_OUT", 'SCALE_IN']},
412                 "scaleByStepData": {
413                     "type": "object",
414                     "properties": {
415                         "scaling-group-descriptor": name_schema,
416                         "member-vnf-index": name_schema,
417                         "scaling-policy": name_schema,
418                     },
419                     "required": ["scaling-group-descriptor", "member-vnf-index"],
420                     "additionalProperties": False
421                 },
422             },
423             "required": ["scaleVnfType", "scaleByStepData"],  # vnfInstanceId
424             "additionalProperties": False
425         },
426         "scaleTime": time_schema,
427     },
428     "required": ["scaleType", "scaleVnfData"],
429     "additionalProperties": False
430 }
431
432
433 1 schema_version = {"type": "string", "enum": ["1.0"]}
434 1 schema_type = {"type": "string"}
435 1 vim_type = shortname_schema  # {"enum": ["openstack", "openvim", "vmware", "opennebula", "aws", "azure", "fos"]}
436
437 1 vim_account_edit_schema = {
438     "title": "vim_account edit input schema",
439     "$schema": "http://json-schema.org/draft-04/schema#",
440     "type": "object",
441     "properties": {
442         "name": name_schema,
443         "description": description_schema,
444         "vim": name_schema,
445         "datacenter": name_schema,
446         "vim_type": vim_type,
447         "vim_url": description_schema,
448         # "vim_url_admin": description_schema,
449         # "vim_tenant": name_schema,
450         "vim_tenant_name": name_schema,
451         "vim_user": string_schema,
452         "vim_password": passwd_schema,
453         "config": {"type": "object"}
454     },
455     "additionalProperties": False
456 }
457
458 1 vim_account_new_schema = {
459     "title": "vim_account creation input schema",
460     "$schema": "http://json-schema.org/draft-04/schema#",
461     "type": "object",
462     "properties": {
463         "schema_version": schema_version,
464         "schema_type": schema_type,
465         "name": name_schema,
466         "description": description_schema,
467         "vim": name_schema,
468         "datacenter": name_schema,
469         "vim_type": vim_type,
470         "vim_url": description_schema,
471         # "vim_url_admin": description_schema,
472         # "vim_tenant": name_schema,
473         "vim_tenant_name": name_schema,
474         "vim_user": string_schema,
475         "vim_password": passwd_schema,
476         "config": {"type": "object"}
477     },
478     "required": ["name", "vim_url", "vim_type", "vim_user", "vim_password", "vim_tenant_name"],
479     "additionalProperties": False
480 }
481
482 1 wim_type = shortname_schema  # {"enum": ["ietfl2vpn", "onos", "odl", "dynpac", "fake"]}
483
484 1 wim_account_edit_schema = {
485     "title": "wim_account edit input schema",
486     "$schema": "http://json-schema.org/draft-04/schema#",
487     "type": "object",
488     "properties": {
489         "name": name_schema,
490         "description": description_schema,
491         "wim": name_schema,
492         "wim_type": wim_type,
493         "wim_url": description_schema,
494         "user": string_schema,
495         "password": passwd_schema,
496         "config": {"type": "object"}
497     },
498     "additionalProperties": False
499 }
500
501 1 wim_account_new_schema = {
502     "title": "wim_account creation input schema",
503     "$schema": "http://json-schema.org/draft-04/schema#",
504     "type": "object",
505     "properties": {
506         "schema_version": schema_version,
507         "schema_type": schema_type,
508         "name": name_schema,
509         "description": description_schema,
510         "wim": name_schema,
511         "wim_type": wim_type,
512         "wim_url": description_schema,
513         "user": string_schema,
514         "password": passwd_schema,
515         "config": {
516             "type": "object",
517             "patternProperties": {
518                 ".": {"not": {"type": "null"}}
519             }
520         }
521     },
522     "required": ["name", "wim_url", "wim_type"],
523     "additionalProperties": False
524 }
525
526 1 sdn_properties = {
527     "name": name_schema,
528     "type": {"type": "string"},
529     "url": {"type": "string"},
530     "user": string_schema,
531     "password": passwd_schema,
532     "config": {"type": "object"},
533     "description": description_schema,
534     # The folowing are deprecated. Maintanied for backward compatibility
535     "dpid": dpid_Schema,
536     "ip": ip_schema,
537     "port": port_schema,
538     "version": {"type": "string", "minLength": 1, "maxLength": 12},
539 }
540 1 sdn_new_schema = {
541     "title": "sdn controller information schema",
542     "$schema": "http://json-schema.org/draft-04/schema#",
543     "type": "object",
544     "properties": sdn_properties,
545     "required": ["name", 'type'],
546     "additionalProperties": False
547 }
548 1 sdn_edit_schema = {
549     "title": "sdn controller update information schema",
550     "$schema": "http://json-schema.org/draft-04/schema#",
551     "type": "object",
552     "properties": sdn_properties,
553     # "required": ["name", "port", 'ip', 'dpid', 'type'],
554     "additionalProperties": False
555 }
556 1 sdn_port_mapping_schema = {
557     "$schema": "http://json-schema.org/draft-04/schema#",
558     "title": "sdn port mapping information schema",
559     "type": "array",
560     "items": {
561         "type": "object",
562         "properties": {
563             "compute_node": shortname_schema,
564             "ports": {
565                 "type": "array",
566                 "items": {
567                     "type": "object",
568                     "properties": {
569                         "pci": pci_extended_schema,
570                         "switch_port": shortname_schema,
571                         "switch_mac": mac_schema
572                     },
573                     "required": ["pci"]
574                 }
575             }
576         },
577         "required": ["compute_node", "ports"]
578     }
579 }
580 1 sdn_external_port_schema = {
581     "$schema": "http://json-schema.org/draft-04/schema#",
582     "title": "External port information",
583     "type": "object",
584     "properties": {
585         "port": {"type": "string", "minLength": 1, "maxLength": 60},
586         "vlan": vlan_schema,
587         "mac": mac_schema
588     },
589     "required": ["port"]
590 }
591
592 # K8s Clusters
593 1 k8scluster_nets_schema = {
594     "title": "k8scluster nets input schema",
595     "$schema": "http://json-schema.org/draft-04/schema#",
596     "type": "object",
597     "patternProperties": {".": {"oneOf": [name_schema, null_schema]}},
598     "minProperties": 1,
599     "additionalProperties": False
600 }
601 1 k8scluster_new_schema = {
602     "title": "k8scluster creation input schema",
603     "$schema": "http://json-schema.org/draft-04/schema#",
604     "type": "object",
605     "properties": {
606         "schema_version": schema_version,
607         "schema_type": schema_type,
608         "name": name_schema,
609         "description": description_schema,
610         "credentials": object_schema,
611         "vim_account": id_schema,
612         "k8s_version": string_schema,
613         "nets": k8scluster_nets_schema,
614         "namespace": name_schema,
615         "cni": nameshort_list_schema,
616     },
617     "required": ["name", "credentials", "vim_account", "k8s_version", "nets"],
618     "additionalProperties": False
619 }
620 1 k8scluster_edit_schema = {
621     "title": "vim_account edit input schema",
622     "$schema": "http://json-schema.org/draft-04/schema#",
623     "type": "object",
624     "properties": {
625         "name": name_schema,
626         "description": description_schema,
627         "credentials": object_schema,
628         "vim_account": id_schema,
629         "k8s_version": string_schema,
630         "nets": k8scluster_nets_schema,
631         "namespace": name_schema,
632         "cni": nameshort_list_schema,
633     },
634     "additionalProperties": False
635 }
636
637 # K8s Repos
638 1 k8srepo_types = {"enum": ["helm-chart", "juju-bundle"]}
639 1 k8srepo_properties = {
640     "name": name_schema,
641     "description": description_schema,
642     "type": k8srepo_types,
643     "url": description_schema,
644 }
645 1 k8srepo_new_schema = {
646     "title": "k8scluster creation input schema",
647     "$schema": "http://json-schema.org/draft-04/schema#",
648     "type": "object",
649     "properties": k8srepo_properties,
650     "required": ["name", "type", "url"],
651     "additionalProperties": False
652 }
653 1 k8srepo_edit_schema = {
654     "title": "vim_account edit input schema",
655     "$schema": "http://json-schema.org/draft-04/schema#",
656     "type": "object",
657     "properties": k8srepo_properties,
658     "additionalProperties": False
659 }
660
661 # OSM Repos
662 1 osmrepo_types = {"enum": ["osm"]}
663 1 osmrepo_properties = {
664     "name": name_schema,
665     "description": description_schema,
666     "type": osmrepo_types,
667     "url": description_schema
668     # "user": string_schema,
669     # "password": passwd_schema
670 }
671 1 osmrepo_new_schema = {
672     "title": "osm repo creation input schema",
673     "$schema": "http://json-schema.org/draft-04/schema#",
674     "type": "object",
675     "properties": osmrepo_properties,
676     "required": ["name", "type", "url"],
677     "additionalProperties": False
678 }
679 1 osmrepo_edit_schema = {
680     "title": "osm repo edit input schema",
681     "$schema": "http://json-schema.org/draft-04/schema#",
682     "type": "object",
683     "properties": osmrepo_properties,
684     "additionalProperties": False
685 }
686
687 # PDUs
688 1 pdu_interface = {
689     "type": "object",
690     "properties": {
691         "name": shortname_schema,
692         "mgmt": bool_schema,
693         "type": {"enum": ["overlay", 'underlay']},
694         "ip-address": ip_schema,
695         # TODO, add user, password, ssh-key
696         "mac-address": mac_schema,
697         "vim-network-name": shortname_schema,  # interface is connected to one vim network, or switch port
698         "vim-network-id": shortname_schema,
699         # # provide this in case SDN assist must deal with this interface
700         # "switch-dpid": dpid_Schema,
701         # "switch-port": shortname_schema,
702         # "switch-mac": shortname_schema,
703         # "switch-vlan": vlan_schema,
704     },
705     "required": ["name", "mgmt", "ip-address"],
706     "additionalProperties": False
707 }
708 1 pdu_new_schema = {
709     "title": "pdu creation input schema",
710     "$schema": "http://json-schema.org/draft-04/schema#",
711     "type": "object",
712     "properties": {
713         "name": shortname_schema,
714         "type": shortname_schema,
715         "description": description_schema,
716         "shared": bool_schema,
717         "vims": nameshort_list_schema,
718         "vim_accounts": nameshort_list_schema,
719         "interfaces": {
720             "type": "array",
721             "items": pdu_interface,
722             "minItems": 1
723         }
724     },
725     "required": ["name", "type", "interfaces"],
726     "additionalProperties": False
727 }
728 1 pdu_edit_schema = {
729     "title": "pdu edit input schema",
730     "$schema": "http://json-schema.org/draft-04/schema#",
731     "type": "object",
732     "properties": {
733         "name": shortname_schema,
734         "type": shortname_schema,
735         "description": description_schema,
736         "shared": bool_schema,
737         "vims": {"oneOf": [array_edition_schema, nameshort_list_schema]},
738         "vim_accounts": {"oneOf": [array_edition_schema, nameshort_list_schema]},
739         "interfaces": {"oneOf": [
740             array_edition_schema,
741             {
742                 "type": "array",
743                 "items": pdu_interface,
744                 "minItems": 1
745             }
746         ]}
747     },
748     "additionalProperties": False,
749     "minProperties": 1
750 }
751
752 # VNF PKG OPERATIONS
753 1 vnfpkgop_new_schema = {
754     "title": "VNF PKG operation creation input schema",
755     "$schema": "http://json-schema.org/draft-04/schema#",
756     "type": "object",
757     "properties": {
758         "lcmOperationType": string_schema,
759         "vnfPkgId": id_schema,
760         "kdu_name": name_schema,
761         "primitive": name_schema,
762         "primitive_params": {"type": "object"},
763     },
764     "required": ["lcmOperationType", "vnfPkgId", "kdu_name", "primitive", "primitive_params"],
765     "additionalProperties": False
766 }
767
768 # USERS
769 1 project_role_mappings = {
770     "title": "list pf projects/roles",
771     "$schema": "http://json-schema.org/draft-04/schema#",
772     "type": "array",
773     "items": {
774         "type": "object",
775         "properties": {
776             "project": shortname_schema,
777             "role": shortname_schema
778         },
779         "required": ["project", "role"],
780         "additionalProperties": False
781     },
782     "minItems": 1
783 }
784 1 project_role_mappings_optional = {
785     "title": "list of projects/roles or projects only",
786     "$schema": "http://json-schema.org/draft-04/schema#",
787     "type": "array",
788     "items": {
789         "type": "object",
790         "properties": {
791             "project": shortname_schema,
792             "role": shortname_schema
793         },
794         "required": ["project"],
795         "additionalProperties": False
796     },
797     "minItems": 1
798 }
799 1 user_new_schema = {
800     "$schema": "http://json-schema.org/draft-04/schema#",
801     "title": "New user schema",
802     "type": "object",
803     "properties": {
804         "username": string_schema,
805         "domain_name": shortname_schema,
806         "password": passwd_schema,
807         "projects": nameshort_list_schema,
808         "project_role_mappings": project_role_mappings,
809     },
810     "required": ["username", "password"],
811     "additionalProperties": False
812 }
813 1 user_edit_schema = {
814     "$schema": "http://json-schema.org/draft-04/schema#",
815     "title": "User edit schema for administrators",
816     "type": "object",
817     "properties": {
818         "password": passwd_schema,
819         "username": string_schema,     # To allow User Name modification
820         "projects": {
821             "oneOf": [
822                 nameshort_list_schema,
823                 array_edition_schema
824             ]
825         },
826         "project_role_mappings": project_role_mappings,
827         "add_project_role_mappings": project_role_mappings,
828         "remove_project_role_mappings": project_role_mappings_optional,
829     },
830     "minProperties": 1,
831     "additionalProperties": False
832 }
833
834 # PROJECTS
835 1 topics_with_quota = ["vnfds", "nsds", "slice_templates", "pduds", "ns_instances", "slice_instances", "vim_accounts",
836                      "wim_accounts", "sdn_controllers", "k8sclusters", "k8srepos", "osmrepos", "ns_subscriptions"]
837 1 project_new_schema = {
838     "$schema": "http://json-schema.org/draft-04/schema#",
839     "title": "New project schema for administrators",
840     "type": "object",
841     "properties": {
842         "name": shortname_schema,
843         "admin": bool_schema,
844         "domain_name": shortname_schema,
845         "quotas": {
846             "type": "object",
847             "properties": {topic: integer0_schema for topic in topics_with_quota},
848             "additionalProperties": False
849         },
850     },
851     "required": ["name"],
852     "additionalProperties": False
853 }
854 1 project_edit_schema = {
855     "$schema": "http://json-schema.org/draft-04/schema#",
856     "title": "Project edit schema for administrators",
857     "type": "object",
858     "properties": {
859         "admin": bool_schema,
860         "name": shortname_schema,     # To allow Project Name modification
861         "quotas": {
862             "type": "object",
863             "properties": {topic: {"oneOf": [integer0_schema, null_schema]} for topic in topics_with_quota},
864             "additionalProperties": False
865         },
866     },
867     "additionalProperties": False,
868     "minProperties": 1
869 }
870
871 # ROLES
872 1 roles_new_schema = {
873     "$schema": "http://json-schema.org/draft-04/schema#",
874     "title": "New role schema for administrators",
875     "type": "object",
876     "properties": {
877         "name": shortname_schema,
878         "permissions": {
879             "type": "object",
880             "patternProperties": {
881                 ".": bool_schema,
882             },
883             # "minProperties": 1,
884         }
885     },
886     "required": ["name"],
887     "additionalProperties": False
888 }
889 1 roles_edit_schema = {
890     "$schema": "http://json-schema.org/draft-04/schema#",
891     "title": "Roles edit schema for administrators",
892     "type": "object",
893     "properties": {
894         "name": shortname_schema,
895         "permissions": {
896             "type": "object",
897             "patternProperties": {
898                 ".": {
899                     "oneOf": [bool_schema, null_schema]
900                 }
901             },
902             # "minProperties": 1,
903         }
904     },
905     "additionalProperties": False,
906     "minProperties": 1
907 }
908
909 # GLOBAL SCHEMAS
910
911 1 nbi_new_input_schemas = {
912     "users": user_new_schema,
913     "projects": project_new_schema,
914     "vim_accounts": vim_account_new_schema,
915     "sdns": sdn_new_schema,
916     "ns_instantiate": ns_instantiate,
917     "ns_action": ns_action,
918     "ns_scale": ns_scale,
919     "pdus": pdu_new_schema,
920 }
921
922 1 nbi_edit_input_schemas = {
923     "users": user_edit_schema,
924     "projects": project_edit_schema,
925     "vim_accounts": vim_account_edit_schema,
926     "sdns": sdn_edit_schema,
927     "pdus": pdu_edit_schema,
928 }
929
930 # NETSLICE SCHEMAS
931 1 nsi_subnet_instantiate = deepcopy(ns_instantiate)
932 1 nsi_subnet_instantiate["title"] = "netslice subnet instantiation params input schema"
933 1 nsi_subnet_instantiate["properties"]["id"] = name_schema
934 1 del nsi_subnet_instantiate["required"]
935
936 1 nsi_vld_instantiate = {
937     "title": "netslice vld instantiation params input schema",
938     "$schema": "http://json-schema.org/draft-04/schema#",
939     "type": "object",
940     "properties": {
941         "name": string_schema,
942         "vim-network-name": {"oneOf": [string_schema, object_schema]},
943         "vim-network-id": {"oneOf": [string_schema, object_schema]},
944         "ip-profile": object_schema,
945     },
946     "required": ["name"],
947     "additionalProperties": False
948 }
949
950 1 nsi_instantiate = {
951     "title": "netslice action instantiate input schema",
952     "$schema": "http://json-schema.org/draft-04/schema#",
953     "type": "object",
954     "properties": {
955         "lcmOperationType": string_schema,
956         "netsliceInstanceId": id_schema,
957         "nsiName": name_schema,
958         "nsiDescription": {"oneOf": [description_schema, null_schema]},
959         "nstId": string_schema,
960         "vimAccountId": id_schema,
961         "timeout_nsi_deploy": integer1_schema,
962         "ssh_keys": {"type": "array", "items": {"type": "string"}},
963         "nsi_id": id_schema,
964         "additionalParamsForNsi": object_schema,
965         "netslice-subnet": {
966             "type": "array",
967             "minItems": 1,
968             "items": nsi_subnet_instantiate
969         },
970         "netslice-vld": {
971             "type": "array",
972             "minItems": 1,
973             "items": nsi_vld_instantiate
974         },
975     },
976     "required": ["nsiName", "nstId", "vimAccountId"],
977     "additionalProperties": False
978 }
979
980 1 nsi_action = {
981
982 }
983
984 1 nsi_terminate = {
985
986 }
987
988 1 nsinstancesubscriptionfilter_schema = {
989     "title": "instance identifier schema",
990     "$schema": "http://json-schema.org/draft-07/schema#",
991     "type": "object",
992     "properties": {
993         "nsdIds": {"type": "array"},
994         "vnfdIds": {"type": "array"},
995         "pnfdIds": {"type": "array"},
996         "nsInstanceIds": {"type": "array"},
997         "nsInstanceNames": {"type": "array"},
998     },
999 }
1000
1001 1 nslcmsub_schema = {
1002     "title": "nslcmsubscription input schema",
1003     "$schema": "http://json-schema.org/draft-07/schema#",
1004     "type": "object",
1005     "properties": {
1006         "nsInstanceSubscriptionFilter": nsinstancesubscriptionfilter_schema,
1007         "notificationTypes": {
1008             "type": "array",
1009             "items": {
1010                 "enum": ['NsLcmOperationOccurrenceNotification', 'NsChangeNotification',
1011                          'NsIdentifierCreationNotification', 'NsIdentifierDeletionNotification']
1012             }
1013         },
1014         "operationTypes": {
1015             "type": "array",
1016             "items": {
1017                 "enum": ['INSTANTIATE', 'SCALE', 'TERMINATE', 'UPDATE', 'HEAL']
1018             }
1019         },
1020         "operationStates": {
1021             "type": "array",
1022             "items": {
1023                 "enum": ['PROCESSING', 'COMPLETED', 'PARTIALLY_COMPLETED', 'FAILED',
1024                          'FAILED_TEMP', 'ROLLING_BACK', 'ROLLED_BACK']
1025             }
1026         },
1027         "nsComponentTypes": {
1028             "type": "array",
1029             "items": {
1030                 "enum": ['VNF', 'NS', 'PNF']
1031             }
1032         },
1033         "lcmOpNameImpactingNsComponent": {
1034             "type": "array",
1035             "items": {
1036                 "enum": ['VNF_INSTANTIATE', 'VNF_SCALE', 'VNF_SCALE_TO_LEVEL', 'VNF_CHANGE_FLAVOUR',
1037                          'VNF_TERMINATE', 'VNF_HEAL', 'VNF_OPERATE', 'VNF_CHANGE_EXT_CONN', 'VNF_MODIFY_INFO',
1038                          'NS_INSTANTIATE', 'NS_SCALE', 'NS_UPDATE', 'NS_TERMINATE', 'NS_HEAL']
1039             }
1040         },
1041         "lcmOpOccStatusImpactingNsComponent": {
1042             "type": "array",
1043             "items": {
1044                 "enum": ['START', 'COMPLETED', 'PARTIALLY_COMPLETED', 'FAILED', 'ROLLED_BACK']
1045             }
1046         },
1047     },
1048     "allOf": [
1049         {
1050             "if": {
1051                 "properties": {
1052                     "notificationTypes": {
1053                         "contains": {"const": "NsLcmOperationOccurrenceNotification"}
1054                     }
1055                 },
1056             },
1057             "then": {
1058                 "anyOf": [
1059                     {"required": ["operationTypes"]},
1060                     {"required": ["operationStates"]},
1061                 ]
1062             } 
1063         },
1064         {
1065             "if": {
1066                 "properties": {
1067                     "notificationTypes": {
1068                         "contains": {"const": "NsChangeNotification"}
1069                     }
1070                 },
1071             },
1072             "then": {
1073                 "anyOf": [
1074                     {"required": ["nsComponentTypes"]},
1075                     {"required": ["lcmOpNameImpactingNsComponent"]},
1076                     {"required": ["lcmOpOccStatusImpactingNsComponent"]},
1077                 ]
1078             }
1079         }
1080     ]
1081 }
1082
1083 1 authentication_schema = {
1084     "title": "authentication schema for subscription",
1085     "$schema": "http://json-schema.org/draft-07/schema#",
1086     "type": "object",
1087     "properties": {
1088         "authType": {"enum": ["basic"]},
1089         "paramsBasic": {
1090             "type": "object",
1091             "properties": {
1092                 "userName": string_schema,
1093                 "password": passwd_schema,
1094             },
1095         },
1096     },
1097 }
1098
1099 1 subscription = {
1100     "title": "subscription input schema",
1101     "$schema": "http://json-schema.org/draft-07/schema#",
1102     "type": "object",
1103     "properties": {
1104         "filter": nslcmsub_schema,
1105         "CallbackUri": description_schema,
1106         "authentication": authentication_schema
1107     },
1108     "required": ["CallbackUri"],
1109 }
1110
1111
1112 1 class ValidationError(Exception):
1113 1     def __init__(self, message, http_code=HTTPStatus.UNPROCESSABLE_ENTITY):
1114 1         self.http_code = http_code
1115 1         Exception.__init__(self, message)
1116
1117
1118 1 def validate_input(indata, schema_to_use):
1119     """
1120     Validates input data against json schema
1121     :param indata: user input data. Should be a dictionary
1122     :param schema_to_use: jsonschema to test
1123     :return: None if ok, raises ValidationError exception on error
1124     """
1125 1     try:
1126 1         if schema_to_use:
1127 1             js_v(indata, schema_to_use)
1128 1         return None
1129 1     except js_e.ValidationError as e:
1130 1         if e.path:
1131 1             error_pos = "at '" + ":".join(map(str, e.path)) + "'"
1132         else:
1133 1             error_pos = ""
1134 1         raise ValidationError("Format error {} '{}' ".format(error_pos, e.message))
1135 0     except js_e.SchemaError:
1136 0         raise ValidationError("Bad json schema {}".format(schema_to_use), http_code=HTTPStatus.INTERNAL_SERVER_ERROR)
1137
1138
1139 1 def is_valid_uuid(x):
1140     """
1141     Test for a valid UUID
1142     :param x: string to test
1143     :return: True if x is a valid uuid, False otherwise
1144     """
1145 1     try:
1146 1         if UUID(x):
1147 1             return True
1148 1     except (TypeError, ValueError, AttributeError):
1149 1         return False