RBAC with internal authentication backend - Phase 2
[osm/NBI.git] / osm_nbi / instance_topics.py
index 48503a9..74504b3 100644 (file)
@@ -31,6 +31,7 @@ __author__ = "Alfonso Tierno <alfonso.tiernosepulveda@telefonica.com>"
 class NsrTopic(BaseTopic):
     topic = "nsrs"
     topic_msg = "ns"
+    schema_new = ns_instantiate
 
     def __init__(self, db, fs, msg):
         BaseTopic.__init__(self, db, fs, msg)
@@ -53,6 +54,7 @@ class NsrTopic(BaseTopic):
     def format_on_new(content, project_id=None, make_public=False):
         BaseTopic.format_on_new(content, project_id=project_id, make_public=make_public)
         content["_admin"]["nsState"] = "NOT_INSTANTIATED"
+        return None
 
     def check_conflict_on_del(self, session, _id, db_content):
         """
@@ -180,6 +182,7 @@ class NsrTopic(BaseTopic):
         """
 
         try:
+            step = "validating input parameters"
             ns_request = self._remove_envelop(indata)
             # Override descriptor with query string kwargs
             self._update_input_with_kwargs(ns_request, kwargs)
@@ -226,7 +229,7 @@ class NsrTopic(BaseTopic):
                 "id": nsr_id,
                 "_id": nsr_id,
                 # "input-parameter": xpath, value,
-                "ssh-authorized-key": ns_request.get("key-pair-ref"),  # TODO remove
+                "ssh-authorized-key": ns_request.get("ssh_keys"),  # TODO remove
             }
             ns_request["nsr_id"] = nsr_id
             # Create vld
@@ -360,7 +363,7 @@ class NsrTopic(BaseTopic):
                     member_vnf["vnfd-id-ref"], member_vnf["member-vnf-index"])
 
                 # add at database
-                BaseTopic.format_on_new(vnfr_descriptor, session["project_id"], make_public=session["public"])
+                self.format_on_new(vnfr_descriptor, session["project_id"], make_public=session["public"])
                 self.db.create("vnfrs", vnfr_descriptor)
                 rollback.append({"topic": "vnfrs", "_id": vnfr_id})
                 nsr_descriptor["constituent-vnfr-ref"].append(vnfr_id)
@@ -373,12 +376,12 @@ class NsrTopic(BaseTopic):
             step = "creating nsr temporal folder"
             self.fs.mkdir(nsr_id)
 
-            return nsr_id
+            return nsr_id, None
+        except ValidationError as e:   # TODO remove try Except, it is captured at nbi.py
+            raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
         except Exception as e:
             self.logger.exception("Exception {} at NsrTopic.new()".format(e), exc_info=True)
             raise EngineException("Error {}: {}".format(step, e))
-        except ValidationError as e:
-            raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
 
     def edit(self, session, _id, indata=None, kwargs=None, content=None):
         raise EngineException("Method edit called directly", HTTPStatus.INTERNAL_SERVER_ERROR)
@@ -763,6 +766,15 @@ class NsLcmOpTopic(BaseTopic):
         :param headers: http request headers
         :return: id of the nslcmops
         """
+        def check_if_nsr_is_not_slice_member(session, nsr_id):
+            nsis = None
+            db_filter = self._get_project_filter(session)
+            db_filter["_admin.nsrs-detailed-list.ANYINDEX.nsrId"] = nsr_id
+            nsis = self.db.get_one("nsis", db_filter, fail_on_empty=False, fail_on_more=False)
+            if nsis:
+                raise EngineException("The NS instance {} cannot be terminate because is used by the slice {}".format(
+                                      nsr_id, nsis["_id"]), http_code=HTTPStatus.CONFLICT)
+
         try:
             # Override descriptor with query string kwargs
             self._update_input_with_kwargs(indata, kwargs)
@@ -776,6 +788,8 @@ class NsLcmOpTopic(BaseTopic):
             nsr = self.db.get_one("nsrs", _filter)
 
             # initial checking
+            if operation == "terminate" and slice_object is False:
+                check_if_nsr_is_not_slice_member(session, nsr["_id"])
             if not nsr["_admin"].get("nsState") or nsr["_admin"]["nsState"] == "NOT_INSTANTIATED":
                 if operation == "terminate" and indata.get("autoremove"):
                     # NSR must be deleted
@@ -798,8 +812,8 @@ class NsLcmOpTopic(BaseTopic):
             rollback.append({"topic": "nslcmops", "_id": _id})
             if not slice_object:
                 self.msg.write("ns", operation, nslcmop_desc)
-            return _id
-        except ValidationError as e:
+            return _id, None
+        except ValidationError as e:  # TODO remove try Except, it is captured at nbi.py
             raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
         # except DbException as e:
         #     raise EngineException("Cannot get ns_instance '{}': {}".format(e), HTTPStatus.NOT_FOUND)
@@ -976,12 +990,12 @@ class NsiTopic(BaseTopic):
         """
 
         try:
