From 0a517b9e7545addee365ae2622f3db035435cc63 Mon Sep 17 00:00:00 2001 From: garciaale Date: Tue, 12 Jan 2021 15:44:44 -0300 Subject: [PATCH] Adds descriptor translation logic from OSMv8 IM to SOL006 models Change-Id: Ic7bd7d5e63c609600508e13ab21023b8fc38fc25 Signed-off-by: garciaale --- osm_im/im_translation.py | 634 ++++++++++++++++++ tests/examples/alternative_image_sol006.yaml | 31 +- tests/examples/cirros_nsd_im.yaml | 4 +- tests/examples/cirros_nsd_sol006.yaml | 10 +- tests/examples/cirros_vnfd_sol006.yaml | 15 +- tests/examples/epa_im.yaml | 2 +- tests/examples/epa_sol006.yaml | 126 ++-- .../examples/hackfest_charmed_nsd_sol006.yaml | 19 +- tests/examples/hackfest_charmed_vnfd_im.yaml | 7 +- .../hackfest_charmed_vnfd_sol006.yaml | 48 +- tests/examples/magma_knf_im.yaml | 1 + tests/examples/magma_knf_sol006.yaml | 27 +- tests/examples/vepc_im.yaml | 4 +- tests/examples/vepc_nsd_sol006.yaml | 31 +- tests/examples/vepc_sol006.yaml | 77 +-- tests/examples/vnfd_im.yaml | 6 +- tests/examples/vnfd_sol006.yaml | 42 +- tests/test_im_translation.py | 80 +++ 18 files changed, 952 insertions(+), 212 deletions(-) create mode 100644 osm_im/im_translation.py create mode 100644 tests/test_im_translation.py diff --git a/osm_im/im_translation.py b/osm_im/im_translation.py new file mode 100644 index 0000000..9216f45 --- /dev/null +++ b/osm_im/im_translation.py @@ -0,0 +1,634 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Whitestack, LLC +# ************************************************************* +# +# This file is part of OSM common repository. +# All Rights Reserved to Whitestack, LLC +# +# 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. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact: agarcia@whitestack.com +## + +from osm_im.validation import Validation, ValidationException + + +class TranslationException(Exception): + pass + + +# ******************** Translation public functions ******************** + +def translate_im_model_to_sol006(im_model_data): + _validate_im_model(im_model_data) + descriptor_type = _get_im_model_descriptor_type(im_model_data) + if descriptor_type == "vnfd": + return translate_im_vnfd_to_sol006(im_model_data) + if descriptor_type == "nsd": + return translate_im_nsd_to_sol006(im_model_data) + # For sanity, should not happen + raise TranslationException("Error in translation: cannot determine the type of OSM-IM descriptor. Found {}, " + "expected one of: vnfd:vnfd-catalog, vnfd-catalog, nsd:nsd-catalog, nsd-catalog." + .format(descriptor_type)) + + +def translate_im_vnfd_to_sol006(im_vnfd): + im_vnfd = _remove_im_vnfd_envelope(im_vnfd) + sol006_vnfd = {} + _add_im_vnfd_basic_data_to_sol006_vnfd(im_vnfd, sol006_vnfd) + _add_im_vnfd_mgmt_interface_cp_to_sol006_vnfd(im_vnfd, sol006_vnfd) + _add_im_vdu_flavors_to_sol006_vnfd(im_vnfd, sol006_vnfd) + _add_im_vdu_guest_epa_to_sol006_vnfd(im_vnfd, sol006_vnfd) + _add_im_vdu_images_to_sol006_vnfd(im_vnfd, sol006_vnfd) + _add_im_vdus_to_sol006_vnfd(im_vnfd, sol006_vnfd) + _add_im_internal_vlds_to_sol006_vfnd(im_vnfd, sol006_vnfd) + _add_im_vnf_configuration_to_sol006_vnfd(im_vnfd, sol006_vnfd) + _add_im_ip_profiles_to_sol006_vnfd(im_vnfd, sol006_vnfd) + _add_im_vdu_monitoring_params_to_sol006_vnfd(im_vnfd, sol006_vnfd) + _add_im_scaling_group_descriptors_to_sol006_vnfd(im_vnfd, sol006_vnfd) + _add_im_kdus_to_sol006_vnfd(im_vnfd, sol006_vnfd) + _add_im_k8s_clusters_to_sol006_vnfd(im_vnfd, sol006_vnfd) + _add_im_placement_groups_to_sol006_vnfd(im_vnfd, sol006_vnfd) + return {"vnfd": sol006_vnfd} + + +def translate_im_nsd_to_sol006(im_nsd): + im_nsd = _remove_im_nsd_envelope(im_nsd) + sol006_nsd = {} + _add_im_nsd_basic_data_to_sol006_nsd(im_nsd, sol006_nsd) + _add_im_constituent_vnfds_to_sol006_nsd(im_nsd, sol006_nsd) + _add_im_vlds_to_sol006_nsd(im_nsd, sol006_nsd) + return {"nsd": {"nsd": [sol006_nsd]}} + + +# ******************** Common translation private functions ******************** + +def _validate_im_model(im_model_data): + descriptor_type = _get_im_model_descriptor_type(im_model_data) + try: + Validation().pyangbind_validation(descriptor_type, im_model_data) + except ValidationException as e: + raise TranslationException("Error on input model validation: {}".format(str(e))) + + +def _get_im_model_descriptor_type(im_model_data): + data_root = list(im_model_data.keys())[0] + if "vnfd" in data_root: + return "vnfd" + if "nsd" in data_root: + return "nsd" + raise TranslationException("Error in translation: cannot determine the type of OSM-IM descriptor. Found {}, " + "expected one of: vnfd:vnfd-catalog, vnfd-catalog, nsd:nsd-catalog, nsd-catalog." + .format(data_root)) + + +# ******************** VNFD translation private functions ******************** + +def _remove_im_vnfd_envelope(im_vnfd): + # Data is wrapped as { vnfd-catalog: { vnfd: [ ] } } + return list(im_vnfd.values())[0]["vnfd"][0] + + +def _add_im_vnfd_basic_data_to_sol006_vnfd(im_vnfd, sol006_vnfd): + sol006_vnfd["id"] = im_vnfd["id"] + if im_vnfd.get("name"): + sol006_vnfd["product-name"] = im_vnfd["name"] + if im_vnfd.get("description"): + sol006_vnfd["description"] = im_vnfd["description"] + if im_vnfd.get("vendor"): + sol006_vnfd["provider"] = im_vnfd["vendor"] + if im_vnfd.get("version"): + sol006_vnfd["version"] = im_vnfd["version"] + + +def _add_im_vnfd_mgmt_interface_cp_to_sol006_vnfd(im_vnfd, sol006_vnfd): + sol006_vnfd["mgmt-cp"] = "{}-ext".format(im_vnfd["mgmt-interface"]["cp"]) + + +def _add_im_vdu_flavors_to_sol006_vnfd(im_vnfd, sol006_vnfd): + storage_descriptors = [] + compute_descriptors = [] + for vdu in im_vnfd.get("vdu", ()): + vdu_id = vdu.get("id") + vdu_flavor = vdu.get("vm-flavor") + if not vdu_flavor: + continue + storage_descriptor = {"id": "{}-storage".format(vdu_id)} + compute_descriptor = {"id": "{}-compute".format(vdu_id)} + if vdu_flavor.get("storage-gb"): + storage_descriptor["size-of-storage"] = int(vdu_flavor["storage-gb"]) + storage_descriptors.append(storage_descriptor) + if vdu_flavor.get("vcpu-count"): + compute_descriptor["virtual-cpu"] = {"num-virtual-cpu": int(vdu_flavor["vcpu-count"])} + if vdu_flavor.get("memory-mb"): + compute_descriptor["virtual-memory"] = {"size": float(vdu_flavor["memory-mb"]) / 1024.0} + if len(compute_descriptor) > 1: + compute_descriptors.append(compute_descriptor) + if len(storage_descriptors) > 0: + sol006_vnfd["virtual-storage-desc"] = storage_descriptors + if len(compute_descriptors) > 0: + sol006_vnfd["virtual-compute-desc"] = compute_descriptors + + +def _add_im_vdu_guest_epa_to_sol006_vnfd(im_vnfd, sol006_vnfd): + for vdu in im_vnfd.get("vdu", ()): + vdu_guest_epa = vdu.get("guest-epa") + if not vdu_guest_epa: + continue + + _add_im_vdu_guest_epa_memory_and_cpu_to_sol006_vnfd(vdu, sol006_vnfd) + _add_im_vdu_guest_epa_disk_io_to_sol006_vnfd(vdu, sol006_vnfd) + + +def _add_im_vdu_guest_epa_memory_and_cpu_to_sol006_vnfd(im_vdu, sol006_vnfd): + vdu_guest_epa = im_vdu.get("guest-epa") + virtual_memory = _get_virtual_memory_from_im_vdu_guest_epa(vdu_guest_epa) + virtual_cpu = _get_virtual_cpu_from_im_vdu_guest_epa(vdu_guest_epa) + # Find this vdu compute descriptor and update it with the EPA options. If the + # vdu compute descriptor does not exist, create one with the EPA options only. + compute_descriptor_id = "{}-compute".format(im_vdu["id"]) + compute_descriptor = {"id": compute_descriptor_id} + compute_descriptor_found = False + for vcd in sol006_vnfd.get("virtual-compute-desc", ()): + if vcd.get("id") == compute_descriptor_id: + compute_descriptor = vcd + compute_descriptor_found = True + + compute_descriptor_virtual_memory = compute_descriptor.get("virtual-memory", {}) + compute_descriptor_virtual_cpu = compute_descriptor.get("virtual-cpu", {}) + compute_descriptor_virtual_memory.update(virtual_memory) + compute_descriptor_virtual_cpu.update(virtual_cpu) + if compute_descriptor_virtual_memory: + compute_descriptor["virtual-memory"] = compute_descriptor_virtual_memory + if compute_descriptor_virtual_cpu: + compute_descriptor["virtual-cpu"] = compute_descriptor_virtual_cpu + + if not compute_descriptor_found: + if sol006_vnfd.get("virtual-compute-desc"): + sol006_vnfd["virtual-compute-desc"].append(compute_descriptor) + else: + sol006_vnfd["virtual-compute-desc"] = [compute_descriptor] + + +def _add_im_vdu_guest_epa_disk_io_to_sol006_vnfd(im_vdu, sol006_vnfd): + vdu_guest_epa = im_vdu.get("guest-epa") + disk_io_quota = vdu_guest_epa.get("disk-io-quota", {}) + if not disk_io_quota: + return + # Find this vdu storage descriptor and update it with the EPA options. If the + # vdu storage descriptor does not exist, create one with the EPA options only. + storage_descriptor_id = "{}-storage".format(im_vdu["id"]) + storage_descriptor = {"id": storage_descriptor_id} + storage_descriptor_found = False + for vsd in sol006_vnfd.get("virtual-storage-desc", ()): + if vsd.get("id") == storage_descriptor_id: + storage_descriptor = vsd + storage_descriptor_found = True + + storage_descriptor["disk-io-quota"] = disk_io_quota + if not storage_descriptor_found: + if sol006_vnfd.get("virtual-storage-desc"): + sol006_vnfd["virtual-storage-desc"].append(storage_descriptor) + else: + sol006_vnfd["virtual-storage-desc"] = [storage_descriptor] + + +def _get_virtual_memory_from_im_vdu_guest_epa(im_vdu_guest_epa): + virtual_memory = {} + if im_vdu_guest_epa.get("mempage-size"): + virtual_memory["mempage-size"] = im_vdu_guest_epa["mempage-size"] + if im_vdu_guest_epa.get("numa-node-policy"): + virtual_memory["numa-enabled"] = True + virtual_memory["numa-node-policy"] = im_vdu_guest_epa["numa-node-policy"] + if im_vdu_guest_epa.get("mem-quota"): + virtual_memory["mem-quota"] = im_vdu_guest_epa["mem-quota"] + return virtual_memory + + +def _get_virtual_cpu_from_im_vdu_guest_epa(im_vdu_guest_epa): + virtual_cpu = {} + if im_vdu_guest_epa.get("cpu-pinning-policy") or im_vdu_guest_epa.get("cpu-thread-pinning-policy"): + virtual_cpu["pinning"] = {} + if im_vdu_guest_epa.get("cpu-pinning-policy"): + if im_vdu_guest_epa["cpu-pinning-policy"] == "SHARED": + virtual_cpu["pinning"]["policy"] = "dynamic" + else: + virtual_cpu["pinning"]["policy"] = "static" + if im_vdu_guest_epa.get("cpu-thread-pinning-policy"): + virtual_cpu["pinning"]["thread-policy"] = im_vdu_guest_epa["cpu-thread-pinning-policy"] + if im_vdu_guest_epa.get("cpu-quota"): + virtual_cpu["cpu-quota"] = im_vdu_guest_epa["cpu-quota"] + return virtual_cpu + + +def _add_im_vdu_images_to_sol006_vnfd(im_vnfd, sol006_vnfd): + image_descriptors = [] + all_images = set() # To avoid duplicated images + for vdu in im_vnfd.get("vdu", ()): + vdu_image = vdu.get("image") + if vdu_image and vdu_image not in all_images: + image_descriptors.append({"id": vdu_image, "name": vdu_image, "image": vdu_image}) + all_images.add(vdu_image) + for alternative_image in vdu.get("alternative-images", ()): + alt_image = alternative_image.get("image") + alt_image_descriptor = {"id": alt_image, "name": alt_image, "image": alt_image} + if alternative_image.get("vim-type"): + alt_image_descriptor["vim-type"] = alternative_image["vim-type"] + if alt_image not in all_images: + image_descriptors.append(alt_image_descriptor) + all_images.add(alt_image) + + if len(image_descriptors) > 0: + sol006_vnfd["sw-image-desc"] = image_descriptors + + +def _add_im_vdus_to_sol006_vnfd(im_vnfd, sol006_vnfd): + vdus = [] + ext_cpds = [] + vdu_configurations = [] + df_instantiation_level = {"id": "default-instantiation-level", "vdu-level": []} + df = {"id": "default-df", "vdu-profile": [], "instantiation-level": [df_instantiation_level]} + for vdu in im_vnfd.get("vdu", ()): + vdu_descriptor = {"id": vdu["id"]} + if vdu.get("description"): + vdu_descriptor["description"] = vdu["description"] + if vdu.get("name"): + vdu_descriptor["name"] = vdu["name"] + if vdu.get("cloud-init-file"): + vdu_descriptor["cloud-init-file"] = vdu["cloud-init-file"] + if vdu.get("supplemental-boot-data"): + vdu_descriptor["supplemental-boot-data"] = vdu["supplemental-boot-data"] + if vdu.get("alarm"): + vdu_descriptor["alarm"] = vdu["alarm"] + if vdu.get("pdu-type"): + vdu_descriptor["pdu-type"] = vdu["pdu-type"] + + _add_im_vdu_images_to_sol006_vdu(vdu, vdu_descriptor) + _add_im_vdu_flavor_to_sol006_vdu(vdu, vdu_descriptor) + + vdu_int_cpds, vdu_ext_cpds = _get_int_and_ext_cpds_from_im_vdu(vdu, im_vnfd) + vdu_descriptor["int-cpd"] = vdu_int_cpds + ext_cpds.extend(vdu_ext_cpds) + + vdu_profile = _get_vdu_profile_from_im_vdu(vdu, im_vnfd) + vdu_level = _get_instantiation_level_vdu_level_from_im_vdu(vdu) + if vdu.get("vdu-configuration"): + vdu_configuration = vdu["vdu-configuration"] + vdu_configuration["id"] = "{}-vdu-configuration".format(vdu["id"]) + vdu_configurations.append(vdu_configuration) + df["vdu-profile"].append(vdu_profile) + df["instantiation-level"][0]["vdu-level"].append(vdu_level) + + vdus.append(vdu_descriptor) + + if len(vdus) > 0: + sol006_vnfd["vdu"] = vdus + sol006_vnfd["df"] = [df] + if len(ext_cpds) > 0: + sol006_vnfd["ext-cpd"] = ext_cpds + if len(vdu_configurations) > 0: + sol006_vnfd["vdu-configuration"] = vdu_configurations + + +def _add_im_vdu_images_to_sol006_vdu(im_vdu, sol006_vdu): + if im_vdu.get("image"): + sol006_vdu["sw-image-desc"] = im_vdu["image"] + alternative_images = [] + for alternative_image in im_vdu.get("alternative-images", ()): + alternative_images.append(alternative_image.get("image")) + if len(alternative_images) > 0: + sol006_vdu["alternative-sw-image-desc"] = alternative_images + + +def _add_im_vdu_flavor_to_sol006_vdu(im_vdu, sol006_vdu): + vdu_flavor = im_vdu.get("vm-flavor") + if vdu_flavor: + if vdu_flavor.get("vcpu-count") or vdu_flavor.get("memory-mb"): + sol006_vdu["virtual-compute-desc"] = "{}-compute".format(im_vdu["id"]) + if vdu_flavor.get("storage-gb"): + sol006_vdu["virtual-storage-desc"] = ["{}-storage".format(im_vdu["id"])] + + +def _get_int_and_ext_cpds_from_im_vdu(im_vdu, im_vnfd): + int_cpds = [] + ext_cpds = [] + for interface in im_vdu.get("interface", ()): + int_cpd = {"id": "{}-int".format(interface["name"])} + virtual_network_interface_requirement = {"name": interface["name"]} + if interface.get("virtual-interface"): + virtual_network_interface_requirement["virtual-interface"] = interface["virtual-interface"] + if "position" in interface: + virtual_network_interface_requirement["position"] = int(interface["position"]) + int_cpd["virtual-network-interface-requirement"] = [virtual_network_interface_requirement] + if interface.get("external-connection-point-ref"): + ext_cpd = { + "id": "{}-ext".format(interface["external-connection-point-ref"]), + "int-cpd": { + "vdu-id": im_vdu["id"], + "cpd": int_cpd["id"] + } + } + for cp in im_vnfd.get("connection-point", ()): + if cp.get("name", "") != interface["external-connection-point-ref"]: + continue + if "port-security-enabled" in cp: + ext_cpd["port-security-enabled"] = cp["port-security-enabled"] + if cp.get("port-security-disable-strategy"): + ext_cpd["port-security-disable-strategy"] = cp["port-security-disable-strategy"] + ext_cpds.append(ext_cpd) + + int_cpds.append(int_cpd) + + return int_cpds, ext_cpds + + +def _get_vdu_profile_from_im_vdu(im_vdu, im_vnfd): + vdu_profile = {"id": im_vdu["id"]} + initial_instances = int(im_vdu.get("count", 1)) + vdu_profile["min-number-of-instances"] = initial_instances + for scaling_group_descriptor in im_vnfd.get("scaling-group-descriptor", ()): + for sgd_vdu in scaling_group_descriptor.get("vdu", []): + if sgd_vdu.get("vdu-id-ref") == im_vdu["id"]: + sgd_max_instances = int(scaling_group_descriptor.get("max-instance-count", 1)) + sgd_min_instances = int(scaling_group_descriptor.get("min-instance-count", 0)) + vdu_profile["min-number-of-instances"] = sgd_min_instances + initial_instances + vdu_profile["max-number-of-instances"] = sgd_max_instances + initial_instances + if im_vdu.get("vdu-configuration"): + vdu_profile["vdu-configuration-id"] = "{}-vdu-configuration".format(im_vdu["id"]) + return vdu_profile + + +def _get_instantiation_level_vdu_level_from_im_vdu(im_vdu): + vdu_level = {"vdu-id": im_vdu["id"]} + vdu_level["number-of-instances"] = int(im_vdu.get("count", 1)) + return vdu_level + + +def _add_im_internal_vlds_to_sol006_vfnd(im_vnfd, sol006_vnfd): + int_virtual_link_descs = [] + for ivld in im_vnfd.get("internal-vld", ()): + int_virtual_link_desc = {"id": ivld["id"]} + _add_im_internal_vld_connection_point_refs_to_sol006_vnfd(ivld, im_vnfd, sol006_vnfd) + + int_virtual_link_descs.append(int_virtual_link_desc) + + if len(int_virtual_link_descs) > 0: + sol006_vnfd["int-virtual-link-desc"] = int_virtual_link_descs + + +def _add_im_internal_vld_connection_point_refs_to_sol006_vnfd(ivld, im_vnfd, sol006_vnfd): + all_int_cp_refs_interfaces = {} + for vdu in im_vnfd.get("vdu", ()): + for interface in vdu.get("interface", ()): + int_cp_ref = interface.get("internal-connection-point-ref") + if not int_cp_ref: + continue + all_int_cp_refs_interfaces[int_cp_ref] = (vdu["id"], interface["name"]) + + for int_cp in ivld.get("internal-connection-point", ()): + int_cp_ref = int_cp["id-ref"] + (vdu_id, interface_name) = all_int_cp_refs_interfaces[int_cp_ref] + sol006_int_cpd_id = "{}-int".format(interface_name) + # Search for this int_cp on sol006_vnfd and update it + for vdu in sol006_vnfd.get("vdu", ()): + if vdu["id"] != vdu_id: + continue + for int_cpd in vdu.get("int-cpd", ()): + if int_cpd["id"] == sol006_int_cpd_id: + int_cpd["int-virtual-link-desc"] = ivld["id"] + + +def _add_im_vnf_configuration_to_sol006_vnfd(im_vnfd, sol006_vnfd): + vnf_configuration = im_vnfd.get("vnf-configuration") + if not vnf_configuration: + return + vnf_configuration["id"] = "default-vnf-configuration" + sol006_vnfd["vnf-configuration"] = [vnf_configuration] + sol006_vnfd["df"][0]["vnf-configuration-id"] = vnf_configuration["id"] + + +def _add_im_ip_profiles_to_sol006_vnfd(im_vnfd, sol006_vnfd): + all_ivlds_ip_profiles = {} + for ivld in im_vnfd.get("internal-vld", ()): + if ivld.get("ip-profile-ref"): + all_ivlds_ip_profiles[ivld["ip-profile-ref"]] = ivld["id"] + + virtual_link_profiles = [] + for ip_profile in im_vnfd.get("ip-profiles", ()): + virtual_link_profile = {"id": all_ivlds_ip_profiles[ip_profile["name"]], "flavour": ""} + ip_profile_params = ip_profile.get("ip-profile-params") + if ip_profile_params: + l3_protocol_data = {"name": "{}-l3-protocol-data".format(virtual_link_profile["id"])} + if ip_profile_params.get("ip-version"): + l3_protocol_data["ip-version"] = ip_profile_params["ip-version"] + if ip_profile_params.get("subnet-address"): + l3_protocol_data["cidr"] = ip_profile_params["subnet-address"] + if ip_profile_params.get("gateway-address"): + l3_protocol_data["gateway-ip"] = ip_profile_params["gateway-address"] + if ip_profile_params.get("security-group"): + l3_protocol_data["security-group"] = ip_profile_params["security-group"] + if ip_profile_params.get("dhcp-params", {}).get("enabled"): + l3_protocol_data["dhcp-enabled"] = ip_profile_params["dhcp-params"]["enabled"] + if ip_profile.get("description"): + l3_protocol_data["description"] = ip_profile["description"] + + virtual_link_profile["virtual-link-protocol-data"] = {"l3-protocol-data": l3_protocol_data} + + virtual_link_profiles.append(virtual_link_profile) + + if len(virtual_link_profiles) > 0: + sol006_vnfd["df"][0]["virtual-link-profile"] = virtual_link_profiles + + +def _add_im_vdu_monitoring_params_to_sol006_vnfd(im_vnfd, sol006_vnfd): + all_vdu_monitoring_param_metrics = {} + for vdu in im_vnfd.get("vdu", ()): + for monitoring_param in vdu.get("monitoring-param", ()): + monitoring_param_metric = monitoring_param.get("nfvi-metric") + if monitoring_param_metric: + all_vdu_monitoring_param_metrics[(vdu["id"], monitoring_param["id"])] = monitoring_param_metric + + for monitoring_param in im_vnfd.get("monitoring-param", ()): + sol006_mp = {"id": monitoring_param["id"]} + if monitoring_param.get("name"): + sol006_mp["name"] = monitoring_param["name"] + if monitoring_param.get("vdu-monitoring-param"): + monitoring_param_vdu_id = monitoring_param["vdu-monitoring-param"].get("vdu-ref") + monitoring_param_id = monitoring_param["vdu-monitoring-param"].get("vdu-monitoring-param-ref") + metric = all_vdu_monitoring_param_metrics.get((monitoring_param_vdu_id, monitoring_param_id)) + if metric: + sol006_mp["performance-metric"] = metric + # Find that vdu inside sol006_vnfd and update its monitoring-parameter list + for vdu in sol006_vnfd.get("vdu", ()): + if vdu["id"] != monitoring_param_vdu_id: + continue + if vdu.get("monitoring-parameter"): + vdu["monitoring-parameter"].append(sol006_mp) + else: + vdu["monitoring-parameter"] = [sol006_mp] + + +def _add_im_scaling_group_descriptors_to_sol006_vnfd(im_vnfd, sol006_vnfd): + scaling_aspects = [] + for scaling_group_descriptor in im_vnfd.get("scaling-group-descriptor", ()): + scaling_aspect = {"id": scaling_group_descriptor["name"], "name": scaling_group_descriptor["name"]} + if scaling_group_descriptor.get("max-instance-count"): + scaling_aspect["max-scale-level"] = int(scaling_group_descriptor["max-instance-count"]) + if scaling_group_descriptor.get("scaling-policy"): + scaling_aspect["scaling-policy"] = scaling_group_descriptor["scaling-policy"] + if scaling_group_descriptor.get("scaling-config-action"): + scaling_aspect["scaling-config-action"] = scaling_group_descriptor["scaling-config-action"] + + delta = {"id": "{}-delta".format(scaling_aspect["id"])} + vdu_deltas = [] + for vdu in scaling_group_descriptor.get("vdu", ()): + vdu_delta = {} + if vdu.get("count"): + vdu_delta["number-of-instances"] = int(vdu["count"]) + if vdu.get("vdu-id-ref"): + vdu_delta["id"] = vdu["vdu-id-ref"] + vdu_deltas.append(vdu_delta) + if len(vdu_deltas) > 0: + delta["vdu-delta"] = vdu_deltas + scaling_aspect["aspect-delta-details"] = {"deltas": [delta]} + + scaling_aspects.append(scaling_aspect) + + if len(scaling_aspects) > 0: + sol006_vnfd["df"][0]["scaling-aspect"] = scaling_aspects + + +def _add_im_kdus_to_sol006_vnfd(im_vnfd, sol006_vnfd): + if im_vnfd.get("kdu"): + sol006_vnfd["kdu"] = im_vnfd["kdu"] + if len(sol006_vnfd.get("df", ())) == 0: + sol006_vnfd["df"] = [{"id": "default-df"}] + + +def _add_im_k8s_clusters_to_sol006_vnfd(im_vnfd, sol006_vnfd): + im_k8s_cluster = im_vnfd.get("k8s-cluster") + if not im_k8s_cluster: + return + + sol006_k8s_cluster = {} + if im_k8s_cluster.get("version"): + sol006_k8s_cluster["version"] = im_k8s_cluster["version"] + if im_k8s_cluster.get("cni"): + sol006_k8s_cluster["cni"] = im_k8s_cluster["cni"] + + nets = [] + k8s_cluster_ext_cpds = [] + for net in im_k8s_cluster.get("nets", ()): + if net.get("external-connection-point-ref"): + ext_cpd = {"id": "{}-ext".format(net["external-connection-point-ref"]), "k8s-cluster-net": net["id"]} + k8s_cluster_ext_cpds.append(ext_cpd) + nets.append({"id": net["id"]}) + if len(nets) > 0: + sol006_k8s_cluster["nets"] = nets + + sol006_vnfd["k8s-cluster"] = sol006_k8s_cluster + if len(k8s_cluster_ext_cpds) > 0: + if not sol006_vnfd.get("ext-cpd"): + sol006_vnfd["ext-cpd"] = [] + sol006_vnfd["ext-cpd"].extend(k8s_cluster_ext_cpds) + + +def _add_im_placement_groups_to_sol006_vnfd(im_vnfd, sol006_vnfd): + if im_vnfd.get("placement-groups"): + sol006_vnfd["placement-groups"] = im_vnfd["placement-groups"] + + +# ******************** NSD translation private functions ******************** + +def _remove_im_nsd_envelope(im_nsd): + # Data is wrapped as { nsd-catalog: { nsd: [ ] } } + return list(im_nsd.values())[0]["nsd"][0] + + +def _add_im_nsd_basic_data_to_sol006_nsd(im_nsd, sol006_nsd): + sol006_nsd["id"] = im_nsd["id"] + if im_nsd.get("name"): + sol006_nsd["name"] = im_nsd["name"] + if im_nsd.get("description"): + sol006_nsd["description"] = im_nsd["description"] + if im_nsd.get("vendor"): + sol006_nsd["designer"] = im_nsd["vendor"] + if im_nsd.get("version"): + sol006_nsd["version"] = im_nsd["version"] + + +def _add_im_constituent_vnfds_to_sol006_nsd(im_nsd, sol006_nsd): + vnfd_ids = set() + for constituent_vnfd in im_nsd.get("constituent-vnfd", ()): + if constituent_vnfd.get("vnfd-id-ref"): + vnfd_ids.add(constituent_vnfd["vnfd-id-ref"]) + + if len(vnfd_ids) > 0: + sol006_nsd["vnfd-id"] = list(vnfd_ids) + + +def _add_im_vlds_to_sol006_nsd(im_nsd, sol006_nsd): + vlds = im_nsd.get("vld", []) + flattened_vlds = [{**vld, **cp_ref} for vld in vlds for cp_ref in vld.get("vnfd-connection-point-ref", ())] + all_vlds_by_member_vnf_index = {} + for vld in flattened_vlds: + member_vnf_index = str(vld.get("member-vnf-index-ref", "")) + if member_vnf_index in all_vlds_by_member_vnf_index: + all_vlds_by_member_vnf_index[member_vnf_index].append(vld) + else: + all_vlds_by_member_vnf_index[member_vnf_index] = [vld] + + df = {"id": "default-df", "vnf-profile": []} + + for member_vnf_index in all_vlds_by_member_vnf_index: + vnf_profile = {"id": member_vnf_index} + vnf_profile["vnfd-id"] = all_vlds_by_member_vnf_index.get(member_vnf_index, [{}])[0].get("vnfd-id-ref") + vnf_profile["virtual-link-connectivity"] = [] + for vld in all_vlds_by_member_vnf_index[member_vnf_index]: + virtual_link_connectivity = {"virtual-link-profile-id": vld["id"]} + virtual_link_connectivity["constituent-cpd-id"] = [{ + "constituent-base-element-id": member_vnf_index, + "constituent-cpd-id": "{}-ext".format(vld.get("vnfd-connection-point-ref")) + }] + if vld.get("ip-address"): + virtual_link_connectivity["constituent-cpd-id"][0]["ip-address"] = vld["ip-address"] + vnf_profile["virtual-link-connectivity"].append(virtual_link_connectivity) + + vlcs_by_virtual_link_profile = {} + for vlc in vnf_profile.get("virtual-link-connectivity"): + vl_profile_id = vlc.get("virtual-link-profile-id") + if vl_profile_id in vlcs_by_virtual_link_profile: + vlc_constituent_cpds = vlcs_by_virtual_link_profile[vl_profile_id].get("constituent-cpd-id") + vlc_constituent_cpds.extend(vlc.get("constituent-cpd-id")) + else: + vlcs_by_virtual_link_profile[vl_profile_id] = vlc + + vnf_profile["virtual-link-connectivity"] = list(vlcs_by_virtual_link_profile.values()) + + df["vnf-profile"].append(vnf_profile) + + sol006_nsd["df"] = [df] + + virtual_link_descs = [] + for vld in im_nsd.get("vld", ()): + virtual_link_desc = {"id": vld["id"]} + if vld.get("mgmt-network"): + virtual_link_desc["mgmt-network"] = vld["mgmt-network"] + if vld.get("vim-network-name"): + virtual_link_desc["vim-network-name"] = vld["vim-network-name"] + virtual_link_descs.append(virtual_link_desc) + + if len(virtual_link_descs) > 0: + sol006_nsd["virtual-link-desc"] = virtual_link_descs diff --git a/tests/examples/alternative_image_sol006.yaml b/tests/examples/alternative_image_sol006.yaml index 446eae4..74ffe93 100644 --- a/tests/examples/alternative_image_sol006.yaml +++ b/tests/examples/alternative_image_sol006.yaml @@ -18,60 +18,57 @@ vnfd: product-name: hackfest_basic-vnf description: A basic VNF descriptor w/ one VDU version: "1.0" - mgmt-cp: vnf-cp0 + mgmt-cp: vnf-cp0-ext virtual-compute-desc: - - id: cirros-compute + - id: hackfest_basic-VM-compute virtual-cpu: num-virtual-cpu: 1 virtual-memory: size: 1 # Memory size in GB virtual-storage-desc: - - id: cirros-storage + - id: hackfest_basic-VM-storage size-of-storage: 10 sw-image-desc: - id: ubuntu1604 name: ubuntu1604 - checksum: - hash: # Mandatory? - - id: ubuntu1604-aws - name: ubuntu1604-aws + image: ubuntu1604 + - id: ubuntu/images/hvm-ssd/ubuntu-artful-17.10-amd64-server-20180509 + name: ubuntu/images/hvm-ssd/ubuntu-artful-17.10-amd64-server-20180509 image: ubuntu/images/hvm-ssd/ubuntu-artful-17.10-amd64-server-20180509 vim-type: aws - checksum: - hash: # Mandatory? vdu: - id: hackfest_basic-VM name: hackfest_basic-VM - virtual-compute-desc: cirros-compute + virtual-compute-desc: hackfest_basic-VM-compute virtual-storage-desc: - - cirros-storage + - hackfest_basic-VM-storage sw-image-desc: ubuntu1604 alternative-sw-image-desc: - - ubuntu1604-aws + - ubuntu/images/hvm-ssd/ubuntu-artful-17.10-amd64-server-20180509 int-cpd: - - id: eth0-int + - id: vdu-eth0-int virtual-network-interface-requirement: - name: vdu-eth0 virtual-interface: type: PARAVIRT df: - - id: cirros_default + - id: default-df vdu-profile: - id: hackfest_basic-VM min-number-of-instances: 1 instantiation-level: - - id: default + - id: default-instantiation-level vdu-level: - vdu-id: hackfest_basic-VM number-of-instances: 1 ext-cpd: - - id: vnf-cp0 + - id: vnf-cp0-ext int-cpd: # Connection to int-cpd vdu-id: hackfest_basic-VM - cpd: eth0-int + cpd: vdu-eth0-int diff --git a/tests/examples/cirros_nsd_im.yaml b/tests/examples/cirros_nsd_im.yaml index dcc832b..7279394 100644 --- a/tests/examples/cirros_nsd_im.yaml +++ b/tests/examples/cirros_nsd_im.yaml @@ -16,9 +16,9 @@ nsd:nsd-catalog: nsd: - id: cirros_2vnf_nsd - name: cirros_2vnf_ns + name: cirros_2vnf_nsd short-name: cirros_2vnf_ns - description: Generated by OSM pacakage generator + description: Generated by OSM package generator vendor: OSM version: "1.0" diff --git a/tests/examples/cirros_nsd_sol006.yaml b/tests/examples/cirros_nsd_sol006.yaml index ee279ca..9175bdd 100644 --- a/tests/examples/cirros_nsd_sol006.yaml +++ b/tests/examples/cirros_nsd_sol006.yaml @@ -28,19 +28,19 @@ nsd: mgmt-network: "true" df: - - id: cirros_DF + - id: default-df vnf-profile: - - id: cirros_vnf1 # member-vnf-index-ref: 1 + - id: "1" # member-vnf-index-ref: 1 vnfd-id: cirros_vnfd virtual-link-connectivity: - virtual-link-profile-id: cirros_2vnf_nsd_vld1 constituent-cpd-id: - - constituent-base-element-id: cirros_vnf1 + - constituent-base-element-id: "1" constituent-cpd-id: eth0-ext - - id: cirros_vnf2 # member-vnf-index-ref: 2 + - id: "2" # member-vnf-index-ref: 2 vnfd-id: cirros_vnfd virtual-link-connectivity: - virtual-link-profile-id: cirros_2vnf_nsd_vld1 constituent-cpd-id: - - constituent-base-element-id: cirros_vnf2 + - constituent-base-element-id: "2" constituent-cpd-id: eth0-ext diff --git a/tests/examples/cirros_vnfd_sol006.yaml b/tests/examples/cirros_vnfd_sol006.yaml index 9ecdd7b..84489a3 100644 --- a/tests/examples/cirros_vnfd_sol006.yaml +++ b/tests/examples/cirros_vnfd_sol006.yaml @@ -22,27 +22,28 @@ vnfd: mgmt-cp: eth0-ext virtual-compute-desc: - - id: cirros-compute + - id: cirros_vnfd-VM-compute virtual-cpu: num-virtual-cpu: 1 virtual-memory: - size: 0.256 # Memory size in GB + size: 0.25 # Memory size in GB virtual-storage-desc: - - id: cirros-storage + - id: cirros_vnfd-VM-storage size-of-storage: 2 sw-image-desc: - id: cirros034 name: cirros034 + image: cirros034 vdu: - id: cirros_vnfd-VM name: cirros_vnfd-VM description: cirros_vnfd-VM - virtual-compute-desc: cirros-compute + virtual-compute-desc: cirros_vnfd-VM-compute virtual-storage-desc: - - cirros-storage + - cirros_vnfd-VM-storage sw-image-desc: cirros034 int-cpd: - id: eth0-int @@ -54,12 +55,12 @@ vnfd: vpci: 0000:00:0a.0 df: - - id: cirros_default + - id: default-df vdu-profile: - id: cirros_vnfd-VM min-number-of-instances: 1 instantiation-level: - - id: default + - id: default-instantiation-level vdu-level: - vdu-id: cirros_vnfd-VM number-of-instances: 1 diff --git a/tests/examples/epa_im.yaml b/tests/examples/epa_im.yaml index f13d08b..cf25ac7 100644 --- a/tests/examples/epa_im.yaml +++ b/tests/examples/epa_im.yaml @@ -79,7 +79,7 @@ vnfd-catalog: virtual-interface: bandwidth: "1000000" type: PARAVIRT - vpci: 0000:00:0a.0 + vpci: "0000:00:0a.0" - external-connection-point-ref: xe0 name: xe0 position: "2" diff --git a/tests/examples/epa_sol006.yaml b/tests/examples/epa_sol006.yaml index 275cfcb..7a8ab73 100644 --- a/tests/examples/epa_sol006.yaml +++ b/tests/examples/epa_sol006.yaml @@ -14,7 +14,7 @@ # limitations under the License. vnfd: - id: epa-advanced-vnfd + id: vbng34 description: vBNG VNF for performance tests, with 34 HTs product-name: vbng34 provider: Intel @@ -23,142 +23,154 @@ vnfd: sw-image-desc: - id: intel_vbng34 name: intel_vbng34 + image: intel_vbng34 virtual-compute-desc: - - id: epa-compute + - id: vbng34-VM-compute virtual-cpu: pinning: # Generic key/value pairs policy: static thread-policy: PREFER virtual-memory: - size: 32 + size: 32.0 mempage-size: LARGE numa-enabled: true # Replaces NUMA aware/unaware choice numa-node-policy: mem-policy: STRICT node: - - id: "1" + - id: "0" paired-threads: num-paired-threads: "17" node-cnt: "1" virtual-storage-desc: - - id: epa-storage - size-of-storage: 10 + - id: vbng34-VM-storage + size-of-storage: 15 vdu: - - id: epa-vdu - name: epa-vdu + - id: vbng34-VM + name: vbng34-VM + description: vbng34-VM sw-image-desc: intel_vbng34 - virtual-compute-desc: epa-compute + virtual-compute-desc: vbng34-VM-compute virtual-storage-desc: - - epa-storage + - vbng34-VM-storage int-cpd: - - id: eth0 + - id: eth0-int virtual-network-interface-requirement: - name: eth0 position: 1 virtual-interface: type: PARAVIRT - bandwidth: 1000000 - vpci: 0000:00:0a.0 - - id: xe0 + bandwidth: "1000000" + vpci: "0000:00:0a.0" + - id: xe0-int virtual-network-interface-requirement: - name: xe0 position: 2 virtual-interface: type: PCI-PASSTHROUGH - bandwidth: 10000000000 - vpci: 0000:00:10.0 - - id: xe1 + bandwidth: "10000000000" + vpci: "0000:00:10.0" + - id: xe1-int virtual-network-interface-requirement: - name: xe1 position: 3 virtual-interface: type: PCI-PASSTHROUGH - bandwidth: 10000000000 - vpci: 0000:00:11.0 - - id: xe2 + bandwidth: "10000000000" + vpci: "0000:00:11.0" + - id: xe2-int virtual-network-interface-requirement: - name: xe2 position: 4 virtual-interface: type: PCI-PASSTHROUGH - bandwidth: 10000000000 - vpci: 0000:00:12.0 - - id: xe3 + bandwidth: "10000000000" + vpci: "0000:00:12.0" + - id: xe3-int virtual-network-interface-requirement: - name: xe3 position: 5 virtual-interface: type: PCI-PASSTHROUGH - bandwidth: 10000000000 - vpci: 0000:00:13.0 - - id: xe4 + bandwidth: "10000000000" + vpci: "0000:00:13.0" + - id: xe4-int virtual-network-interface-requirement: - name: xe4 position: 6 virtual-interface: type: PCI-PASSTHROUGH - bandwidth: 10000000000 - vpci: 0000:00:14.0 - - id: xe5 + bandwidth: "10000000000" + vpci: "0000:00:14.0" + - id: xe5-int virtual-network-interface-requirement: - name: xe5 position: 7 virtual-interface: type: PCI-PASSTHROUGH - bandwidth: 10000000000 - vpci: 0000:00:15.0 - - id: xe6 + bandwidth: "10000000000" + vpci: "0000:00:15.0" + - id: xe6-int virtual-network-interface-requirement: - name: xe6 position: 8 virtual-interface: type: PCI-PASSTHROUGH - bandwidth: 10000000000 - vpci: 0000:00:16.0 - - id: xe7 + bandwidth: "10000000000" + vpci: "0000:00:16.0" + - id: xe7-int virtual-network-interface-requirement: - name: xe7 position: 9 virtual-interface: - type: VIRTIO - bandwidth: 10000000000 - vpci: 0000:00:17.0 + type: PCI-PASSTHROUGH + bandwidth: "10000000000" + vpci: "0000:00:17.0" supplemental-boot-data: - boot-data-drive: false + boot-data-drive: "false" ext-cpd: - id: eth0-ext int-cpd: - vdu-id: epa-vdu - cpd: eth0 + vdu-id: vbng34-VM + cpd: eth0-int - id: xe0-ext int-cpd: - vdu-id: epa-vdu - cpd: xe0 + vdu-id: vbng34-VM + cpd: xe0-int - id: xe1-ext int-cpd: - vdu-id: epa-vdu - cpd: xe1 + vdu-id: vbng34-VM + cpd: xe1-int - id: xe2-ext int-cpd: - vdu-id: epa-vdu - cpd: xe2 + vdu-id: vbng34-VM + cpd: xe2-int - id: xe3-ext int-cpd: - vdu-id: epa-vdu - cpd: xe3 + vdu-id: vbng34-VM + cpd: xe3-int - id: xe4-ext int-cpd: - vdu-id: epa-vdu - cpd: xe4 + vdu-id: vbng34-VM + cpd: xe4-int - id: xe5-ext int-cpd: - vdu-id: epa-vdu - cpd: xe5 + vdu-id: vbng34-VM + cpd: xe5-int - id: xe6-ext int-cpd: - vdu-id: epa-vdu - cpd: xe6 + vdu-id: vbng34-VM + cpd: xe6-int - id: xe7-ext int-cpd: - vdu-id: epa-vdu - cpd: xe7 \ No newline at end of file + vdu-id: vbng34-VM + cpd: xe7-int + df: + - id: default-df + instantiation-level: + - id: default-instantiation-level + vdu-level: + - number-of-instances: 1 + vdu-id: vbng34-VM + vdu-profile: + - id: vbng34-VM + min-number-of-instances: 1 \ No newline at end of file diff --git a/tests/examples/hackfest_charmed_nsd_sol006.yaml b/tests/examples/hackfest_charmed_nsd_sol006.yaml index 0d6533e..2d2c726 100644 --- a/tests/examples/hackfest_charmed_nsd_sol006.yaml +++ b/tests/examples/hackfest_charmed_nsd_sol006.yaml @@ -18,7 +18,6 @@ nsd: - id: hackfest3charmed-ns name: hackfest3charmed-ns description: NS with 2 VNFs hackfest3charmed-vnf connected by datanet and mgmtnet VLs - designer: OSM version: '1.0' vnfd-id: @@ -26,32 +25,32 @@ nsd: virtual-link-desc: - id: mgmt - mgmt-network: "true" + mgmt-network: true + vim-network-name: mgmt - id: datanet - mgmt-network: "false" df: - - id: hackfest_charmed_DF + - id: default-df vnf-profile: - - id: hackfest_vnf1 # member-vnf-index-ref: 1 + - id: "1" # member-vnf-index-ref: 1 vnfd-id: hackfest3charmed-vnf virtual-link-connectivity: - virtual-link-profile-id: mgmt constituent-cpd-id: - - constituent-base-element-id: hackfest_vnf1 + - constituent-base-element-id: "1" constituent-cpd-id: vnf-mgmt-ext - virtual-link-profile-id: datanet constituent-cpd-id: - - constituent-base-element-id: hackfest_vnf1 + - constituent-base-element-id: "1" constituent-cpd-id: vnf-data-ext - - id: hackfest_vnf2 # member-vnf-index-ref: 2 + - id: "2" # member-vnf-index-ref: 2 vnfd-id: hackfest3charmed-vnf virtual-link-connectivity: - virtual-link-profile-id: mgmt constituent-cpd-id: - - constituent-base-element-id: hackfest_vnf2 + - constituent-base-element-id: "2" constituent-cpd-id: vnf-mgmt-ext - virtual-link-profile-id: datanet constituent-cpd-id: - - constituent-base-element-id: hackfest_vnf2 + - constituent-base-element-id: "2" constituent-cpd-id: vnf-data-ext \ No newline at end of file diff --git a/tests/examples/hackfest_charmed_vnfd_im.yaml b/tests/examples/hackfest_charmed_vnfd_im.yaml index f7828fe..ce288d6 100644 --- a/tests/examples/hackfest_charmed_vnfd_im.yaml +++ b/tests/examples/hackfest_charmed_vnfd_im.yaml @@ -41,8 +41,8 @@ vnfd:vnfd-catalog: cp: vnf-mgmt monitoring-param: - aggregation-type: AVERAGE - id: monitor1 - name: monitor1 + id: dataVM_cpu_util + name: dataVM_cpu_util vdu-monitoring-param: vdu-monitoring-param-ref: dataVM_cpu_util vdu-ref: dataVM @@ -64,8 +64,9 @@ vnfd:vnfd-catalog: scale-in-threshold: '15.0000000000' scale-out-relational-operation: GE scale-out-threshold: '60.0000000000' - vnf-monitoring-param-ref: monitor1 + vnf-monitoring-param-ref: dataVM_cpu_util scaling-type: automatic + enabled: true threshold-time: 0 vdu: - count: 1 diff --git a/tests/examples/hackfest_charmed_vnfd_sol006.yaml b/tests/examples/hackfest_charmed_vnfd_sol006.yaml index f73264f..069198b 100644 --- a/tests/examples/hackfest_charmed_vnfd_sol006.yaml +++ b/tests/examples/hackfest_charmed_vnfd_sol006.yaml @@ -23,43 +23,44 @@ vnfd: mgmt-cp: vnf-mgmt-ext virtual-compute-desc: - - id: mgmt-compute + - id: mgmtVM-compute virtual-cpu: num-virtual-cpu: 1 virtual-memory: size: 1 - - id: data-compute + - id: dataVM-compute virtual-cpu: num-virtual-cpu: 1 virtual-memory: size: 1 virtual-storage-desc: - - id: mgmt-storage + - id: mgmtVM-storage size-of-storage: 10 - - id: data-storage + - id: dataVM-storage size-of-storage: 10 sw-image-desc: - id: hackfest3-mgmt name: hackfest3-mgmt + image: hackfest3-mgmt vdu: - id: mgmtVM name: mgmtVM cloud-init-file: cloud-config.txt sw-image-desc: hackfest3-mgmt - virtual-compute-desc: mgmt-compute + virtual-compute-desc: mgmtVM-compute virtual-storage-desc: - - mgmt-storage + - mgmtVM-storage int-cpd: - - id: vnf-mgmt + - id: mgmtVM-eth0-int virtual-network-interface-requirement: - name: mgmtVM-eth0 position: 1 virtual-interface: type: VIRTIO - - id: mgmtVM-internal + - id: mgmtVM-eth1-int int-virtual-link-desc: internal virtual-network-interface-requirement: - name: mgmtVM-eth1 @@ -69,20 +70,20 @@ vnfd: - id: dataVM name: dataVM sw-image-desc: hackfest3-mgmt - virtual-compute-desc: data-compute + virtual-compute-desc: dataVM-compute virtual-storage-desc: - - data-storage + - dataVM-storage int-cpd: - - id: dataVM-internal + - id: dataVM-eth0-int int-virtual-link-desc: internal virtual-network-interface-requirement: - - name: dataVM-eth1 + - name: dataVM-eth0 position: 1 virtual-interface: type: VIRTIO - - id: vnf-data + - id: dataVM-xe0-int virtual-network-interface-requirement: - - name: dataVM-eth0 + - name: dataVM-xe0 position: 2 virtual-interface: type: VIRTIO @@ -98,24 +99,23 @@ vnfd: - id: vnf-mgmt-ext int-cpd: # Connection to int-cpd vdu-id: mgmtVM - cpd: vnf-mgmt + cpd: mgmtVM-eth0-int - id: vnf-data-ext int-cpd: # Connection to int-cpd vdu-id: dataVM - cpd: vnf-data + cpd: dataVM-xe0-int df: - - id: hackfest_default - vnf-configuration-id: vnf-configuration-example + - id: default-df + vnf-configuration-id: default-vnf-configuration vdu-profile: - id: mgmtVM min-number-of-instances: 1 - id: dataVM min-number-of-instances: 1 - max-number-of-instances: 10 - vdu-configuration-id: vdu-configuration-example + max-number-of-instances: 11 instantiation-level: - - id: default + - id: default-instantiation-level vdu-level: - vdu-id: mgmtVM number-of-instances: 1 @@ -127,9 +127,9 @@ vnfd: max-scale-level: 10 aspect-delta-details: deltas: - - id: delta1 + - id: scale_dataVM-delta vdu-delta: - - id: vdudelta1 + - id: dataVM number-of-instances: 1 scaling-policy: - name: auto_cpu_util_above_threshold @@ -151,7 +151,7 @@ vnfd: vnf-config-primitive-name-ref: touch vnf-configuration: - - id: vnf-configuration-example + - id: default-vnf-configuration initial-config-primitive: - seq: "1" name: config diff --git a/tests/examples/magma_knf_im.yaml b/tests/examples/magma_knf_im.yaml index feefeba..b2d9e10 100644 --- a/tests/examples/magma_knf_im.yaml +++ b/tests/examples/magma_knf_im.yaml @@ -33,3 +33,4 @@ vnfd-catalog: kdu: - name: orc8r helm-chart: magma/orc8r + description: Facebook magma orc8r diff --git a/tests/examples/magma_knf_sol006.yaml b/tests/examples/magma_knf_sol006.yaml index 228e3a4..1cb5298 100644 --- a/tests/examples/magma_knf_sol006.yaml +++ b/tests/examples/magma_knf_sol006.yaml @@ -14,22 +14,21 @@ # limitations under the License. vnfd: - id: fb_magma_knf - product-name: fb_magma_knf description: KNF with KDU using a helm-chart for Facebook magma orc8r - provider: ATOS - version: "1.0" - mgmt-cp: mgmt-ext - + df: + - id: default-df ext-cpd: - - id: mgmt-ext - k8s-cluster-net: mgmtnet - + - id: mgmt-ext + k8s-cluster-net: mgmtnet + id: fb_magma_knf k8s-cluster: nets: - - id: mgmtnet - + - id: mgmtnet kdu: - - name: orc8r - helm-chart: magma/orc8r - + - name: orc8r + helm-chart: magma/orc8r + description: Facebook magma orc8r + mgmt-cp: mgmt-ext + product-name: fb_magma_knf + provider: ATOS + version: '1.0' \ No newline at end of file diff --git a/tests/examples/vepc_im.yaml b/tests/examples/vepc_im.yaml index d816967..ea091b8 100644 --- a/tests/examples/vepc_im.yaml +++ b/tests/examples/vepc_im.yaml @@ -24,7 +24,7 @@ vnfd:vnfd-catalog: mgmt-interface: # To mgmt-cp cp: spgwmme-mgmt ip-profiles: # To deployment flavour (DF) - - name: s6a + - name: s6a-fefe description: s6a network ip-profile-params: ip-version: ipv4 @@ -124,7 +124,7 @@ vnfd:vnfd-catalog: charm: hsscharm internal-vld: - id: s6a - ip-profile-ref: s6a + ip-profile-ref: s6a-fefe internal-connection-point: - id-ref: spgwmme-s6a - id-ref: hss-s6a diff --git a/tests/examples/vepc_nsd_sol006.yaml b/tests/examples/vepc_nsd_sol006.yaml index 21ea2dc..65f8454 100644 --- a/tests/examples/vepc_nsd_sol006.yaml +++ b/tests/examples/vepc_nsd_sol006.yaml @@ -26,32 +26,31 @@ nsd: virtual-link-desc: - id: management mgmt-network: "true" - provider-network: - physical-network: osm-ext + vim-network-name: osm-ext - id: s1 - provider-network: - physical-network: s1 + vim-network-name: s1 - id: sgi - provider-network: - physical-network: sgi + vim-network-name: sgi df: - - id: vEPC_DF + - id: default-df vnf-profile: - - id: vEPC-VNF + - id: "1" vnfd-id: vEPC_vnfd virtual-link-connectivity: - virtual-link-profile-id: management constituent-cpd-id: - - constituent-base-element-id: vEPC_vnfd - constituent-cpd-id: spgwmme-mgmt - - constituent-base-element-id: vEPC_vnfd - constituent-cpd-id: hss-mgmt + - constituent-base-element-id: "1" + constituent-cpd-id: spgwmme-mgmt-ext + - constituent-base-element-id: "1" + constituent-cpd-id: hss-mgmt-ext - virtual-link-profile-id: s1 constituent-cpd-id: - - constituent-base-element-id: vEPC_vnfd - constituent-cpd-id: spgwmme-s1 + - constituent-base-element-id: "1" + constituent-cpd-id: spgwmme-s1-ext + ip-address: 192.168.0.11 - virtual-link-profile-id: sgi constituent-cpd-id: - - constituent-base-element-id: vEPC_vnfd - constituent-cpd-id: spgwmme-sgi + - constituent-base-element-id: "1" + constituent-cpd-id: spgwmme-sgi-ext + ip-address: 192.168.2.11 diff --git a/tests/examples/vepc_sol006.yaml b/tests/examples/vepc_sol006.yaml index b4e43c2..e5863e7 100644 --- a/tests/examples/vepc_sol006.yaml +++ b/tests/examples/vepc_sol006.yaml @@ -25,12 +25,12 @@ vnfd: virtual-cpu: num-virtual-cpu: 2 virtual-memory: - size: 4 # Memory size in GB + size: 4.0 # Memory size in GB - id: hss-compute virtual-cpu: num-virtual-cpu: 1 virtual-memory: - size: 2 # Memory size in GB + size: 2.0 # Memory size in GB virtual-storage-desc: - id: spgwmme-storage size-of-storage: 10 @@ -39,12 +39,11 @@ vnfd: sw-image-desc: - id: nextepc-spgwmme-base name: nextepc-spgwmme-base - checksum: - hash: # Mandatory? - - id: nextepc-hss-bas - name: nextepc-hss-bas - checksum: - hash: # Mandatory? + image: nextepc-spgwmme-base + - id: nextepc-hss-base + name: nextepc-hss-base + image: nextepc-hss-base + vdu: - id: spgwmme name: spgwmme @@ -55,27 +54,34 @@ vnfd: - spgwmme-storage sw-image-desc: nextepc-spgwmme-base int-cpd: - - id: spgwmme-mgmt-int + - id: eth0-int virtual-network-interface-requirement: - name: eth0 virtual-interface: type: PARAVIRT - - id: spgwmme-s1-int + - id: eth1-int virtual-network-interface-requirement: - name: eth1 virtual-interface: type: PARAVIRT - - id: spgwmme-sgi-int + - id: eth2-int virtual-network-interface-requirement: - name: eth2 virtual-interface: type: PARAVIRT - - id: spgwmme-s6a-int + - id: eth3-int int-virtual-link-desc: s6a # Connection to VLD! virtual-network-interface-requirement: - name: eth3 virtual-interface: type: PARAVIRT + monitoring-parameter: + - id: "spgw_cpu_util" + name: "spgw_cpu_util" + performance-metric: "cpu_utilization" + - id: "spgw_memory_util" + name: "spgw_memory_util" + performance-metric: "average_memory_utilization" - id: hss name: hss description: hss @@ -83,30 +89,30 @@ vnfd: virtual-compute-desc: hss-compute virtual-storage-desc: - hss-storage - sw-image-desc: nextepc-hss-bas + sw-image-desc: nextepc-hss-base int-cpd: - - id: hss-mgmt-int + - id: eth0-int virtual-network-interface-requirement: - name: eth0 virtual-interface: type: PARAVIRT - - id: hss-s6a-int + - id: eth1-int int-virtual-link-desc: s6a # Connection to VLD! virtual-network-interface-requirement: - name: eth1 virtual-interface: type: PARAVIRT df: - - id: vepc_default - vnf-configuration-id: vnf-configuration-example + - id: default-df + vnf-configuration-id: default-vnf-configuration vdu-profile: - id: spgwmme min-number-of-instances: 1 - id: hss min-number-of-instances: 1 - vdu-configuration-id: vdu-configuration-example + vdu-configuration-id: hss-vdu-configuration instantiation-level: - - id: default + - id: default-instantiation-level vdu-level: - vdu-id: spgwmme number-of-instances: 1 @@ -114,31 +120,16 @@ vnfd: number-of-instances: 1 virtual-link-profile: - id: s6a - flavour: + flavour: "" virtual-link-protocol-data: l3-protocol-data: - name: s6a + name: s6a-l3-protocol-data description: s6a network ip-version: ipv4 cidr: 10.0.6.0/24 dhcp-enabled: true - monitoring-parameter: - - id: "spgw_cpu_util" - name: "spgw_cpu_util" - performance-metric: "cpu_load" - collection-period: 123456 - #aggregation-type: AVERAGE # Not included in augments - #vdu-monitoring-param: # Not included in augments - # vdu-ref: "spgwmme" # Not included in augments - # vdu-monitoring-param-ref: "spgw_cpu_util" # Not included in augments - - id: "spgw_memory_util" - name: "spgw_memory_util" - #aggregation-type: AVERAGE # Not included in augments - #vdu-monitoring-param: # Not included in augments - # vdu-ref: "spgwmme" # Not included in augments - # vdu-monitoring-param-ref: "spgw_memory_util" # Not included in augments vdu-configuration: - - id: vdu-configuration-example + - id: hss-vdu-configuration initial-config-primitive: - seq: "1" name: config @@ -163,7 +154,7 @@ vnfd: juju: charm: hsscharm vnf-configuration: - - id: vnf-configuration-example + - id: default-vnf-configuration initial-config-primitive: - seq: "1" name: config @@ -203,17 +194,17 @@ vnfd: - id: spgwmme-mgmt-ext int-cpd: # Connection to int-cpd vdu-id: spgwmme - cpd: spgwmme-mgmt-int + cpd: eth0-int - id: spgwmme-s1-ext int-cpd: # Connection to int-cpd vdu-id: spgwmme - cpd: spgwmme-mgmt-int + cpd: eth1-int - id: spgwmme-sgi-ext int-cpd: # Connection to int-cpd vdu-id: spgwmme - cpd: spgwmme-mgmt-int + cpd: eth2-int # HSS - id: hss-mgmt-ext int-cpd: # Connection to int-cpd - vdu-id: spgwmme - cpd: spgwmme-mgmt-int + vdu-id: hss + cpd: eth0-int diff --git a/tests/examples/vnfd_im.yaml b/tests/examples/vnfd_im.yaml index 587cb89..6742889 100644 --- a/tests/examples/vnfd_im.yaml +++ b/tests/examples/vnfd_im.yaml @@ -17,7 +17,7 @@ vnfd:vnfd-catalog: vnfd: - id: vnfd + - id: vnfd mgmt-interface: cp: vnf-mgmt @@ -44,6 +44,8 @@ vnfd:vnfd-catalog: vdu: - id: mgmtVM + image: ubuntu1804 + interface: - name: mgmtVM-eth0 position: "1" @@ -66,6 +68,8 @@ vnfd:vnfd-catalog: - id: dataVM + image: ubuntu1804 + interface: - name: dataVM-eth0 position: "1" diff --git a/tests/examples/vnfd_sol006.yaml b/tests/examples/vnfd_sol006.yaml index 6ecbb82..cb314f9 100644 --- a/tests/examples/vnfd_sol006.yaml +++ b/tests/examples/vnfd_sol006.yaml @@ -19,48 +19,70 @@ vnfd: id: vnfd mgmt-cp: vnf-mgmt-ext + sw-image-desc: + - id: ubuntu1804 + image: ubuntu1804 + name: ubuntu1804 + ext-cpd: - id: vnf-mgmt-ext int-cpd: vdu-id: mgmtVM - cpd: vnf-mgmt-int + cpd: mgmtVM-eth0-int - id: vnf-data-ext int-cpd: vdu-id: dataVM - cpd: vnf-data-int + cpd: dataVM-xe0-int int-virtual-link-desc: - id: internal vdu: - id: mgmtVM + sw-image-desc: ubuntu1804 int-cpd: - - id: vnf-mgmt-int + - id: mgmtVM-eth0-int virtual-network-interface-requirement: - name: mgmtVM-eth0 - position: "1" + position: 1 virtual-interface: type: VIRTIO - - id: mgmtVM-internal + - id: mgmtVM-eth1-int int-virtual-link-desc: internal virtual-network-interface-requirement: - name: mgmtVM-eth1 - position: "2" + position: 2 virtual-interface: type: VIRTIO - id: dataVM + sw-image-desc: ubuntu1804 int-cpd: - - id: dataVM-internal + - id: dataVM-eth0-int int-virtual-link-desc: internal virtual-network-interface-requirement: - name: dataVM-eth0 - position: "1" + position: 1 virtual-interface: type: VIRTIO - - id: vnf-data-int + - id: dataVM-xe0-int virtual-network-interface-requirement: - name: dataVM-xe0 - position: "2" + position: 2 virtual-interface: type: VIRTIO + + df: + - id: default-df + instantiation-level: + - id: default-instantiation-level + vdu-level: + - number-of-instances: 1 + vdu-id: mgmtVM + - number-of-instances: 1 + vdu-id: dataVM + vdu-profile: + - id: mgmtVM + min-number-of-instances: 1 + - id: dataVM + min-number-of-instances: 1 \ No newline at end of file diff --git a/tests/test_im_translation.py b/tests/test_im_translation.py new file mode 100644 index 0000000..065cbdc --- /dev/null +++ b/tests/test_im_translation.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Whitestack, LLC +# ************************************************************* +# +# This file is part of OSM common repository. +# All Rights Reserved to Whitestack, LLC +# +# 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. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact: agarcia@whitestack.com +## + +from osm_im.im_translation import translate_im_vnfd_to_sol006, translate_im_nsd_to_sol006 +import unittest +import yaml + +TESTS_EXAMPLES_FOLDER = 'tests/examples/' + +IM_TO_SOL006_VNFD_FILES = { + 'cirros_vnfd_im.yaml': 'cirros_vnfd_sol006.yaml', + 'alternative_image_im.yaml': 'alternative_image_sol006.yaml', + 'epa_im.yaml': 'epa_sol006.yaml', + 'magma_knf_im.yaml': 'magma_knf_sol006.yaml', + 'vnfd_im.yaml': 'vnfd_sol006.yaml', + 'vepc_im.yaml': 'vepc_sol006.yaml', + 'hackfest_charmed_vnfd_im.yaml': 'hackfest_charmed_vnfd_sol006.yaml', +} + +IM_TO_SOL006_NSD_FILES = { + 'cirros_nsd_im.yaml': 'cirros_nsd_sol006.yaml', + 'vepc_nsd_im.yaml': 'vepc_nsd_sol006.yaml', + 'hackfest_charmed_nsd_im.yaml': 'hackfest_charmed_nsd_sol006.yaml', +} + + +class TranslationTest(unittest.TestCase): + def _sort_descriptor(self, descriptor): + if isinstance(descriptor, dict): + return sorted((k, self._sort_descriptor(v)) for k, v in descriptor.items()) + if isinstance(descriptor, list): + return sorted(self._sort_descriptor(x) for x in descriptor) + else: + return descriptor + + def _get_descriptor_file_data_as_dict(self, descriptor_file_path): + with open(descriptor_file_path, 'r') as descriptor_file: + descriptor_dict = yaml.safe_load(descriptor_file.read()) + return descriptor_dict + + def test_translate_im_vnfd_to_sol006(self): + for im_file in IM_TO_SOL006_VNFD_FILES: + im_file_path = TESTS_EXAMPLES_FOLDER + im_file + sol006_file_path = TESTS_EXAMPLES_FOLDER + IM_TO_SOL006_VNFD_FILES[im_file] + im_vnfd = self._get_descriptor_file_data_as_dict(im_file_path) + sol006_vnfd = self._get_descriptor_file_data_as_dict(sol006_file_path) + + translated_vnfd = translate_im_vnfd_to_sol006(im_vnfd) + self.assertEqual(self._sort_descriptor(sol006_vnfd), self._sort_descriptor(translated_vnfd)) + + def test_translate_im_nsd_to_sol006(self): + for im_file in IM_TO_SOL006_NSD_FILES: + im_file_path = TESTS_EXAMPLES_FOLDER + im_file + sol006_file_path = TESTS_EXAMPLES_FOLDER + IM_TO_SOL006_NSD_FILES[im_file] + im_nsd = self._get_descriptor_file_data_as_dict(im_file_path) + sol006_nsd = self._get_descriptor_file_data_as_dict(sol006_file_path) + + translated_nsd = translate_im_nsd_to_sol006(im_nsd) + self.assertEqual(self._sort_descriptor(sol006_nsd), self._sort_descriptor(translated_nsd)) -- 2.17.1