X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FNBI.git;a=blobdiff_plain;f=osm_nbi%2Finstance_topics.py;h=8632e9465b4296375b5afd07b3fe5b8a3d68587c;hp=6922112d4430ed7ef938a8842309ceefc7bbce49;hb=ee31f53e40fd2435bf19c394842693ae0eb72a9e;hpb=e395aa49c788ab9c776d16b49b75cf80a54af532 diff --git a/osm_nbi/instance_topics.py b/osm_nbi/instance_topics.py index 6922112..8632e94 100644 --- a/osm_nbi/instance_topics.py +++ b/osm_nbi/instance_topics.py @@ -14,6 +14,7 @@ # limitations under the License. # import logging +import json from uuid import uuid4 from http import HTTPStatus from time import time @@ -239,14 +240,16 @@ class NsrTopic(BaseTopic): where_, k ) ) - if "." in k or "$" in k: + if "$" in k: raise EngineException( - "Invalid param at {}:{}. Keys must not contain dots or $".format( + "Invalid param at {}:{}. Keys must not contain $ symbol".format( where_, k ) ) if isinstance(v, (dict, tuple, list)): additional_params[k] = "!!yaml " + safe_dump(v) + if kdu_name: + additional_params = json.dumps(additional_params) if descriptor: for df in descriptor.get("df", []): @@ -345,6 +348,9 @@ class NsrTopic(BaseTopic): ) if vnfd_id not in needed_vnfds: vnfd = self._get_vnfd_from_db(vnfd_id, session) + if "revision" in vnfd["_admin"]: + vnfd["revision"] = vnfd["_admin"]["revision"] + vnfd.pop("_admin") needed_vnfds[vnfd_id] = vnfd nsr_descriptor["vnfd-id"].append(vnfd["_id"]) else: @@ -394,7 +400,6 @@ class NsrTopic(BaseTopic): _filter = self._get_project_filter(session) _filter["id"] = vnfd_id vnfd = self.db.get_one("vnfds", _filter, fail_on_empty=True, fail_on_more=True) - vnfd.pop("_admin") return vnfd def _add_nsr_to_db(self, nsr_descriptor, rollback, session): @@ -474,6 +479,7 @@ class NsrTopic(BaseTopic): "ssh-authorized-key": ns_request.get("ssh_keys"), # TODO remove "flavor": [], "image": [], + "affinity-or-anti-affinity-group": [], } ns_request["nsr_id"] = nsr_id if ns_request and ns_request.get("config-units"): @@ -503,6 +509,7 @@ class NsrTopic(BaseTopic): ) vnfd = self._get_vnfd_from_db(vnf_profile.get("vnfd-id"), session) + vnfd.pop("_admin") for vdu in vnfd.get("vdu", ()): flavor_data = {} @@ -588,6 +595,29 @@ class NsrTopic(BaseTopic): image_data = self._get_image_data_from_vnfd(vnfd, alt_image) self._add_image_to_nsr(nsr_descriptor, image_data) + # Add Affinity or Anti-affinity group information to NSR + vdu_profiles = vnfd.get("df", [[]])[0].get("vdu-profile", ()) + affinity_group_prefix_name = "{}-{}".format( + nsr_descriptor["name"][:16], vnf_profile.get("id")[:16] + ) + + for vdu_profile in vdu_profiles: + affinity_group_data = {} + for affinity_group in vdu_profile.get( + "affinity-or-anti-affinity-group", () + ): + affinity_group_data = ( + self._get_affinity_or_anti_affinity_group_data_from_vnfd( + vnfd, affinity_group["id"] + ) + ) + affinity_group_data["member-vnf-index"] = vnf_profile.get("id") + self._add_affinity_or_anti_affinity_group_to_nsr( + nsr_descriptor, + affinity_group_data, + affinity_group_prefix_name, + ) + for vld in nsr_vld: vld["vnfd-connection-point-ref"] = all_vld_connection_point_data.get( vld.get("id"), [] @@ -597,6 +627,51 @@ class NsrTopic(BaseTopic): return nsr_descriptor + def _get_affinity_or_anti_affinity_group_data_from_vnfd( + self, vnfd, affinity_group_id + ): + """ + Gets affinity-or-anti-affinity-group info from df and returns the desired affinity group + """ + affinity_group = utils.find_in_list( + vnfd.get("df", [[]])[0].get("affinity-or-anti-affinity-group", ()), + lambda ag: ag["id"] == affinity_group_id, + ) + affinity_group_data = {} + if affinity_group: + if affinity_group.get("id"): + affinity_group_data["ag-id"] = affinity_group["id"] + if affinity_group.get("type"): + affinity_group_data["type"] = affinity_group["type"] + if affinity_group.get("scope"): + affinity_group_data["scope"] = affinity_group["scope"] + return affinity_group_data + + def _add_affinity_or_anti_affinity_group_to_nsr( + self, nsr_descriptor, affinity_group_data, affinity_group_prefix_name + ): + """ + Adds affinity-or-anti-affinity-group to nsr checking first it is not already added + """ + affinity_group = next( + ( + f + for f in nsr_descriptor["affinity-or-anti-affinity-group"] + if all(f.get(k) == affinity_group_data[k] for k in affinity_group_data) + ), + None, + ) + if not affinity_group: + affinity_group_data["id"] = str( + len(nsr_descriptor["affinity-or-anti-affinity-group"]) + ) + affinity_group_data["name"] = "{}-{}".format( + affinity_group_prefix_name, affinity_group_data["ag-id"][:32] + ) + nsr_descriptor["affinity-or-anti-affinity-group"].append( + affinity_group_data + ) + def _get_image_data_from_vnfd(self, vnfd, sw_image_id): sw_image_desc = utils.find_in_list( vnfd.get("sw-image-desc", ()), lambda sw: sw["id"] == sw_image_id @@ -659,6 +734,13 @@ class NsrTopic(BaseTopic): "connection-point": [], "ip-address": None, # mgmt-interface filled by LCM } + + # Revision backwards compatility. Only specify the revision in the record if + # the original VNFD has a revision. + if "revision" in vnfd: + vnfr_descriptor["revision"] = vnfd["revision"] + + vnf_k8s_namespace = ns_k8s_namespace if vnf_params: if vnf_params.get("k8s-namespace"): @@ -938,6 +1020,49 @@ class NsrTopic(BaseTopic): if nsr_flavor_desc: vdur["ns-flavor-id"] = nsr_flavor_desc["id"] + # Adding Affinity groups information to vdur + try: + vdu_profile_affinity_group = utils.find_in_list( + vnfd.get("df")[0]["vdu-profile"], + lambda a_vdu: a_vdu["id"] == vdu["id"], + ) + except Exception: + vdu_profile_affinity_group = None + + if vdu_profile_affinity_group: + affinity_group_ids = [] + for affinity_group in vdu_profile_affinity_group.get( + "affinity-or-anti-affinity-group", () + ): + vdu_affinity_group = utils.find_in_list( + vdu_profile_affinity_group.get( + "affinity-or-anti-affinity-group", () + ), + lambda ag_fp: ag_fp["id"] == affinity_group["id"], + ) + nsr_affinity_group = utils.find_in_list( + nsr_descriptor["affinity-or-anti-affinity-group"], + lambda nsr_ag: ( + nsr_ag.get("ag-id") == vdu_affinity_group.get("id") + and nsr_ag.get("member-vnf-index") + == vnfr_descriptor.get("member-vnf-index-ref") + ), + ) + # Update Affinity Group VIM name if VDU instantiation parameter is present + if vnf_params and vnf_params.get("affinity-or-anti-affinity-group"): + vnf_params_affinity_group = utils.find_in_list( + vnf_params["affinity-or-anti-affinity-group"], + lambda vnfp_ag: ( + vnfp_ag.get("id") == vdu_affinity_group.get("id") + ), + ) + if vnf_params_affinity_group.get("vim-affinity-group-id"): + nsr_affinity_group[ + "vim-affinity-group-id" + ] = vnf_params_affinity_group["vim-affinity-group-id"] + affinity_group_ids.append(nsr_affinity_group["id"]) + vdur["affinity-or-anti-affinity-group-id"] = affinity_group_ids + if vdu_instantiation_level: count = vdu_instantiation_level.get("number-of-instances") else: @@ -1210,7 +1335,14 @@ class NsLcmOpTopic(BaseTopic): "Invalid parameter member_vnf_index='{}' is not one of the " "nsd:constituent-vnfd".format(member_vnf_index) ) - vnfd = self.db.get_one("vnfds", {"_id": vnfr["vnfd-id"]}, fail_on_empty=False) + + ## Backwards compatibility: if there is no revision, get it from the one and only VNFD entry + if "revision" in vnfr: + vnfd_revision = vnfr["vnfd-id"] + ":" + str(vnfr["revision"]) + vnfd = self.db.get_one("vnfds_revisions", {"_id": vnfd_revision}, fail_on_empty=False) + else: + vnfd = self.db.get_one("vnfds", {"_id": vnfr["vnfd-id"]}, fail_on_empty=False) + if not vnfd: raise EngineException( "vnfd id={} has been deleted!. Operation cannot be performed".format( @@ -1987,6 +2119,10 @@ class NsLcmOpTopic(BaseTopic): HTTPStatus.CONFLICT, ) self._check_ns_operation(session, nsr, operation, indata) + if (indata.get("primitive_params")): + indata["primitive_params"] = json.dumps(indata["primitive_params"]) + elif (indata.get("additionalParamsForVnf")): + indata["additionalParamsForVnf"] = json.dumps(indata["additionalParamsForVnf"]) if operation == "instantiate": self._update_vnfrs_from_nsd(nsr)