+            step = ""
             slice_request = self._remove_envelop(indata)
             # Override descriptor with query string kwargs
             self._update_input_with_kwargs(slice_request, kwargs)
             self._validate_input_new(slice_request, session["force"])
 
-            step = ""
             # look for nstd
             step = "getting nstd id='{}' from database".format(slice_request.get("nstId"))
             _filter = self._get_project_filter(session)
@@ -1090,7 +1104,8 @@ class NsiTopic(BaseTopic):
                     indata_ns["nsName"] = slice_request.get("nsiName") + "." + service["id"]
                     indata_ns["vimAccountId"] = slice_request.get("vimAccountId")
                     indata_ns["nsDescription"] = service["description"]
-                    indata_ns["key-pair-ref"] = slice_request.get("key-pair-ref")
+                    if slice_request.get("ssh_keys"):
+                        indata_ns["ssh_keys"] = slice_request.get("ssh_keys")
 
                     if ns_params:
                         for ns_param in ns_params:
@@ -1101,7 +1116,7 @@ class NsiTopic(BaseTopic):
                                 break                   
 
                     # Creates Nsr objects
-                    _id_nsr = self.nsrTopic.new(rollback, session, indata_ns, kwargs, headers)
+                    _id_nsr, _ = self.nsrTopic.new(rollback, session, indata_ns, kwargs, headers)
                 nsrs_item = {"nsrId": _id_nsr, "shared": service.get("is-shared-nss"), "nsd-id": service["nsd-ref"], 
                              "nslcmop_instantiate": None}
                 indata_ns["nss-id"] = service["id"]
@@ -1118,8 +1133,8 @@ class NsiTopic(BaseTopic):
             # Creating the entry in the database
             self.db.create("nsis", nsi_descriptor)
             rollback.append({"topic": "nsis", "_id": nsi_id})
-            return nsi_id
-        except Exception as e:
+            return nsi_id, None
+        except Exception as e:   # TODO remove try Except, it is captured at nbi.py
             self.logger.exception("Exception {} at NsiTopic.new()".format(e), exc_info=True)
             raise EngineException("Error {}: {}".format(step, e))
         except ValidationError as e:
@@ -1281,11 +1296,10 @@ class NsiLcmOpTopic(BaseTopic):
                     indata_ns["nsInstanceId"] = service["_id"]
                     # Including netslice_id in the ns instantiate Operation
                     indata_ns["netsliceInstanceId"] = netsliceInstanceId
-                    del indata_ns["key-pair-ref"]
-                    # Creating NS_LCM_OP with the flag slice_object=True to not trigger the service instantiation 
+                    # Creating NS_LCM_OP with the flag slice_object=True to not trigger the service instantiation
                     # message via kafka bus
-                    nslcmop = self.nsi_NsLcmOpTopic.new(rollback, session, indata_ns, kwargs, headers, 
-                                                        slice_object=True)
+                    nslcmop, _ = self.nsi_NsLcmOpTopic.new(rollback, session, indata_ns, kwargs, headers,
+                                                           slice_object=True)
                     nslcmops.append(nslcmop)
                     if operation == "terminate":
                         nslcmop = None
@@ -1307,7 +1321,7 @@ class NsiLcmOpTopic(BaseTopic):
             _id = self.db.create("nsilcmops", nsilcmop_desc)
             rollback.append({"topic": "nsilcmops", "_id": _id})
             self.msg.write("nsi", operation, nsilcmop_desc)
-            return _id
+            return _id, None
         except ValidationError as e:
             raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)