X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FNBI.git;a=blobdiff_plain;f=osm_nbi%2Fvalidation.py;h=f81f45ca1ad5d934ab14346801ab28154dbf6f27;hp=2eb703448d17f27db5fe63cc7194a78e2d0f6e84;hb=36ec86019fa668dddbbe0cf9d9ec53b9ea6569cf;hpb=cb83c941ebdf6a8807ffe3b1c3346c61e085b0bf;ds=sidebyside diff --git a/osm_nbi/validation.py b/osm_nbi/validation.py index 2eb7034..f81f45c 100644 --- a/osm_nbi/validation.py +++ b/osm_nbi/validation.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from jsonschema import validate as js_v, exceptions as js_e +from http import HTTPStatus __author__ = "Alfonso Tierno " __version__ = "0.1" @@ -12,7 +13,7 @@ Validator of input data using JSON schemas for those items that not contains an # Basis schemas patern_name = "^[ -~]+$" -nameshort_schema = {"type": "string", "minLength": 1, "maxLength": 60, "pattern": "^[^,;()\.\$'\"]+$"} +nameshort_schema = {"type": "string", "minLength": 1, "maxLength": 60, "pattern": "^[^,;()\\.\\$'\"]+$"} passwd_schema = {"type": "string", "minLength": 1, "maxLength": 60} name_schema = {"type": "string", "minLength": 1, "maxLength": 255, "pattern": "^[^,;()'\"]+$"} string_schema = {"type": "string", "minLength": 1, "maxLength": 255} @@ -24,13 +25,15 @@ null_schema = {"type": "null"} # "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}$" id_schema = {"type": "string", "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"} time_schema = {"type": "string", "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]([0-5]:){2}"} -pci_schema = {"type": "string", "pattern": "^[0-9a-fA-F]{4}(:[0-9a-fA-F]{2}){2}\.[0-9a-fA-F]$"} +pci_schema = {"type": "string", "pattern": "^[0-9a-fA-F]{4}(:[0-9a-fA-F]{2}){2}\\.[0-9a-fA-F]$"} +# allows [] for wildcards. For that reason huge length limit is set +pci_extended_schema = {"type": "string", "pattern": "^[0-9a-fA-F.:-\\[\\]]{12,40}$"} http_schema = {"type": "string", "pattern": "^https?://[^'\"=]+$"} bandwidth_schema = {"type": "string", "pattern": "^[0-9]+ *([MG]bps)?$"} memory_schema = {"type": "string", "pattern": "^[0-9]+ *([MG]i?[Bb])?$"} integer0_schema = {"type": "integer", "minimum": 0} integer1_schema = {"type": "integer", "minimum": 1} -path_schema = {"type": "string", "pattern": "^(\.){0,2}(/[^/\"':{}\(\)]+)+$"} +path_schema = {"type": "string", "pattern": "^(\\.){0,2}(/[^/\"':{}\\(\\)]+)+$"} vlan_schema = {"type": "integer", "minimum": 1, "maximum": 4095} vlan1000_schema = {"type": "integer", "minimum": 1000, "maximum": 4095} mac_schema = {"type": "string", @@ -38,9 +41,9 @@ mac_schema = {"type": "string", dpid_Schema = {"type": "string", "pattern": "^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){7}$"} # mac_schema={"type":"string", "pattern":"^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$"} ip_schema = {"type": "string", - "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]?)$"} + "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]?)$"} ip_prefix_schema = {"type": "string", - "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}" + "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]?)/(30|[12]?[0-9])$"} port_schema = {"type": "integer", "minimum": 1, "maximum": 65534} object_schema = {"type": "object"} @@ -52,7 +55,7 @@ size_schema = {"type": "integer", "minimum": 1, "maximum": 100} array_edition_schema = { "type": "object", "patternProperties": { - "^\$": "Any" + "^\\$": "Any" }, "additionalProperties": False, "minProperties": 1, @@ -188,12 +191,15 @@ ns_instantiate = { "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { + "lcmOperationType": string_schema, + "nsInstanceId": id_schema, "nsName": name_schema, "nsDescription": {"oneOf": [description_schema, {"type": "null"}]}, "nsdId": id_schema, "vimAccountId": id_schema, - "ssh_keys": {"type": "string"}, + "ssh_keys": {"type": "array", "items": {"type": "string"}}, "nsr_id": id_schema, + "vduImage": name_schema, "vnf": { "type": "array", "minItems": 1, @@ -258,6 +264,8 @@ ns_action = { # TODO for the moment it is only contemplated the vnfd primitive "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { + "lcmOperationType": string_schema, + "nsInstanceId": id_schema, "member_vnf_index": name_schema, "vnf_member_index": name_schema, # TODO for backward compatibility. To remove in future "vdu_id": name_schema, @@ -272,6 +280,8 @@ ns_scale = { # TODO for the moment it is only VDU-scaling "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { + "lcmOperationType": string_schema, + "nsInstanceId": id_schema, "scaleType": {"enum": ["SCALE_VNF"]}, "scaleVnfData": { "type": "object", @@ -387,7 +397,7 @@ sdn_port_mapping_schema = { "items": { "type": "object", "properties": { - "pci": pci_schema, + "pci": pci_extended_schema, "switch_port": nameshort_schema, "switch_mac": mac_schema }, @@ -417,18 +427,18 @@ pdu_interface = { "name": nameshort_schema, "mgmt": bool_schema, "type": {"enum": ["overlay", 'underlay']}, - "ip_address": ip_schema, + "ip-address": ip_schema, # TODO, add user, password, ssh-key - "mac_address": mac_schema, - "vim_network_name": nameshort_schema, # interface is connected to one vim network, or switch port - "vim_network_id": nameshort_schema, - # provide this in case SDN assist must deal with this interface - "switch_dpid": dpid_Schema, - "switch_port": nameshort_schema, - "switch_mac": nameshort_schema, - "switch_vlan": vlan_schema, + "mac-address": mac_schema, + "vim-network-name": nameshort_schema, # interface is connected to one vim network, or switch port + # TODO "vim-network-id": nameshort_schema, + # # provide this in case SDN assist must deal with this interface + # "switch-dpid": dpid_Schema, + # "switch-port": nameshort_schema, + # "switch-mac": nameshort_schema, + # "switch-vlan": vlan_schema, }, - "required": ["name", "mgmt", "ip_address"], + "required": ["name", "mgmt", "ip-address"], "additionalProperties": False } pdu_new_schema = { @@ -444,7 +454,7 @@ pdu_new_schema = { "vim_accounts": nameshort_list_schema, "interfaces": { "type": "array", - "items": {"type": pdu_interface}, + "items": pdu_interface, "minItems": 1 } }, @@ -467,7 +477,7 @@ pdu_edit_schema = { array_edition_schema, { "type": "array", - "items": {"type": pdu_interface}, + "items": pdu_interface, "minItems": 1 } ]} @@ -552,22 +562,19 @@ nbi_edit_input_schemas = { class ValidationError(Exception): - pass + def __init__(self, message, http_code=HTTPStatus.UNPROCESSABLE_ENTITY): + self.http_code = http_code + Exception.__init__(self, message) -def validate_input(indata, item, new=True): +def validate_input(indata, schema_to_use): """ Validates input data against json schema :param indata: user input data. Should be a dictionary - :param item: can be users, projects, vims, sdns, ns_xxxxx - :param new: True if the validation is for creating or False if it is for editing - :return: None if ok, raises ValidationError exception otherwise + :param schema_to_use: jsonschema to test + :return: None if ok, raises ValidationError exception on error """ try: - if new: - schema_to_use = nbi_new_input_schemas.get(item) - else: - schema_to_use = nbi_edit_input_schemas.get(item) if schema_to_use: js_v(indata, schema_to_use) return None @@ -577,3 +584,5 @@ def validate_input(indata, item, new=True): 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)