From cb83c941ebdf6a8807ffe3b1c3346c61e085b0bf Mon Sep 17 00:00:00 2001 From: tierno Date: Mon, 24 Sep 2018 17:28:13 +0200 Subject: [PATCH] feature 1417: Add pdu CRUD Change-Id: Ia1d34bd05e34129acca89f1dee97f2bbe52036c1 Signed-off-by: tierno --- osm_nbi/engine.py | 42 ++++++++++++----- osm_nbi/html_public/version | 5 +- osm_nbi/nbi.py | 12 +++++ osm_nbi/validation.py | 93 ++++++++++++++++++++++++++++++++----- 4 files changed, 126 insertions(+), 26 deletions(-) diff --git a/osm_nbi/engine.py b/osm_nbi/engine.py index 53bf219..6df84c8 100644 --- a/osm_nbi/engine.py +++ b/osm_nbi/engine.py @@ -29,15 +29,15 @@ class EngineException(Exception): Exception.__init__(self, message) -def get_iterable(input): +def get_iterable(input_var): """ - Returns an iterable, in case input is None it just returns an empty tuple - :param input: - :return: iterable + Returns an iterable, in case input_var is None it just returns an empty tuple + :param input_var: can be a list, tuple or None + :return: input_var or () if it is None """ - if input is None: + if input_var is None: return () - return input + return input_var class Engine(object): @@ -137,8 +137,7 @@ class Engine(object): def _check_project_dependencies(self, project_id): """ Check if a project can be deleted - :param session: - :param _id: + :param project_id: :return: """ # TODO Is it needed to check descriptors _admin.project_read/project_write?? @@ -146,6 +145,17 @@ class Engine(object): if self.db.get_list("users", _filter): raise EngineException("There are users that uses this project", http_code=HTTPStatus.CONFLICT) + def _check_pdus_usage(self, pdu_id): + """ + Check if a pdu can be deleted + :param pdu_id: + :return: + """ + # TODO Is it needed to check descriptors _admin.project_read/project_write?? + _filter = {"vdur.pdu-id": pdu_id} + if self.db.get_list("vnfrs", _filter): + raise EngineException("There are ns that uses this pdu", http_code=HTTPStatus.CONFLICT) + def _check_dependencies_on_descriptor(self, session, item, descriptor_id, _id): """ Check that the descriptor to be deleded is not a dependency of others @@ -380,12 +390,12 @@ class Engine(object): else: if not indata.get("_id"): indata["_id"] = str(uuid4()) - if item in ("vnfds", "nsds", "nsrs", "vnfrs"): + if item in ("vnfds", "nsds", "nsrs", "vnfrs", "pdus"): if not indata["_admin"].get("projects_read"): indata["_admin"]["projects_read"] = [session["project_id"]] if not indata["_admin"].get("projects_write"): indata["_admin"]["projects_write"] = [session["project_id"]] - if item in ("vnfds", "nsds"): + if item in ("vnfds", "nsds", "pdus"): indata["_admin"]["onboardingState"] = "CREATED" indata["_admin"]["operationalState"] = "DISABLED" indata["_admin"]["usageSate"] = "NOT_IN_USE" @@ -642,6 +652,8 @@ class Engine(object): "internal-connection-point": [], "interfaces": [], } + if vnfd.get("pdu-type"): + vdur["pdu-type"] = vnfd["pdu-type"] # TODO volumes: name, volume-id for icp in vdu.get("internal-connection-point", ()): vdu_icp = { @@ -833,7 +845,7 @@ class Engine(object): return filter if item == "users": filter["username"] = session["username"] - elif item in ("vnfds", "nsds", "nsrs", "vnfrs"): + elif item in ("vnfds", "nsds", "nsrs", "vnfrs", "pdus"): filter["_admin.projects_read.cont"] = ["ANY", session["project_id"]] def _add_delete_filter(self, session, item, filter): @@ -845,7 +857,7 @@ class Engine(object): elif item == "project": if filter.get("_id") == session["project_id"]: raise EngineException("You cannot delete your own project", http_code=HTTPStatus.CONFLICT) - elif item in ("vnfds", "nsds") and not session["admin"]: + elif item in ("vnfds", "nsds", "pdus") and not session["admin"]: filter["_admin.projects_write.cont"] = ["ANY", session["project_id"]] def get_file(self, session, item, _id, path=None, accept_header=None): @@ -965,6 +977,9 @@ class Engine(object): elif item == "projects": if not force: self._check_project_dependencies(_id) + elif item == "pdus": + if not force: + self._check_pdus_usage(_id) if item == "nsrs": nsr = self.db.get_one(item, filter) @@ -975,6 +990,9 @@ class Engine(object): v = self.db.del_one(item, {"_id": _id}) self.db.del_list("nslcmops", {"nsInstanceId": _id}) self.db.del_list("vnfrs", {"nsr-id-ref": _id}) + # set all used pdus as free + self.db.set_list("pdus", {"_admin.usage.nsr_id": _id}, + {"_admin.usageSate": "NOT_IN_USE", "_admin.usage": None}) self.msg.write("ns", "deleted", {"_id": _id}) return v if item in ("vim_accounts", "sdns") and not force: diff --git a/osm_nbi/html_public/version b/osm_nbi/html_public/version index 85cfc0d..c9d0d9b 100644 --- a/osm_nbi/html_public/version +++ b/osm_nbi/html_public/version @@ -1,3 +1,2 @@ -0.1.19 -2018-10-04 - +0.1.20 +2018-10-08 diff --git a/osm_nbi/nbi.py b/osm_nbi/nbi.py index fa2f043..0a4c402 100644 --- a/osm_nbi/nbi.py +++ b/osm_nbi/nbi.py @@ -75,6 +75,9 @@ URL: /osm GET POST / O /subscriptions 5 5 / 5 X + /pdu/v1 + /pdu_descriptor O O + / O O O O /admin/v1 /tokens O O / O O @@ -172,6 +175,13 @@ class Server(object): }, } }, + "pdu": { + "v1": { + "pdu_descriptors": {"METHODS": ("GET", "POST"), + "": {"METHODS": ("GET", "POST", "DELETE", "PATCH", "PUT")} + }, + } + }, "nsd": { "v1": { "ns_descriptors_content": {"METHODS": ("GET", "POST"), @@ -624,6 +634,8 @@ class Server(object): engine_item = "nslcmops" if item == "vnfrs" or item == "vnf_instances": engine_item = "vnfrs" + elif topic == "pdu": + engine_item = "pdus" if engine_item == "vims": # TODO this is for backward compatibility, it will remove in the future engine_item = "vim_accounts" diff --git a/osm_nbi/validation.py b/osm_nbi/validation.py index 4ffd0b7..2eb7034 100644 --- a/osm_nbi/validation.py +++ b/osm_nbi/validation.py @@ -35,6 +35,7 @@ vlan_schema = {"type": "integer", "minimum": 1, "maximum": 4095} vlan1000_schema = {"type": "integer", "minimum": 1000, "maximum": 4095} mac_schema = {"type": "string", "pattern": "^[0-9a-fA-F][02468aceACE](:[0-9a-fA-F]{2}){5}$"} # must be unicast: LSB bit of MSB byte ==0 +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]?)$"} @@ -56,6 +57,11 @@ array_edition_schema = { "additionalProperties": False, "minProperties": 1, } +nameshort_list_schema = { + "type": "array", + "minItems": 1, + "items": nameshort_schema, +} ns_instantiate_vdu = { @@ -344,7 +350,7 @@ vim_account_new_schema = { sdn_properties = { "name": name_schema, "description": description_schema, - "dpid": {"type": "string", "pattern": "^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){7}$"}, + "dpid": dpid_Schema, "ip": ip_schema, "port": port_schema, "type": {"type": "string", "enum": ["opendaylight", "floodlight", "onos"]}, @@ -404,12 +410,73 @@ sdn_external_port_schema = { "required": ["port"] } -# USERS -user_project_schema = { - "type": "array", - "minItems": 1, - "items": nameshort_schema, +# PDUs +pdu_interface = { + "type": "object", + "properties": { + "name": nameshort_schema, + "mgmt": bool_schema, + "type": {"enum": ["overlay", 'underlay']}, + "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, + }, + "required": ["name", "mgmt", "ip_address"], + "additionalProperties": False } +pdu_new_schema = { + "title": "pdu creation input schema", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "name": nameshort_schema, + "type": nameshort_schema, + "description": description_schema, + "shared": bool_schema, + "vims": nameshort_list_schema, + "vim_accounts": nameshort_list_schema, + "interfaces": { + "type": "array", + "items": {"type": pdu_interface}, + "minItems": 1 + } + }, + "required": ["name", "type", "interfaces"], + "additionalProperties": False +} + +pdu_edit_schema = { + "title": "pdu edit input schema", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "name": nameshort_schema, + "type": nameshort_schema, + "description": description_schema, + "shared": bool_schema, + "vims": {"oneOff": [array_edition_schema, nameshort_list_schema]}, + "vim_accounts": {"oneOff": [array_edition_schema, nameshort_list_schema]}, + "interfaces": {"oneOff": [ + array_edition_schema, + { + "type": "array", + "items": {"type": pdu_interface}, + "minItems": 1 + } + ]} + }, + "additionalProperties": False, + "minProperties": 1 +} + +# USERS user_new_schema = { "$schema": "http://json-schema.org/draft-04/schema#", "title": "New user schema", @@ -417,7 +484,7 @@ user_new_schema = { "properties": { "username": nameshort_schema, "password": passwd_schema, - "projects": user_project_schema, + "projects": nameshort_list_schema, }, "required": ["username", "password", "projects"], "additionalProperties": False @@ -430,11 +497,13 @@ user_edit_schema = { "password": passwd_schema, "projects": { "oneOff": [ - user_project_schema, + nameshort_list_schema, array_edition_schema ] }, - } + }, + "minProperties": 1, + "additionalProperties": False } # PROJECTS @@ -469,14 +538,16 @@ nbi_new_input_schemas = { "sdns": sdn_new_schema, "ns_instantiate": ns_instantiate, "ns_action": ns_action, - "ns_scale": ns_scale + "ns_scale": ns_scale, + "pdus": pdu_new_schema, } nbi_edit_input_schemas = { "users": user_edit_schema, "projects": project_edit_schema, "vim_accounts": vim_account_edit_schema, - "sdns": sdn_edit_schema + "sdns": sdn_edit_schema, + "pdus": pdu_edit_schema, } -- 2.25.1