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 = []
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):
"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
),
},
"ns": {
"v1": {
+ "rebuild": {
+ "METHODS": ("POST",),
+ "ROLE_PERMISSION": "rebuild:",
+ "<ID>": {
+ "METHODS": ("POST",),
+ "ROLE_PERMISSION": "rebuild:id:",
+ },
+ },
+ "start": {
+ "METHODS": ("POST",),
+ "ROLE_PERMISSION": "start:",
+ "<ID>": {
+ "METHODS": ("POST",),
+ "ROLE_PERMISSION": "start:id:",
+ },
+ },
+ "stop": {
+ "METHODS": ("POST",),
+ "ROLE_PERMISSION": "stop:",
+ "<ID>": {
+ "METHODS": ("POST",),
+ "ROLE_PERMISSION": "stop:id:",
+ },
+ },
"deploy": {
"METHODS": ("GET",),
"ROLE_PERMISSION": "deploy:",
"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,
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)
"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):
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:
--- /dev/null
+#######################################################################################
+# 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.