X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FNBI.git;a=blobdiff_plain;f=osm_nbi%2Finstance_topics.py;h=16bd4062ace93245f70359f3ef2ec2d7169a4a3e;hp=2df6a7d15b93bf78a26fd84f74c0672b93e1a440;hb=99078a9577483842df536a706651542dfcde35be;hpb=6380e7cbe3ffd525453b5d8ef54c18a9cc14fa5d diff --git a/osm_nbi/instance_topics.py b/osm_nbi/instance_topics.py index 2df6a7d..16bd406 100644 --- a/osm_nbi/instance_topics.py +++ b/osm_nbi/instance_topics.py @@ -27,8 +27,10 @@ from osm_nbi.validation import ( ns_action, ns_scale, ns_update, + ns_heal, nsi_instantiate, ns_migrate, + ns_verticalscale, ) from osm_nbi.base_topic import ( BaseTopic, @@ -439,6 +441,81 @@ class NsrTopic(BaseTopic): return ns_k8s_namespace + def _add_flavor_to_nsr(self, vdu, vnfd, nsr_descriptor, member_vnf_index, revision=None): + flavor_data = {} + guest_epa = {} + # Find this vdu compute and storage descriptors + vdu_virtual_compute = {} + vdu_virtual_storage = {} + for vcd in vnfd.get("virtual-compute-desc", ()): + if vcd.get("id") == vdu.get("virtual-compute-desc"): + vdu_virtual_compute = vcd + for vsd in vnfd.get("virtual-storage-desc", ()): + if vsd.get("id") == vdu.get("virtual-storage-desc", [[]])[0]: + vdu_virtual_storage = vsd + # Get this vdu vcpus, memory and storage info for flavor_data + if vdu_virtual_compute.get("virtual-cpu", {}).get( + "num-virtual-cpu" + ): + flavor_data["vcpu-count"] = vdu_virtual_compute["virtual-cpu"][ + "num-virtual-cpu" + ] + if vdu_virtual_compute.get("virtual-memory", {}).get("size"): + flavor_data["memory-mb"] = ( + float(vdu_virtual_compute["virtual-memory"]["size"]) + * 1024.0 + ) + if vdu_virtual_storage.get("size-of-storage"): + flavor_data["storage-gb"] = vdu_virtual_storage[ + "size-of-storage" + ] + # Get this vdu EPA info for guest_epa + if vdu_virtual_compute.get("virtual-cpu", {}).get("cpu-quota"): + guest_epa["cpu-quota"] = vdu_virtual_compute["virtual-cpu"][ + "cpu-quota" + ] + if vdu_virtual_compute.get("virtual-cpu", {}).get("pinning"): + vcpu_pinning = vdu_virtual_compute["virtual-cpu"]["pinning"] + if vcpu_pinning.get("thread-policy"): + guest_epa["cpu-thread-pinning-policy"] = vcpu_pinning[ + "thread-policy" + ] + if vcpu_pinning.get("policy"): + cpu_policy = ( + "SHARED" + if vcpu_pinning["policy"] == "dynamic" + else "DEDICATED" + ) + guest_epa["cpu-pinning-policy"] = cpu_policy + if vdu_virtual_compute.get("virtual-memory", {}).get("mem-quota"): + guest_epa["mem-quota"] = vdu_virtual_compute["virtual-memory"][ + "mem-quota" + ] + if vdu_virtual_compute.get("virtual-memory", {}).get( + "mempage-size" + ): + guest_epa["mempage-size"] = vdu_virtual_compute[ + "virtual-memory" + ]["mempage-size"] + if vdu_virtual_compute.get("virtual-memory", {}).get( + "numa-node-policy" + ): + guest_epa["numa-node-policy"] = vdu_virtual_compute[ + "virtual-memory" + ]["numa-node-policy"] + if vdu_virtual_storage.get("disk-io-quota"): + guest_epa["disk-io-quota"] = vdu_virtual_storage[ + "disk-io-quota" + ] + + if guest_epa: + flavor_data["guest-epa"] = guest_epa + + revision = revision if revision is not None else 1 + flavor_data["name"] = vdu["id"][:56] + "-" + member_vnf_index + "-" + str(revision) + "-flv" + flavor_data["id"] = str(len(nsr_descriptor["flavor"])) + nsr_descriptor["flavor"].append(flavor_data) + def _create_nsr_descriptor_from_nsd(self, nsd, ns_request, nsr_id, session): now = time() additional_params, _ = self._format_additional_params( @@ -483,6 +560,9 @@ class NsrTopic(BaseTopic): "image": [], "affinity-or-anti-affinity-group": [], } + if "revision" in nsd["_admin"]: + nsr_descriptor["revision"] = nsd["_admin"]["revision"] + ns_request["nsr_id"] = nsr_id if ns_request and ns_request.get("config-units"): nsr_descriptor["config-units"] = ns_request["config-units"] @@ -514,79 +594,8 @@ class NsrTopic(BaseTopic): vnfd.pop("_admin") for vdu in vnfd.get("vdu", ()): - flavor_data = {} - guest_epa = {} - # Find this vdu compute and storage descriptors - vdu_virtual_compute = {} - vdu_virtual_storage = {} - for vcd in vnfd.get("virtual-compute-desc", ()): - if vcd.get("id") == vdu.get("virtual-compute-desc"): - vdu_virtual_compute = vcd - for vsd in vnfd.get("virtual-storage-desc", ()): - if vsd.get("id") == vdu.get("virtual-storage-desc", [[]])[0]: - vdu_virtual_storage = vsd - # Get this vdu vcpus, memory and storage info for flavor_data - if vdu_virtual_compute.get("virtual-cpu", {}).get( - "num-virtual-cpu" - ): - flavor_data["vcpu-count"] = vdu_virtual_compute["virtual-cpu"][ - "num-virtual-cpu" - ] - if vdu_virtual_compute.get("virtual-memory", {}).get("size"): - flavor_data["memory-mb"] = ( - float(vdu_virtual_compute["virtual-memory"]["size"]) - * 1024.0 - ) - if vdu_virtual_storage.get("size-of-storage"): - flavor_data["storage-gb"] = vdu_virtual_storage[ - "size-of-storage" - ] - # Get this vdu EPA info for guest_epa - if vdu_virtual_compute.get("virtual-cpu", {}).get("cpu-quota"): - guest_epa["cpu-quota"] = vdu_virtual_compute["virtual-cpu"][ - "cpu-quota" - ] - if vdu_virtual_compute.get("virtual-cpu", {}).get("pinning"): - vcpu_pinning = vdu_virtual_compute["virtual-cpu"]["pinning"] - if vcpu_pinning.get("thread-policy"): - guest_epa["cpu-thread-pinning-policy"] = vcpu_pinning[ - "thread-policy" - ] - if vcpu_pinning.get("policy"): - cpu_policy = ( - "SHARED" - if vcpu_pinning["policy"] == "dynamic" - else "DEDICATED" - ) - guest_epa["cpu-pinning-policy"] = cpu_policy - if vdu_virtual_compute.get("virtual-memory", {}).get("mem-quota"): - guest_epa["mem-quota"] = vdu_virtual_compute["virtual-memory"][ - "mem-quota" - ] - if vdu_virtual_compute.get("virtual-memory", {}).get( - "mempage-size" - ): - guest_epa["mempage-size"] = vdu_virtual_compute[ - "virtual-memory" - ]["mempage-size"] - if vdu_virtual_compute.get("virtual-memory", {}).get( - "numa-node-policy" - ): - guest_epa["numa-node-policy"] = vdu_virtual_compute[ - "virtual-memory" - ]["numa-node-policy"] - if vdu_virtual_storage.get("disk-io-quota"): - guest_epa["disk-io-quota"] = vdu_virtual_storage[ - "disk-io-quota" - ] - - if guest_epa: - flavor_data["guest-epa"] = guest_epa - - flavor_data["name"] = vdu["id"][:56] + "-flv" - flavor_data["id"] = str(len(nsr_descriptor["flavor"])) - nsr_descriptor["flavor"].append(flavor_data) - + member_vnf_index = vnf_profile.get("id") + self._add_flavor_to_nsr(vdu, vnfd, nsr_descriptor, member_vnf_index) sw_image_id = vdu.get("sw-image-desc") if sw_image_id: image_data = self._get_image_data_from_vnfd(vnfd, sw_image_id) @@ -712,6 +721,7 @@ class NsrTopic(BaseTopic): nsr_descriptor, ns_request, ns_k8s_namespace, + revision=None, ): vnfr_id = str(uuid4()) nsr_id = nsr_descriptor["id"] @@ -889,7 +899,10 @@ class NsrTopic(BaseTopic): vdur["internal-connection-point"].append(vdu_icp) for iface in icp.get("virtual-network-interface-requirement", ()): - iface_fields = ("name", "mac-address") + # Name, mac-address and interface position is taken from VNFD + # and included into VNFR. By this way RO can process this information + # while creating the VDU. + iface_fields = ("name", "mac-address", "position") vdu_iface = { x: iface[x] for x in iface_fields if iface.get(x) is not None } @@ -1013,7 +1026,8 @@ class NsrTopic(BaseTopic): alt_image_ids.append(nsr_sw_image_data["id"]) vdur["alt-image-ids"] = alt_image_ids - flavor_data_name = vdu["id"][:56] + "-flv" + revision = revision if revision is not None else 1 + flavor_data_name = vdu["id"][:56] + "-" + vnf_index + "-" + str(revision) + "-flv" nsr_flavor_desc = utils.find_in_list( nsr_descriptor["flavor"], lambda flavor: flavor["name"] == flavor_data_name, @@ -1158,18 +1172,21 @@ class NsLcmOpTopic(BaseTopic): "action": ns_action, "update": ns_update, "scale": ns_scale, + "heal": ns_heal, "terminate": ns_terminate, "migrate": ns_migrate, + "verticalscale": ns_verticalscale, } def __init__(self, db, fs, msg, auth): BaseTopic.__init__(self, db, fs, msg, auth) + self.nsrtopic = NsrTopic(db, fs, msg, auth) def _check_ns_operation(self, session, nsr, operation, indata): """ Check that user has enter right parameters for the operation :param session: contains "username", "admin", "force", "public", "project_id", "set_project" - :param operation: it can be: instantiate, terminate, action, update. TODO: heal + :param operation: it can be: instantiate, terminate, action, update, heal :param indata: descriptor with the parameters of the operation :return: None """ @@ -1179,6 +1196,8 @@ class NsLcmOpTopic(BaseTopic): self._check_scale_ns_operation(indata, nsr) elif operation == "update": self._check_update_ns_operation(indata, nsr) + elif operation == "heal": + self._check_heal_ns_operation(indata, nsr) elif operation == "instantiate": self._check_instantiate_ns_operation(indata, nsr, session) @@ -1381,6 +1400,9 @@ class NsLcmOpTopic(BaseTopic): ) ) + def _check_heal_ns_operation(self, indata, nsr): + return + def _check_instantiate_ns_operation(self, indata, nsr, session): vnf_member_index_to_vnfd = {} # map between vnf_member_index to vnf descriptor. vim_accounts = [] @@ -1475,7 +1497,7 @@ class NsLcmOpTopic(BaseTopic): if in_vdu["id"] == vdu["id"]: for volume in get_iterable(in_vdu.get("volume")): for volumed in get_iterable(vdu.get("virtual-storage-desc")): - if volumed["id"] == volume["name"]: + if volumed == volume["name"]: break else: raise EngineException( @@ -1495,7 +1517,7 @@ class NsLcmOpTopic(BaseTopic): ): vdu_if_names.add(iface.get("name")) - for in_iface in get_iterable(in_vdu["interface"]): + for in_iface in get_iterable(in_vdu.get("interface")): if in_iface["name"] in vdu_if_names: break else: @@ -2223,7 +2245,47 @@ class NsLcmOpTopic(BaseTopic): if operation == "instantiate": self._update_vnfrs_from_nsd(nsr) self._update_vnfrs(session, rollback, nsr, indata) - + if (operation == "update") and (indata["updateType"] == "CHANGE_VNFPKG"): + nsr_update = {} + vnfd_id = indata["changeVnfPackageData"]["vnfdId"] + vnfd = self.db.get_one("vnfds", {"_id": vnfd_id}) + nsd = self.db.get_one("nsds", {"_id": nsr["nsd-id"]}) + ns_request = nsr["instantiate_params"] + vnfr = self.db.get_one("vnfrs", {"_id": indata["changeVnfPackageData"]["vnfInstanceId"]}) + latest_vnfd_revision = vnfd["_admin"].get("revision", 1) + vnfr_vnfd_revision = vnfr.get("revision", 1) + if latest_vnfd_revision != vnfr_vnfd_revision: + old_vnfd_id = vnfd_id + ":" + str(vnfr_vnfd_revision) + old_db_vnfd = self.db.get_one("vnfds_revisions", {"_id": old_vnfd_id}) + old_sw_version = old_db_vnfd.get("software-version", "1.0") + new_sw_version = vnfd.get("software-version", "1.0") + if new_sw_version != old_sw_version: + vnf_index = vnfr["member-vnf-index-ref"] + self.logger.info("nsr {}".format(nsr)) + for vdu in vnfd["vdu"]: + self.nsrtopic._add_flavor_to_nsr(vdu, vnfd, nsr, vnf_index, latest_vnfd_revision) + sw_image_id = vdu.get("sw-image-desc") + if sw_image_id: + image_data = self.nsrtopic._get_image_data_from_vnfd(vnfd, sw_image_id) + self.nsrtopic._add_image_to_nsr(nsr, image_data) + for alt_image in vdu.get("alternative-sw-image-desc", ()): + image_data = self.nsrtopic._get_image_data_from_vnfd(vnfd, alt_image) + self.nsrtopic._add_image_to_nsr(nsr, image_data) + nsr_update["image"] = nsr["image"] + nsr_update["flavor"] = nsr["flavor"] + self.db.set_one("nsrs", {"_id": nsr["_id"]}, nsr_update) + ns_k8s_namespace = self.nsrtopic._get_ns_k8s_namespace(nsd, ns_request, session) + vnfr_descriptor = self.nsrtopic._create_vnfr_descriptor_from_vnfd( + nsd, + vnfd, + vnfd_id, + vnf_index, + nsr, + ns_request, + ns_k8s_namespace, + latest_vnfd_revision, + ) + indata["newVdur"] = vnfr_descriptor["vdur"] nslcmop_desc = self._create_nslcmop(nsInstanceId, operation, indata) _id = nslcmop_desc["_id"] self.format_on_new(