Feature 10996: Adds nslcmop_cancel to nbi.py and instance_topics.py 81/13981/6
authorGabriel Cuba <gcuba@whitestack.com>
Mon, 30 Oct 2023 19:01:54 +0000 (14:01 -0500)
committergarciadeblas <gerardo.garciadeblas@telefonica.com>
Wed, 29 Nov 2023 17:09:42 +0000 (18:09 +0100)
Change-Id: I1094c7537377ad31ed38012c4e49d8a3f31b274b
Signed-off-by: Gabriel Cuba <gcuba@whitestack.com>
osm_nbi/engine.py
osm_nbi/instance_topics.py
osm_nbi/nbi.py
osm_nbi/validation.py

index 9b17402..c4c8eb2 100644 (file)
@@ -380,6 +380,26 @@ class Engine(object):
         with self.write_lock:
             return self.map_topic[topic].edit(session, _id, indata, kwargs)
 
+    def cancel_item(
+        self, rollback, session, topic, indata=None, kwargs=None, headers=None
+    ):
+        """
+        Cancels an item
+        :param rollback: list to append created items at database in case a rollback must to be done
+        :param session: contains the used login username and working project, force to avoid checkins, public
+        :param topic: it can be: users, projects, vim_accounts, sdns, nsrs, nsds, vnfds
+        :param indata: data to be inserted
+        :param kwargs: used to override the indata descriptor
+        :param headers: http request headers
+        :return: _id: identity of the inserted data.
+        """
+        if topic not in self.map_topic:
+            raise EngineException(
+                "Unknown topic {}!!!".format(topic), HTTPStatus.INTERNAL_SERVER_ERROR
+            )
+        with self.write_lock:
+            self.map_topic[topic].cancel(rollback, session, indata, kwargs, headers)
+
     def upgrade_db(self, current_version, target_version):
         if target_version not in self.map_target_version_to_int.keys():
             raise EngineException(
index 6072267..8488a93 100644 (file)
@@ -31,6 +31,7 @@ from osm_nbi.validation import (
     nsi_instantiate,
     ns_migrate,
     ns_verticalscale,
+    nslcmop_cancel,
 )
 from osm_nbi.base_topic import (
     BaseTopic,
@@ -1202,6 +1203,7 @@ class NsLcmOpTopic(BaseTopic):
         "terminate": ns_terminate,
         "migrate": ns_migrate,
         "verticalscale": ns_verticalscale,
+        "cancel": nslcmop_cancel,
     }
 
     def __init__(self, db, fs, msg, auth):
@@ -2370,6 +2372,41 @@ class NsLcmOpTopic(BaseTopic):
         # except DbException as e:
         #     raise EngineException("Cannot get ns_instance '{}': {}".format(e), HTTPStatus.NOT_FOUND)
 
+    def cancel(self, rollback, session, indata=None, kwargs=None, headers=None):
+        validate_input(indata, self.operation_schema["cancel"])
+        # Override descriptor with query string kwargs
+        self._update_input_with_kwargs(indata, kwargs, yaml_format=True)
+        nsLcmOpOccId = indata["nsLcmOpOccId"]
+        cancelMode = indata["cancelMode"]
+        # get nslcmop from nsLcmOpOccId
+        _filter = BaseTopic._get_project_filter(session)
+        _filter["_id"] = nsLcmOpOccId
+        nslcmop = self.db.get_one("nslcmops", _filter)
+        # Fail is this is not an ongoing nslcmop
+        if nslcmop.get("operationState") not in [
+            "STARTING",
+            "PROCESSING",
+            "ROLLING_BACK",
+        ]:
+            raise EngineException(
+                "Operation is not in STARTING, PROCESSING or ROLLING_BACK state",
+                http_code=HTTPStatus.CONFLICT,
+            )
+        nsInstanceId = nslcmop["nsInstanceId"]
+        update_dict = {
+            "isCancelPending": True,
+            "cancelMode": cancelMode,
+        }
+        self.db.set_one(
+            "nslcmops", q_filter=_filter, update_dict=update_dict, fail_on_empty=False
+        )
+        data = {
+            "_id": nsLcmOpOccId,
+            "nsInstanceId": nsInstanceId,
+            "cancelMode": cancelMode,
+        }
+        self.msg.write("nslcmops", "cancel", data)
+
     def delete(self, session, _id, dry_run=False, not_send_msg=None):
         raise EngineException(
             "Method delete called directly", HTTPStatus.INTERNAL_SERVER_ERROR
index 46fd8cc..9aff857 100644 (file)
@@ -92,7 +92,7 @@ URL: /osm                                                       GET     POST
                     heal                                                O5
             /ns_lcm_op_occs                                     5       5
                 /<nsLcmOpOccId>                                 5                       5       5
-                    TO BE COMPLETED                             5               5
+                    cancel                                              05
             /vnf_instances  (also vnfrs for compatibility)      O
                 /<vnfInstanceId>                                O
             /subscriptions                                      5       5
@@ -475,6 +475,10 @@ valid_url_methods = {
                 "<ID>": {
                     "METHODS": ("GET",),
                     "ROLE_PERMISSION": "ns_instances:opps:id:",
+                    "cancel": {
+                        "METHODS": ("POST",),
+                        "ROLE_PERMISSION": "ns_instances:opps:cancel:",
+                    },
                 },
             },
             "vnfrs": {
@@ -1670,6 +1674,13 @@ class Server(object):
                     )
                     outdata = {"id": _id}
                     cherrypy.response.status = HTTPStatus.ACCEPTED.value
+                elif topic == "ns_lcm_op_occs" and item == "cancel":
+                    indata["nsLcmOpOccId"] = _id
+                    self.engine.cancel_item(
+                        rollback, engine_session, "nslcmops", indata, None
+                    )
+                    self._set_location_header(main_topic, version, topic, _id)
+                    cherrypy.response.status = HTTPStatus.ACCEPTED.value
                 else:
                     _id, op_id = self.engine.new_item(
                         rollback,
index 1bf597c..bfea112 100644 (file)
@@ -641,6 +641,23 @@ ns_verticalscale = {
     "additionalProperties": False,
 }
 
+nslcmop_cancel = {
+    "title": "Cancel nslcmop input schema",
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "type": "object",
+    "properties": {
+        "nsLcmOpOccId": id_schema,
+        "cancelMode": {
+            "enum": [
+                "GRACEFUL",
+                "FORCEFUL",
+            ]
+        },
+    },
+    "required": ["cancelMode"],
+    "additionalProperties": False,
+}
+
 schema_version = {"type": "string", "enum": ["1.0"]}
 schema_type = {"type": "string"}
 vim_type = shortname_schema  # {"enum": ["openstack", "openvim", "vmware", "opennebula", "aws", "azure", "fos"]}