Merge branch 'master' into netslice
diff --git a/osm_nbi/nbi.py b/osm_nbi/nbi.py
index 1d53396..aeff32c 100644
--- a/osm_nbi/nbi.py
+++ b/osm_nbi/nbi.py
@@ -32,7 +32,7 @@
 """
 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
@@ -75,9 +75,11 @@
                 /<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
@@ -90,6 +92,30 @@
             /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.
     For filtering inside array, it must select the element of the array, or add ANYINDEX to apply the filtering over any
@@ -247,6 +273,40 @@
                                       },
                 }
             },
+            "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):
@@ -640,14 +700,20 @@
                     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
@@ -663,7 +729,7 @@
                 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,
@@ -691,6 +757,22 @@
                     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 NSI
+                    _id = self.engine.new_item(rollback, session, engine_topic, indata, kwargs, force=force)
+                    # creates nsilcmop
+                    indata["lcmOperationType"] = "instantiate"
+                    indata["nsiInstanceId"] = _id
+                    self.engine.new_item(rollback, session, "nsilcmops", indata, None)
+                    self._set_location_header(main_topic, version, topic, _id)
+                    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)
@@ -713,6 +795,15 @@
                         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
@@ -724,7 +815,7 @@
                 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: