#!/usr/bin/python3
# -*- coding: utf-8 -*-
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
import cherrypy
import time
import json
"""
North Bound Interface (O: OSM specific; 5,X: SOL005 not implemented yet; O5: SOL005 implemented)
URL: /osm GET POST PUT DELETE PATCH
- /nsd/v1 O O
+ /nsd/v1
/ns_descriptors_content O O
/<nsdInfoId> O O O O
/ns_descriptors O5 O5
/<vnfInstanceId> O
/subscriptions 5 5
/<subscriptionId> 5 X
+
/pdu/v1
/pdu_descriptor O O
/<id> O O O O
+
/admin/v1
/tokens O O
/<id> O O
/sdns O O
/<id> O O O
+ /nst/v1 O O
+ /netslice_templates_content O O
+ /<nstInfoId> O O O O
+ /netslice_templates O O
+ /<nstInfoId> O O O
+ /nst_content O O
+ /nst O
+ /artifacts[/<artifactPath>] O
+ /subscriptions X X
+ /<subscriptionId> X X
+
+ /nsilcm/v1
+ /netslice_instances_content O O
+ /<SliceInstanceId> O O
+ /netslice_instances O O
+ /<SliceInstanceId> O O
+ instantiate O
+ terminate O
+ action O
+ /nsi_lcm_op_occs O O
+ /<nsiLcmOpOccId> O O O
+ /subscriptions X X
+ /<subscriptionId> X X
+
query string:
Follows SOL005 section 4.3.2 It contains extra METHOD to override http method, FORCE to force.
simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
},
}
},
+ "nst": {
+ "v1": {
+ "netslice_templates_content": {"METHODS": ("GET", "POST"),
+ "<ID>": {"METHODS": ("GET", "PUT", "DELETE")}
+ },
+ "netslice_templates": {"METHODS": ("GET", "POST"),
+ "<ID>": {"METHODS": ("GET", "DELETE"), "TODO": "PATCH",
+ "nst_content": {"METHODS": ("GET", "PUT")},
+ "nst": {"METHODS": "GET"}, # descriptor inside package
+ "artifacts": {"*": {"METHODS": "GET"}}
+ }
+ },
+ "subscriptions": {"TODO": ("GET", "POST"),
+ "<ID>": {"TODO": ("GET", "DELETE")}
+ },
+ }
+ },
+ "nsilcm": {
+ "v1": {
+ "netslice_instances_content": {"METHODS": ("GET", "POST"),
+ "<ID>": {"METHODS": ("GET", "DELETE")}
+ },
+ "netslice_instances": {"METHODS": ("GET", "POST"),
+ "<ID>": {"METHODS": ("GET", "DELETE"),
+ "terminate": {"METHODS": "POST"},
+ "instantiate": {"METHODS": "POST"},
+ "action": {"METHODS": "POST"},
+ }
+ },
+ "nsi_lcm_op_occs": {"METHODS": "GET",
+ "<ID>": {"METHODS": "GET"},
+ },
+ }
+ },
}
def _format_in(self, kwargs):
if not main_topic or not version or not topic:
raise NbiException("URL must contain at least 'main_topic/version/topic'",
HTTPStatus.METHOD_NOT_ALLOWED)
- if main_topic not in ("admin", "vnfpkgm", "nsd", "nslcm", "pdu"):
+ if main_topic not in ("admin", "vnfpkgm", "nsd", "nslcm", "pdu", "nst", "nsilcm"):
raise NbiException("URL main_topic '{}' not supported".format(main_topic),
HTTPStatus.METHOD_NOT_ALLOWED)
if version != 'v1':
force = kwargs.pop("FORCE")
else:
force = False
-
self._check_valid_url_method(method, main_topic, version, topic, _id, item, *args)
-
if main_topic == "admin" and topic == "tokens":
return self.token(method, _id, kwargs)
engine_topic = "nslcmops"
if topic == "vnfrs" or topic == "vnf_instances":
engine_topic = "vnfrs"
+ elif main_topic == "nst":
+ engine_topic = "nsts"
+ elif main_topic == "nsilcm":
+ engine_topic = "nsis"
+ if topic == "nsi_lcm_op_occs":
+ engine_topic = "nsilcmops"
elif main_topic == "pdu":
engine_topic = "pdus"
if engine_topic == "vims": # TODO this is for backward compatibility, it will remove in the future
engine_topic = "vim_accounts"
if method == "GET":
- if item in ("nsd_content", "package_content", "artifacts", "vnfd", "nsd"):
- if item in ("vnfd", "nsd"):
+ if item in ("nsd_content", "package_content", "artifacts", "vnfd", "nsd", "nst", "nst_content"):
+ if item in ("vnfd", "nsd", "nst"):
path = "$DESCRIPTOR"
elif args:
path = args
else:
outdata = self.engine.get_item(session, engine_topic, _id)
elif method == "POST":
- if topic in ("ns_descriptors_content", "vnf_packages_content"):
+ if topic in ("ns_descriptors_content", "vnf_packages_content", "netslice_templates_content"):
_id = cherrypy.request.headers.get("Transaction-Id")
if not _id:
_id = self.engine.new_item(rollback, session, engine_topic, {}, None, cherrypy.request.headers,
self._set_location_header(main_topic, version, "ns_lcm_op_occs", _id)
outdata = {"id": _id}
cherrypy.response.status = HTTPStatus.ACCEPTED.value
+ elif topic == "netslice_instances_content":
+ # creates NetSlice_Instance_record (NSIR)
+ _id = self.engine.new_item(rollback, session, engine_topic, indata, kwargs, force=force)
+ self._set_location_header(main_topic, version, topic, _id)
+ indata["lcmOperationType"] = "instantiate"
+ indata["nsiInstanceId"] = _id
+ self.engine.new_item(rollback, session, "nsilcmops", indata, kwargs)
+ outdata = {"id": _id}
+
+ elif topic == "netslice_instances" and item:
+ indata["lcmOperationType"] = item
+ indata["nsiInstanceId"] = _id
+ _id = self.engine.new_item(rollback, session, "nsilcmops", indata, kwargs)
+ self._set_location_header(main_topic, version, "nsi_lcm_op_occs", _id)
+ outdata = {"id": _id}
+ cherrypy.response.status = HTTPStatus.ACCEPTED.value
else:
_id = self.engine.new_item(rollback, session, engine_topic, indata, kwargs,
cherrypy.request.headers, force=force)
opp_id = self.engine.new_item(rollback, session, "nslcmops", nslcmop_desc, None)
outdata = {"_id": opp_id}
cherrypy.response.status = HTTPStatus.ACCEPTED.value
+ elif topic == "netslice_instances_content" and not force:
+ nsilcmop_desc = {
+ "lcmOperationType": "terminate",
+ "nsiInstanceId": _id,
+ "autoremove": True
+ }
+ opp_id = self.engine.new_item(rollback, session, "nsilcmops", nsilcmop_desc, None)
+ outdata = {"_id": opp_id}
+ cherrypy.response.status = HTTPStatus.ACCEPTED.value
else:
self.engine.del_item(session, engine_topic, _id, force)
cherrypy.response.status = HTTPStatus.NO_CONTENT.value
if not indata and not kwargs:
raise NbiException("Nothing to update. Provide payload and/or query string",
HTTPStatus.BAD_REQUEST)
- if item in ("nsd_content", "package_content") and method == "PUT":
+ if item in ("nsd_content", "package_content", "nst_content") and method == "PUT":
completed = self.engine.upload_content(session, engine_topic, _id, indata, kwargs,
cherrypy.request.headers, force=force)
if not completed:
cherrypy.log("Exception {}".format(e))
else:
http_code_value = cherrypy.response.status = HTTPStatus.BAD_REQUEST.value # INTERNAL_SERVER_ERROR
- cherrypy.log("CRITICAL: Exception {}".format(e))
+ cherrypy.log("CRITICAL: Exception {}".format(e), traceback=True)
http_code_name = HTTPStatus.BAD_REQUEST.name
if hasattr(outdata, "close"): # is an open file
outdata.close()