From: k4.rahul Date: Mon, 2 May 2022 15:47:57 +0000 (+0000) Subject: Feature 10922: Stop, start and rebuild X-Git-Tag: v12.0.0rc1~9 X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FRO.git;a=commitdiff_plain;h=78f474e69fde9d64e8716978b5ea38f9f5aace48 Feature 10922: Stop, start and rebuild Added support for feature start stop rebuild of VNF instances Added unit test case for start stop rebuil of VNF instances Change-Id: I09d2512084268c190f5ae9cfdaae41269c6bc069 Signed-off-by: k4.rahul --- diff --git a/NG-RO/osm_ng_ro/ns.py b/NG-RO/osm_ng_ro/ns.py index d2dc46b5..3f14c587 100644 --- a/NG-RO/osm_ng_ro/ns.py +++ b/NG-RO/osm_ng_ro/ns.py @@ -2379,6 +2379,99 @@ class Ns(object): return None, None, True + def rebuild_start_stop_task( + self, + vdu_id, + vnf_id, + vdu_index, + action_id, + nsr_id, + task_index, + target_vim, + extra_dict, + ): + self._assign_vim(target_vim) + target_record = "vnfrs:{}:vdur.{}".format(vnf_id, vdu_index) + target_record_id = "vnfrs:{}:vdur.{}".format(vnf_id, vdu_id) + deployment_info = { + "action_id": action_id, + "nsr_id": nsr_id, + "task_index": task_index, + } + + task = Ns._create_task( + deployment_info=deployment_info, + target_id=target_vim, + item="update", + action="EXEC", + target_record=target_record, + target_record_id=target_record_id, + extra_dict=extra_dict, + ) + return task + + def rebuild_start_stop( + self, session, action_dict, version, nsr_id, *args, **kwargs + ): + task_index = 0 + extra_dict = {} + now = time() + action_id = action_dict.get("action_id", str(uuid4())) + step = "" + logging_text = "Task deploy nsr_id={} action_id={} ".format(nsr_id, action_id) + self.logger.debug(logging_text + "Enter") + + action = list(action_dict.keys())[0] + task_dict = action_dict.get(action) + vim_vm_id = action_dict.get(action).get("vim_vm_id") + + if action_dict.get("stop"): + action = "shutoff" + db_new_tasks = [] + try: + step = "lock the operation & do task creation" + with self.write_lock: + extra_dict["params"] = { + "vim_vm_id": vim_vm_id, + "action": action, + } + task = self.rebuild_start_stop_task( + task_dict["vdu_id"], + task_dict["vnf_id"], + task_dict["vdu_index"], + action_id, + nsr_id, + task_index, + task_dict["target_vim"], + extra_dict, + ) + db_new_tasks.append(task) + step = "upload Task to db" + self.upload_all_tasks( + db_new_tasks=db_new_tasks, + now=now, + ) + self.logger.debug( + logging_text + "Exit. Created {} tasks".format(len(db_new_tasks)) + ) + return ( + {"status": "ok", "nsr_id": nsr_id, "action_id": action_id}, + action_id, + True, + ) + except Exception as e: + if isinstance(e, (DbException, NsException)): + self.logger.error( + logging_text + "Exit Exception while '{}': {}".format(step, e) + ) + else: + e = traceback_format_exc() + self.logger.critical( + logging_text + "Exit Exception while '{}': {}".format(step, e), + exc_info=True, + ) + raise NsException(e) + def get_deploy(self, session, indata, version, nsr_id, action_id, *args, **kwargs): nsrs = self.db.get_list("nsrs", {}) return_data = [] diff --git a/NG-RO/osm_ng_ro/ns_thread.py b/NG-RO/osm_ng_ro/ns_thread.py index 767382d9..9ed04d7b 100644 --- a/NG-RO/osm_ng_ro/ns_thread.py +++ b/NG-RO/osm_ng_ro/ns_thread.py @@ -887,6 +887,48 @@ class VimInteractionAffinityGroup(VimInteractionBase): return "FAILED", ro_vim_item_update +class VimInteractionUpdateVdu(VimInteractionBase): + def exec(self, ro_task, task_index, task_depends): + task = ro_task["tasks"][task_index] + task_id = task["task_id"] + db_task_update = {"retries": 0} + created = False + created_items = {} + target_vim = self.my_vims[ro_task["target_id"]] + + try: + if task.get("params"): + vim_vm_id = task["params"].get("vim_vm_id") + action = task["params"].get("action") + context = {action: action} + target_vim.action_vminstance(vim_vm_id, context) + # created = True + ro_vim_item_update = { + "vim_id": vim_vm_id, + "vim_status": "DONE", + "created": created, + "created_items": created_items, + "vim_details": None, + "vim_message": None, + } + self.logger.debug( + "task={} {} vm-migration done".format(task_id, ro_task["target_id"]) + ) + return "DONE", ro_vim_item_update, db_task_update + except (vimconn.VimConnException, NsWorkerException) as e: + self.logger.error( + "task={} vim={} VM Migration:" + " {}".format(task_id, ro_task["target_id"], e) + ) + ro_vim_item_update = { + "vim_status": "VIM_ERROR", + "created": created, + "vim_message": str(e), + } + + return "FAILED", ro_vim_item_update, db_task_update + + class VimInteractionSdnNet(VimInteractionBase): @staticmethod def _match_pci(port_pci, mapping): @@ -1404,6 +1446,9 @@ class NsWorker(threading.Thread): "sdn_net": VimInteractionSdnNet( self.db, self.my_vims, self.db_vims, self.logger ), + "update": VimInteractionUpdateVdu( + self.db, self.my_vims, self.db_vims, self.logger + ), "affinity-or-anti-affinity-group": VimInteractionAffinityGroup( self.db, self.my_vims, self.db_vims, self.logger ), diff --git a/NG-RO/osm_ng_ro/ro_main.py b/NG-RO/osm_ng_ro/ro_main.py index 30acd2b6..bd2ea9e0 100644 --- a/NG-RO/osm_ng_ro/ro_main.py +++ b/NG-RO/osm_ng_ro/ro_main.py @@ -83,6 +83,30 @@ valid_url_methods = { }, "ns": { "v1": { + "rebuild": { + "METHODS": ("POST",), + "ROLE_PERMISSION": "rebuild:", + "": { + "METHODS": ("POST",), + "ROLE_PERMISSION": "rebuild:id:", + }, + }, + "start": { + "METHODS": ("POST",), + "ROLE_PERMISSION": "start:", + "": { + "METHODS": ("POST",), + "ROLE_PERMISSION": "start:id:", + }, + }, + "stop": { + "METHODS": ("POST",), + "ROLE_PERMISSION": "stop:", + "": { + "METHODS": ("POST",), + "ROLE_PERMISSION": "stop:id:", + }, + }, "deploy": { "METHODS": ("GET",), "ROLE_PERMISSION": "deploy:", @@ -170,6 +194,9 @@ class Server(object): "deploy:id:delete": self.ns.delete, "deploy:id:id:get": self.ns.status, "deploy:id:id:cancel:post": self.ns.cancel, + "rebuild:id:post": self.ns.rebuild_start_stop, + "start:id:post": self.ns.rebuild_start_stop, + "stop:id:post": self.ns.rebuild_start_stop, "recreate:id:post": self.ns.recreate, "recreate:id:id:get": self.ns.recreate_status, "migrate:id:post": self.ns.migrate, diff --git a/NG-RO/osm_ng_ro/tests/test_ns.py b/NG-RO/osm_ng_ro/tests/test_ns.py index 4e081afa..6c2615a5 100644 --- a/NG-RO/osm_ng_ro/tests/test_ns.py +++ b/NG-RO/osm_ng_ro/tests/test_ns.py @@ -2663,3 +2663,51 @@ class TestNs(unittest.TestCase): def test__process_vdu_params(self): pass + + @patch("osm_ng_ro.ns.Ns._assign_vim") + def test__rebuild_start_stop_task(self, assign_vim): + self.ns = Ns() + extra_dict = {} + actions = ["start", "stop", "rebuild"] + vdu_id = "bb9c43f9-10a2-4569-a8a8-957c3528b6d1" + vnf_id = "665b4165-ce24-4320-bf19-b9a45bade49f" + vdu_index = "0" + action_id = "bb937f49-3870-4169-b758-9732e1ff40f3" + nsr_id = "993166fe-723e-4680-ac4b-b1af2541ae31" + task_index = 0 + target_vim = "vim:f9f370ac-0d44-41a7-9000-457f2332bc35" + t = "vnfrs:665b4165-ce24-4320-bf19-b9a45bade49f:vdur.bb9c43f9-10a2-4569-a8a8-957c3528b6d1" + for action in actions: + expected_result = { + "target_id": "vim:f9f370ac-0d44-41a7-9000-457f2332bc35", + "action_id": "bb937f49-3870-4169-b758-9732e1ff40f3", + "nsr_id": "993166fe-723e-4680-ac4b-b1af2541ae31", + "task_id": "bb937f49-3870-4169-b758-9732e1ff40f3:0", + "status": "SCHEDULED", + "action": "EXEC", + "item": "update", + "target_record": "vnfrs:665b4165-ce24-4320-bf19-b9a45bade49f:vdur.0", + "target_record_id": t, + "params": { + "vim_vm_id": "f37b18ef-3caa-4dc9-ab91-15c669b16396", + "action": action, + }, + } + extra_dict["params"] = { + "vim_vm_id": "f37b18ef-3caa-4dc9-ab91-15c669b16396", + "action": action, + } + task = self.ns.rebuild_start_stop_task( + vdu_id, + vnf_id, + vdu_index, + action_id, + nsr_id, + task_index, + target_vim, + extra_dict, + ) + self.assertEqual(task.get("action_id"), action_id) + self.assertEqual(task.get("nsr_id"), nsr_id) + self.assertEqual(task.get("target_id"), target_vim) + self.assertDictEqual(task, expected_result) diff --git a/NG-RO/osm_ng_ro/validation.py b/NG-RO/osm_ng_ro/validation.py index ca8cbc2b..2601e90c 100644 --- a/NG-RO/osm_ng_ro/validation.py +++ b/NG-RO/osm_ng_ro/validation.py @@ -112,6 +112,22 @@ deploy_schema = { "additionalProperties": False, } +rebuild_schema = { + "$schema": "http://json-schema.org/draft-04/schema#", + "vm_rebuild": { + "type": "array", + "items": { + "type": "object", + "properties": { + "vdu-id": id_schema, + "vim_name": name_schema, + "member-vnf-index": name_schema, + }, + }, + "additionalProperties": True, + }, +} + class ValidationError(Exception): def __init__(self, message, http_code=HTTPStatus.UNPROCESSABLE_ENTITY): diff --git a/RO-VIM-openstack/osm_rovim_openstack/vimconn_openstack.py b/RO-VIM-openstack/osm_rovim_openstack/vimconn_openstack.py index 11a50aac..da1499d7 100644 --- a/RO-VIM-openstack/osm_rovim_openstack/vimconn_openstack.py +++ b/RO-VIM-openstack/osm_rovim_openstack/vimconn_openstack.py @@ -2519,12 +2519,29 @@ class vimconnector(vimconn.VimConnector): server.resume() elif server.status == "SHUTOFF": server.start() + else: + self.logger.debug( + "ERROR : Instance is not in SHUTOFF/PAUSE/SUSPEND state" + ) + raise vimconn.VimConnException( + "Cannot 'start' instance while it is in active state", + http_code=vimconn.HTTP_Bad_Request, + ) + elif "pause" in action_dict: server.pause() elif "resume" in action_dict: server.resume() elif "shutoff" in action_dict or "shutdown" in action_dict: - server.stop() + self.logger.debug("server status %s", server.status) + if server.status == "ACTIVE": + server.stop() + else: + self.logger.debug("ERROR: VM is not in Active state") + raise vimconn.VimConnException( + "VM is not in active state, stop operation is not allowed", + http_code=vimconn.HTTP_Bad_Request, + ) elif "forceOff" in action_dict: server.stop() # TODO elif "terminate" in action_dict: diff --git a/releasenotes/notes/feature_10922_stop_start_rebuild-917f01116bc078e3.yaml b/releasenotes/notes/feature_10922_stop_start_rebuild-917f01116bc078e3.yaml new file mode 100644 index 00000000..9f21d66b --- /dev/null +++ b/releasenotes/notes/feature_10922_stop_start_rebuild-917f01116bc078e3.yaml @@ -0,0 +1,21 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# 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. +####################################################################################### +--- +features: + - | + Feature 10922 - Stop, start and rebuild operations over a VDU of a running VNF instance + This feature enables performing Stop, start and rebuild operations on a VDU of a running VNF instance.