# limitations under the License.
# import logging
+import json
from uuid import uuid4
from http import HTTPStatus
from time import time
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", []):
"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"):
nsr_descriptor["config-units"] = ns_request["config-units"]
-
# Create vld
if nsd.get("virtual-link-desc"):
nsr_vld = deepcopy(nsd.get("virtual-link-desc", []))
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"), []
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
kdu_model = kdu_params.get("kdu_model") if kdu_params else None
if kdu_params and kdu_params.get("k8s-namespace"):
kdu_k8s_namespace = kdu_params["k8s-namespace"]
+ kdu_deployment_name = ""
+ if kdu_params and kdu_params.get("kdu-deployment-name"):
+ kdu_deployment_name = kdu_params.get("kdu-deployment-name")
kdur = {
"additionalParams": additional_params,
"k8s-namespace": kdu_k8s_namespace,
+ "kdu-deployment-name": kdu_deployment_name,
"kdu-name": kdu["name"],
# TODO "name": "" Name of the VDU in the VIM
"ip-address": None, # mgmt-interface filled by LCM
additional_params, vdu_params = self._format_additional_params(
ns_request, vnf_index, vdu_id=vdu["id"], descriptor=vnfd
)
+
+ try:
+ vdu_virtual_storage_descriptors = utils.filter_in_list(
+ vnfd.get("virtual-storage-desc", []),
+ lambda stg_desc: stg_desc["id"] in vdu["virtual-storage-desc"]
+ )
+ except Exception:
+ vdu_virtual_storage_descriptors = []
vdur = {
"vdu-id-ref": vdu["id"],
# TODO "name": "" Name of the VDU in the VIM
"interfaces": [],
"additionalParams": additional_params,
"vdu-name": vdu["name"],
+ "virtual-storages": vdu_virtual_storage_descriptors
}
if vdu_params and vdu_params.get("config-units"):
vdur["config-units"] = vdu_params["config-units"]
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:
for index in range(0, count):
vdur = deepcopy(vdur)
for iface in vdur["interfaces"]:
- if iface.get("ip-address"):
+ if iface.get("ip-address") and index != 0:
iface["ip-address"] = increment_ip_mac(iface["ip-address"])
- if iface.get("mac-address"):
+ if iface.get("mac-address") and index != 0:
iface["mac-address"] = increment_ip_mac(iface["mac-address"])
vdur["_id"] = str(uuid4())
)
vim_accounts.append(vim_account)
+ def _get_vim_account(self, vim_id: str, session):
+ try:
+ db_filter = self._get_project_filter(session)
+ db_filter["_id"] = vim_id
+ return self.db.get_one("vim_accounts", db_filter)
+ except Exception:
+ raise EngineException(
+ "Invalid vimAccountId='{}' not present for the project".format(
+ vim_id
+ )
+ )
+
def _check_valid_wim_account(self, wim_account, wim_accounts, session):
if not isinstance(wim_account, str):
return
if wim_account in wim_accounts:
return
try:
- db_filter = self._get_project_filter(session, write=False, show_all=True)
+ db_filter = self._get_project_filter(session)
db_filter["_id"] = wim_account
self.db.get_one("wim_accounts", db_filter)
except Exception:
# TODO check that this forcing is not incompatible with other forcing
return ifaces_forcing_vim_network
+ def _update_vnfrs_from_nsd(self, nsr):
+ try:
+ nsr_id = nsr["_id"]
+ nsd = nsr["nsd"]
+
+ step = "Getting vnf_profiles from nsd"
+ vnf_profiles = nsd.get("df", [{}])[0].get("vnf-profile", ())
+ vld_fixed_ip_connection_point_data = {}
+
+ step = "Getting ip-address info from vnf_profile if it exists"
+ for vnfp in vnf_profiles:
+ # Checking ip-address info from nsd.vnf_profile and storing
+ for vlc in vnfp.get("virtual-link-connectivity", ()):
+ for cpd in vlc.get("constituent-cpd-id", ()):
+ if cpd.get("ip-address"):
+ step = "Storing ip-address info"
+ vld_fixed_ip_connection_point_data.update({vlc.get("virtual-link-profile-id") + '.' + cpd.get("constituent-base-element-id"): {
+ "vnfd-connection-point-ref": cpd.get(
+ "constituent-cpd-id"),
+ "ip-address": cpd.get(
+ "ip-address")}})
+
+ # Inserting ip address to vnfr
+ if len(vld_fixed_ip_connection_point_data) > 0:
+ step = "Getting vnfrs"
+ vnfrs = self.db.get_list("vnfrs", {"nsr-id-ref": nsr_id})
+ for item in vld_fixed_ip_connection_point_data.keys():
+ step = "Filtering vnfrs"
+ vnfr = next(filter(lambda vnfr: vnfr["member-vnf-index-ref"] == item.split('.')[1], vnfrs), None)
+ if vnfr:
+ vnfr_update = {}
+ for vdur_index, vdur in enumerate(vnfr["vdur"]):
+ for iface_index, iface in enumerate(vdur["interfaces"]):
+ step = "Looking for matched interface"
+ if (
+ iface.get("external-connection-point-ref")
+ == vld_fixed_ip_connection_point_data[item].get("vnfd-connection-point-ref") and
+ iface.get("ns-vld-id") == item.split('.')[0]
+
+ ):
+ vnfr_update_text = "vdur.{}.interfaces.{}".format(
+ vdur_index, iface_index
+ )
+ step = "Storing info in order to update vnfr"
+ vnfr_update[
+ vnfr_update_text + ".ip-address"
+ ] = increment_ip_mac(
+ vld_fixed_ip_connection_point_data[item].get("ip-address"),
+ vdur.get("count-index", 0), )
+ vnfr_update[vnfr_update_text + ".fixed-ip"] = True
+
+ step = "updating vnfr at database"
+ self.db.set_one("vnfrs", {"_id": vnfr["_id"]}, vnfr_update)
+ except (
+ ValidationError,
+ EngineException,
+ DbException,
+ MsgException,
+ FsException,
+ ) as e:
+ raise type(e)("{} while '{}'".format(e, step), http_code=e.http_code)
+
def _update_vnfrs(self, session, rollback, nsr, indata):
# get vnfr
nsr_id = nsr["_id"]
# update vim-account-id
vim_account = indata["vimAccountId"]
- vca_id = indata.get("vcaId")
+ vca_id = self._get_vim_account(vim_account, session).get("vca")
# check instantiate parameters
for vnf_inst_params in get_iterable(indata.get("vnf")):
if vnf_inst_params["member-vnf-index"] != member_vnf_index:
continue
if vnf_inst_params.get("vimAccountId"):
vim_account = vnf_inst_params.get("vimAccountId")
- if vnf_inst_params.get("vcaId"):
- vca_id = vnf_inst_params.get("vcaId")
+ vca_id = self._get_vim_account(vim_account, session).get("vca")
# get vnf.vdu.interface instantiation params to update vnfr.vdur.interfaces ip, mac
for vdu_inst_param in get_iterable(vnf_inst_params.get("vdu")):
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)
self._update_vnfrs(session, rollback, nsr, indata)
nslcmop_desc = self._create_nslcmop(nsInstanceId, operation, indata)