self.lcm_tasks.remove("ns", nsr_id, nslcmop_id, "ns_action")
return nslcmop_operation_state, detailed_status
+ async def terminate_vdus(
+ self, db_vnfr, member_vnf_index, db_nsr, update_db_nslcmops, stage, logging_text
+ ):
+ """This method terminates VDUs
+
+ Args:
+ db_vnfr: VNF instance record
+ member_vnf_index: VNF index to identify the VDUs to be removed
+ db_nsr: NS instance record
+ update_db_nslcmops: Nslcmop update record
+ """
+ vca_scaling_info = []
+ scaling_info = {"scaling_group_name": "vdu_autoscale", "vdu": [], "kdu": []}
+ scaling_info["scaling_direction"] = "IN"
+ scaling_info["vdu-delete"] = {}
+ scaling_info["kdu-delete"] = {}
+ db_vdur = db_vnfr.get("vdur")
+ vdur_list = copy(db_vdur)
+ count_index = 0
+ for index, vdu in enumerate(vdur_list):
+ vca_scaling_info.append(
+ {
+ "osm_vdu_id": vdu["vdu-id-ref"],
+ "member-vnf-index": member_vnf_index,
+ "type": "delete",
+ "vdu_index": count_index,
+ })
+ scaling_info["vdu-delete"][vdu["vdu-id-ref"]] = count_index
+ scaling_info["vdu"].append(
+ {
+ "name": vdu.get("name") or vdu.get("vdu-name"),
+ "vdu_id": vdu["vdu-id-ref"],
+ "interface": [],
+ })
+ for interface in vdu["interfaces"]:
+ scaling_info["vdu"][index]["interface"].append(
+ {
+ "name": interface["name"],
+ "ip_address": interface["ip-address"],
+ "mac_address": interface.get("mac-address"),
+ })
+ self.logger.info("NS update scaling info{}".format(scaling_info))
+ stage[2] = "Terminating VDUs"
+ if scaling_info.get("vdu-delete"):
+ # scale_process = "RO"
+ if self.ro_config.get("ng"):
+ await self._scale_ng_ro(
+ logging_text, db_nsr, update_db_nslcmops, db_vnfr, scaling_info, stage
+ )
+
+ async def remove_vnf(
+ self, nsr_id, nslcmop_id, vnf_instance_id
+ ):
+ """This method is to Remove VNF instances from NS.
+
+ Args:
+ nsr_id: NS instance id
+ nslcmop_id: nslcmop id of update
+ vnf_instance_id: id of the VNF instance to be removed
+
+ Returns:
+ result: (str, str) COMPLETED/FAILED, details
+ """
+ try:
+ db_nsr_update = {}
+ logging_text = "Task ns={} update ".format(nsr_id)
+ check_vnfr_count = len(self.db.get_list("vnfrs", {"nsr-id-ref": nsr_id}))
+ self.logger.info("check_vnfr_count {}".format(check_vnfr_count))
+ if check_vnfr_count > 1:
+ stage = ["", "", ""]
+ step = "Getting nslcmop from database"
+ self.logger.debug(step + " after having waited for previous tasks to be completed")
+ # db_nslcmop = self.db.get_one("nslcmops", {"_id": nslcmop_id})
+ db_nsr = self.db.get_one("nsrs", {"_id": nsr_id})
+ db_vnfr = self.db.get_one("vnfrs", {"_id": vnf_instance_id})
+ member_vnf_index = db_vnfr["member-vnf-index-ref"]
+ """ db_vnfr = self.db.get_one(
+ "vnfrs", {"member-vnf-index-ref": member_vnf_index, "nsr-id-ref": nsr_id}) """
+
+ update_db_nslcmops = self.db.get_one("nslcmops", {"_id": nslcmop_id})
+ await self.terminate_vdus(db_vnfr, member_vnf_index, db_nsr, update_db_nslcmops, stage, logging_text)
+
+ constituent_vnfr = db_nsr.get("constituent-vnfr-ref")
+ constituent_vnfr.remove(db_vnfr.get("_id"))
+ db_nsr_update["constituent-vnfr-ref"] = db_nsr.get("constituent-vnfr-ref")
+ self.update_db_2("nsrs", nsr_id, db_nsr_update)
+ self.db.del_one("vnfrs", {"_id": db_vnfr.get("_id")})
+ self.update_db_2("nsrs", nsr_id, db_nsr_update)
+ return "COMPLETED", "Done"
+ else:
+ step = "Terminate VNF Failed with"
+ raise LcmException("{} Cannot terminate the last VNF in this NS.".format(
+ vnf_instance_id))
+ except (LcmException, asyncio.CancelledError):
+ raise
+ except Exception as e:
+ self.logger.debug("Error removing VNF {}".format(e))
+ return "FAILED", "Error removing VNF {}".format(e)
+
async def _ns_charm_upgrade(
self,
ee_id,
db_nsr_update = {}
error_description_nslcmop = ""
exc = None
- change_type = ""
+ change_type = "updated"
detailed_status = ""
try:
)
elif update_type == "REMOVE_VNF":
# This part is included in https://osm.etsi.org/gerrit/11876
- pass
+ vnf_instance_id = db_nslcmop["operationParams"]["removeVnfInstanceId"]
+ db_vnfr = self.db.get_one("vnfrs", {"_id": vnf_instance_id})
+ member_vnf_index = db_vnfr["member-vnf-index-ref"]
+ step = "Removing VNF"
+ (result, detailed_status) = await self.remove_vnf(nsr_id, nslcmop_id, vnf_instance_id)
+ if result == "FAILED":
+ nslcmop_operation_state = result
+ error_description_nslcmop = detailed_status
+ db_nslcmop_update["detailed-status"] = detailed_status
+ change_type = "vnf_terminated"
+ if not nslcmop_operation_state:
+ nslcmop_operation_state = "COMPLETED"
+ self.logger.debug(
+ logging_text
+ + " task Done with result {} {}".format(
+ nslcmop_operation_state, detailed_status
+ )
+ )
# If nslcmop_operation_state is None, so any operation is not failed.
# All operations are executed in overall.
if nslcmop_operation_state:
try:
- await self.msg.aiowrite(
- "ns",
- "updated",
- {
+ msg = {
"nsr_id": nsr_id,
"nslcmop_id": nslcmop_id,
"operationState": nslcmop_operation_state,
- },
- loop=self.loop,
- )
+ }
+ if change_type in ("vnf_terminated"):
+ msg.update({"vnf_member_index": member_vnf_index})
+ await self.msg.aiowrite("ns", change_type, msg, loop=self.loop)
except Exception as e:
self.logger.error(
logging_text + "kafka_write notification Exception {}".format(e)
operationState: COMPLETED
startTime: 1575034637.0445576
statusEnteredTime: 1575034663.8484545
+
+- _admin:
+ created: 1566823354.4148262
+ modified: 1566823354.4148262
+ projects_read:
+ - 25b5aebf-3da1-49ed-99de-1d2b4a86d6e4
+ projects_write:
+ - 25b5aebf-3da1-49ed-99de-1d2b4a86d6e4
+ worker: 86434c2948e2
+ operations:
+ - member_vnf_index: '1'
+ primitive: touch
+ primitive_params: /home/ubuntu/last-touch-1
+ operationState: COMPLETED
+ detailed-status: Done
+ _id: a639fac7-e0bb-4225-8ecb-c1f8efcc125f
+ detailed-status: done
+ id: a639fac7-e0bb-4225-8ecb-c1f8efcc125f
+ isAutomaticInvocation: false
+ isCancelPending: false
+ lcmOperationType: update
+ links:
+ nsInstance: /osm/nslcm/v1/ns_instances/f48163a6-c807-47bc-9682-f72caef5af85
+ self: /osm/nslcm/v1/ns_lcm_op_occs/a639fac7-e0bb-4225-8ecb-c1f8efcc125f
+ nsInstanceId: f48163a6-c807-47bc-9682-f72caef5af85
+ operationParams:
+ lcmOperationType: update
+ nsInstanceId: f48163a6-c807-47bc-9682-f72caef5af85
+ removeVnfInstanceId: 88d90b0c-faff-4b9f-bccd-017f33985984
+ updateType: REMOVE_VNF
+ operationState: FAILED
+ startTime: 1566823354.414689
+ statusEnteredTime: 1566824534.5112448
"""
db_nsrs_text = """
detailed-status: done
"""
+ro_update_action_text = """
+action_id: e62fc036-6e6f-4a6f-885e-bc12e2fbe75d
+details: progress 1/1
+nsr_id: 31dbfa80-80a8-4f2a-a557-626904df3402
+status: DONE
+tasks:
+- action: DELETE
+ action_id: e62fc036-6e6f-4a6f-885e-bc12e2fbe75d
+ item: vdu
+ nsr_id: 31dbfa80-80a8-4f2a-a557-626904df3402
+ status: FINISHED
+ target_record: vnfrs:5bbe7015-ae98-4e09-9316-76f3bf218353:vdur.0.vim_info.vim:2a3dc443-415b-4865-8420-f804b993c5a3
+ target_record_id: vnfrs:5bbe7015-ae98-4e09-9316-76f3bf218353:vdur.e03e2281-c70e-44ef-ac3b-052b81efd31d
+ task_id: e62fc036-6e6f-4a6f-885e-bc12e2fbe75d:0
+"""
+
test_ids = {
# contains the ids of ns and operations of every test
"TEST-A": {
"instantiate": "4013bbd2-b151-40ee-bcef-7e24ce5432f6",
"terminate": None,
},
+ "TEST-UPDATE": {
+ "ns": "f48163a6-c807-47bc-9682-f72caef5af85",
+ "vnf": "88d90b0c-faff-4b9f-bccd-017f33985984",
+ "removeVnf": "a639fac7-e0bb-4225-8ecb-c1f8efcc125f",
+ },
}
def _ro_status(self, *args, **kwargs):
print("Args > {}".format(args))
print("kwargs > {}".format(kwargs))
+ if args:
+ if "update" in args:
+ ro_ns_desc = yaml.load(
+ descriptors.ro_update_action_text, Loader=yaml.Loader
+ )
+ while True:
+ yield ro_ns_desc
if kwargs.get("delete"):
ro_ns_desc = yaml.load(
descriptors.ro_delete_action_text, Loader=yaml.Loader
or expected_kdu_model in nsr_kdu_model_result
)
+ # Test remove_vnf() and related methods
+ @asynctest.fail_on(active_handles=True) # all async tasks must be completed
+ async def test_remove_vnf(self):
+ # Test REMOVE_VNF
+ nsr_id = descriptors.test_ids["TEST-UPDATE"]["ns"]
+ nslcmop_id = descriptors.test_ids["TEST-UPDATE"]["removeVnf"]
+ vnf_instance_id = descriptors.test_ids["TEST-UPDATE"]["vnf"]
+ self.my_ns.RO.status = asynctest.CoroutineMock(self.my_ns.RO.status, side_effect=self._ro_status("update"))
+ await self.my_ns.update(nsr_id, nslcmop_id)
+ expected_value = "COMPLETED"
+ return_value = self.db.get_one("nslcmops", {"_id": nslcmop_id}).get(
+ "operationState"
+ )
+ self.assertEqual(return_value, expected_value)
+ with self.assertRaises(Exception) as context:
+ self.db.get_one("vnfrs", {"_id": vnf_instance_id})
+ self.assertTrue("database exception Not found entry with filter" in str(context.exception))
+
# async def test_instantiate_pdu(self):
# nsr_id = descriptors.test_ids["TEST-A"]["ns"]
# nslcmop_id = descriptors.test_ids["TEST-A"]["instantiate"]