| garciaale | 0a517b9 | 2021-01-12 15:44:44 -0300 | [diff] [blame] | 1 | # -*- coding: utf-8 -*- |
| 2 | |
| 3 | # Copyright 2020 Whitestack, LLC |
| 4 | # ************************************************************* |
| 5 | # |
| 6 | # This file is part of OSM common repository. |
| 7 | # All Rights Reserved to Whitestack, LLC |
| 8 | # |
| 9 | # Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 10 | # not use this file except in compliance with the License. You may obtain |
| 11 | # a copy of the License at |
| 12 | # |
| 13 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 14 | # |
| 15 | # Unless required by applicable law or agreed to in writing, software |
| 16 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 17 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 18 | # License for the specific language governing permissions and limitations |
| 19 | # under the License. |
| 20 | # |
| 21 | # For those usages not covered by the Apache License, Version 2.0 please |
| 22 | # contact: agarcia@whitestack.com |
| 23 | ## |
| 24 | |
| 25 | from osm_im.validation import Validation, ValidationException |
| 26 | |
| 27 | |
| 28 | class TranslationException(Exception): |
| 29 | pass |
| 30 | |
| 31 | |
| 32 | # ******************** Translation public functions ******************** |
| 33 | |
| 34 | def translate_im_model_to_sol006(im_model_data): |
| 35 | _validate_im_model(im_model_data) |
| 36 | descriptor_type = _get_im_model_descriptor_type(im_model_data) |
| 37 | if descriptor_type == "vnfd": |
| 38 | return translate_im_vnfd_to_sol006(im_model_data) |
| 39 | if descriptor_type == "nsd": |
| 40 | return translate_im_nsd_to_sol006(im_model_data) |
| 41 | # For sanity, should not happen |
| 42 | raise TranslationException("Error in translation: cannot determine the type of OSM-IM descriptor. Found {}, " |
| 43 | "expected one of: vnfd:vnfd-catalog, vnfd-catalog, nsd:nsd-catalog, nsd-catalog." |
| 44 | .format(descriptor_type)) |
| 45 | |
| 46 | |
| 47 | def translate_im_vnfd_to_sol006(im_vnfd): |
| 48 | im_vnfd = _remove_im_vnfd_envelope(im_vnfd) |
| 49 | sol006_vnfd = {} |
| 50 | _add_im_vnfd_basic_data_to_sol006_vnfd(im_vnfd, sol006_vnfd) |
| 51 | _add_im_vnfd_mgmt_interface_cp_to_sol006_vnfd(im_vnfd, sol006_vnfd) |
| 52 | _add_im_vdu_flavors_to_sol006_vnfd(im_vnfd, sol006_vnfd) |
| 53 | _add_im_vdu_guest_epa_to_sol006_vnfd(im_vnfd, sol006_vnfd) |
| 54 | _add_im_vdu_images_to_sol006_vnfd(im_vnfd, sol006_vnfd) |
| 55 | _add_im_vdus_to_sol006_vnfd(im_vnfd, sol006_vnfd) |
| 56 | _add_im_internal_vlds_to_sol006_vfnd(im_vnfd, sol006_vnfd) |
| 57 | _add_im_vnf_configuration_to_sol006_vnfd(im_vnfd, sol006_vnfd) |
| 58 | _add_im_ip_profiles_to_sol006_vnfd(im_vnfd, sol006_vnfd) |
| 59 | _add_im_vdu_monitoring_params_to_sol006_vnfd(im_vnfd, sol006_vnfd) |
| 60 | _add_im_scaling_group_descriptors_to_sol006_vnfd(im_vnfd, sol006_vnfd) |
| 61 | _add_im_kdus_to_sol006_vnfd(im_vnfd, sol006_vnfd) |
| 62 | _add_im_k8s_clusters_to_sol006_vnfd(im_vnfd, sol006_vnfd) |
| 63 | _add_im_placement_groups_to_sol006_vnfd(im_vnfd, sol006_vnfd) |
| 64 | return {"vnfd": sol006_vnfd} |
| 65 | |
| 66 | |
| 67 | def translate_im_nsd_to_sol006(im_nsd): |
| 68 | im_nsd = _remove_im_nsd_envelope(im_nsd) |
| 69 | sol006_nsd = {} |
| 70 | _add_im_nsd_basic_data_to_sol006_nsd(im_nsd, sol006_nsd) |
| 71 | _add_im_constituent_vnfds_to_sol006_nsd(im_nsd, sol006_nsd) |
| 72 | _add_im_vlds_to_sol006_nsd(im_nsd, sol006_nsd) |
| 73 | return {"nsd": {"nsd": [sol006_nsd]}} |
| 74 | |
| 75 | |
| 76 | # ******************** Common translation private functions ******************** |
| 77 | |
| 78 | def _validate_im_model(im_model_data): |
| 79 | descriptor_type = _get_im_model_descriptor_type(im_model_data) |
| 80 | try: |
| 81 | Validation().pyangbind_validation(descriptor_type, im_model_data) |
| 82 | except ValidationException as e: |
| 83 | raise TranslationException("Error on input model validation: {}".format(str(e))) |
| 84 | |
| 85 | |
| 86 | def _get_im_model_descriptor_type(im_model_data): |
| 87 | data_root = list(im_model_data.keys())[0] |
| 88 | if "vnfd" in data_root: |
| 89 | return "vnfd" |
| 90 | if "nsd" in data_root: |
| 91 | return "nsd" |
| 92 | raise TranslationException("Error in translation: cannot determine the type of OSM-IM descriptor. Found {}, " |
| 93 | "expected one of: vnfd:vnfd-catalog, vnfd-catalog, nsd:nsd-catalog, nsd-catalog." |
| 94 | .format(data_root)) |
| 95 | |
| 96 | |
| 97 | # ******************** VNFD translation private functions ******************** |
| 98 | |
| 99 | def _remove_im_vnfd_envelope(im_vnfd): |
| 100 | # Data is wrapped as { vnfd-catalog: { vnfd: [ <data> ] } } |
| 101 | return list(im_vnfd.values())[0]["vnfd"][0] |
| 102 | |
| 103 | |
| 104 | def _add_im_vnfd_basic_data_to_sol006_vnfd(im_vnfd, sol006_vnfd): |
| 105 | sol006_vnfd["id"] = im_vnfd["id"] |
| 106 | if im_vnfd.get("name"): |
| 107 | sol006_vnfd["product-name"] = im_vnfd["name"] |
| 108 | if im_vnfd.get("description"): |
| 109 | sol006_vnfd["description"] = im_vnfd["description"] |
| 110 | if im_vnfd.get("vendor"): |
| 111 | sol006_vnfd["provider"] = im_vnfd["vendor"] |
| 112 | if im_vnfd.get("version"): |
| 113 | sol006_vnfd["version"] = im_vnfd["version"] |
| 114 | |
| 115 | |
| 116 | def _add_im_vnfd_mgmt_interface_cp_to_sol006_vnfd(im_vnfd, sol006_vnfd): |
| 117 | sol006_vnfd["mgmt-cp"] = "{}-ext".format(im_vnfd["mgmt-interface"]["cp"]) |
| 118 | |
| 119 | |
| 120 | def _add_im_vdu_flavors_to_sol006_vnfd(im_vnfd, sol006_vnfd): |
| 121 | storage_descriptors = [] |
| 122 | compute_descriptors = [] |
| 123 | for vdu in im_vnfd.get("vdu", ()): |
| 124 | vdu_id = vdu.get("id") |
| 125 | vdu_flavor = vdu.get("vm-flavor") |
| 126 | if not vdu_flavor: |
| 127 | continue |
| 128 | storage_descriptor = {"id": "{}-storage".format(vdu_id)} |
| 129 | compute_descriptor = {"id": "{}-compute".format(vdu_id)} |
| 130 | if vdu_flavor.get("storage-gb"): |
| 131 | storage_descriptor["size-of-storage"] = int(vdu_flavor["storage-gb"]) |
| 132 | storage_descriptors.append(storage_descriptor) |
| 133 | if vdu_flavor.get("vcpu-count"): |
| 134 | compute_descriptor["virtual-cpu"] = {"num-virtual-cpu": int(vdu_flavor["vcpu-count"])} |
| 135 | if vdu_flavor.get("memory-mb"): |
| 136 | compute_descriptor["virtual-memory"] = {"size": float(vdu_flavor["memory-mb"]) / 1024.0} |
| 137 | if len(compute_descriptor) > 1: |
| 138 | compute_descriptors.append(compute_descriptor) |
| 139 | if len(storage_descriptors) > 0: |
| 140 | sol006_vnfd["virtual-storage-desc"] = storage_descriptors |
| 141 | if len(compute_descriptors) > 0: |
| 142 | sol006_vnfd["virtual-compute-desc"] = compute_descriptors |
| 143 | |
| 144 | |
| 145 | def _add_im_vdu_guest_epa_to_sol006_vnfd(im_vnfd, sol006_vnfd): |
| 146 | for vdu in im_vnfd.get("vdu", ()): |
| 147 | vdu_guest_epa = vdu.get("guest-epa") |
| 148 | if not vdu_guest_epa: |
| 149 | continue |
| 150 | |
| 151 | _add_im_vdu_guest_epa_memory_and_cpu_to_sol006_vnfd(vdu, sol006_vnfd) |
| 152 | _add_im_vdu_guest_epa_disk_io_to_sol006_vnfd(vdu, sol006_vnfd) |
| 153 | |
| 154 | |
| 155 | def _add_im_vdu_guest_epa_memory_and_cpu_to_sol006_vnfd(im_vdu, sol006_vnfd): |
| 156 | vdu_guest_epa = im_vdu.get("guest-epa") |
| 157 | virtual_memory = _get_virtual_memory_from_im_vdu_guest_epa(vdu_guest_epa) |
| 158 | virtual_cpu = _get_virtual_cpu_from_im_vdu_guest_epa(vdu_guest_epa) |
| 159 | # Find this vdu compute descriptor and update it with the EPA options. If the |
| 160 | # vdu compute descriptor does not exist, create one with the EPA options only. |
| 161 | compute_descriptor_id = "{}-compute".format(im_vdu["id"]) |
| 162 | compute_descriptor = {"id": compute_descriptor_id} |
| 163 | compute_descriptor_found = False |
| 164 | for vcd in sol006_vnfd.get("virtual-compute-desc", ()): |
| 165 | if vcd.get("id") == compute_descriptor_id: |
| 166 | compute_descriptor = vcd |
| 167 | compute_descriptor_found = True |
| 168 | |
| 169 | compute_descriptor_virtual_memory = compute_descriptor.get("virtual-memory", {}) |
| 170 | compute_descriptor_virtual_cpu = compute_descriptor.get("virtual-cpu", {}) |
| 171 | compute_descriptor_virtual_memory.update(virtual_memory) |
| 172 | compute_descriptor_virtual_cpu.update(virtual_cpu) |
| 173 | if compute_descriptor_virtual_memory: |
| 174 | compute_descriptor["virtual-memory"] = compute_descriptor_virtual_memory |
| 175 | if compute_descriptor_virtual_cpu: |
| 176 | compute_descriptor["virtual-cpu"] = compute_descriptor_virtual_cpu |
| 177 | |
| 178 | if not compute_descriptor_found: |
| 179 | if sol006_vnfd.get("virtual-compute-desc"): |
| 180 | sol006_vnfd["virtual-compute-desc"].append(compute_descriptor) |
| 181 | else: |
| 182 | sol006_vnfd["virtual-compute-desc"] = [compute_descriptor] |
| 183 | |
| 184 | |
| 185 | def _add_im_vdu_guest_epa_disk_io_to_sol006_vnfd(im_vdu, sol006_vnfd): |
| 186 | vdu_guest_epa = im_vdu.get("guest-epa") |
| 187 | disk_io_quota = vdu_guest_epa.get("disk-io-quota", {}) |
| 188 | if not disk_io_quota: |
| 189 | return |
| 190 | # Find this vdu storage descriptor and update it with the EPA options. If the |
| 191 | # vdu storage descriptor does not exist, create one with the EPA options only. |
| 192 | storage_descriptor_id = "{}-storage".format(im_vdu["id"]) |
| 193 | storage_descriptor = {"id": storage_descriptor_id} |
| 194 | storage_descriptor_found = False |
| 195 | for vsd in sol006_vnfd.get("virtual-storage-desc", ()): |
| 196 | if vsd.get("id") == storage_descriptor_id: |
| 197 | storage_descriptor = vsd |
| 198 | storage_descriptor_found = True |
| 199 | |
| 200 | storage_descriptor["disk-io-quota"] = disk_io_quota |
| 201 | if not storage_descriptor_found: |
| 202 | if sol006_vnfd.get("virtual-storage-desc"): |
| 203 | sol006_vnfd["virtual-storage-desc"].append(storage_descriptor) |
| 204 | else: |
| 205 | sol006_vnfd["virtual-storage-desc"] = [storage_descriptor] |
| 206 | |
| 207 | |
| 208 | def _get_virtual_memory_from_im_vdu_guest_epa(im_vdu_guest_epa): |
| 209 | virtual_memory = {} |
| 210 | if im_vdu_guest_epa.get("mempage-size"): |
| 211 | virtual_memory["mempage-size"] = im_vdu_guest_epa["mempage-size"] |
| 212 | if im_vdu_guest_epa.get("numa-node-policy"): |
| 213 | virtual_memory["numa-enabled"] = True |
| 214 | virtual_memory["numa-node-policy"] = im_vdu_guest_epa["numa-node-policy"] |
| 215 | if im_vdu_guest_epa.get("mem-quota"): |
| 216 | virtual_memory["mem-quota"] = im_vdu_guest_epa["mem-quota"] |
| 217 | return virtual_memory |
| 218 | |
| 219 | |
| 220 | def _get_virtual_cpu_from_im_vdu_guest_epa(im_vdu_guest_epa): |
| 221 | virtual_cpu = {} |
| 222 | if im_vdu_guest_epa.get("cpu-pinning-policy") or im_vdu_guest_epa.get("cpu-thread-pinning-policy"): |
| 223 | virtual_cpu["pinning"] = {} |
| 224 | if im_vdu_guest_epa.get("cpu-pinning-policy"): |
| 225 | if im_vdu_guest_epa["cpu-pinning-policy"] == "SHARED": |
| 226 | virtual_cpu["pinning"]["policy"] = "dynamic" |
| 227 | else: |
| 228 | virtual_cpu["pinning"]["policy"] = "static" |
| 229 | if im_vdu_guest_epa.get("cpu-thread-pinning-policy"): |
| 230 | virtual_cpu["pinning"]["thread-policy"] = im_vdu_guest_epa["cpu-thread-pinning-policy"] |
| 231 | if im_vdu_guest_epa.get("cpu-quota"): |
| 232 | virtual_cpu["cpu-quota"] = im_vdu_guest_epa["cpu-quota"] |
| 233 | return virtual_cpu |
| 234 | |
| 235 | |
| 236 | def _add_im_vdu_images_to_sol006_vnfd(im_vnfd, sol006_vnfd): |
| 237 | image_descriptors = [] |
| 238 | all_images = set() # To avoid duplicated images |
| 239 | for vdu in im_vnfd.get("vdu", ()): |
| 240 | vdu_image = vdu.get("image") |
| 241 | if vdu_image and vdu_image not in all_images: |
| 242 | image_descriptors.append({"id": vdu_image, "name": vdu_image, "image": vdu_image}) |
| 243 | all_images.add(vdu_image) |
| 244 | for alternative_image in vdu.get("alternative-images", ()): |
| 245 | alt_image = alternative_image.get("image") |
| 246 | alt_image_descriptor = {"id": alt_image, "name": alt_image, "image": alt_image} |
| 247 | if alternative_image.get("vim-type"): |
| 248 | alt_image_descriptor["vim-type"] = alternative_image["vim-type"] |
| 249 | if alt_image not in all_images: |
| 250 | image_descriptors.append(alt_image_descriptor) |
| 251 | all_images.add(alt_image) |
| 252 | |
| 253 | if len(image_descriptors) > 0: |
| 254 | sol006_vnfd["sw-image-desc"] = image_descriptors |
| 255 | |
| 256 | |
| 257 | def _add_im_vdus_to_sol006_vnfd(im_vnfd, sol006_vnfd): |
| 258 | vdus = [] |
| 259 | ext_cpds = [] |
| 260 | vdu_configurations = [] |
| 261 | df_instantiation_level = {"id": "default-instantiation-level", "vdu-level": []} |
| 262 | df = {"id": "default-df", "vdu-profile": [], "instantiation-level": [df_instantiation_level]} |
| 263 | for vdu in im_vnfd.get("vdu", ()): |
| 264 | vdu_descriptor = {"id": vdu["id"]} |
| 265 | if vdu.get("description"): |
| 266 | vdu_descriptor["description"] = vdu["description"] |
| 267 | if vdu.get("name"): |
| 268 | vdu_descriptor["name"] = vdu["name"] |
| 269 | if vdu.get("cloud-init-file"): |
| 270 | vdu_descriptor["cloud-init-file"] = vdu["cloud-init-file"] |
| 271 | if vdu.get("supplemental-boot-data"): |
| 272 | vdu_descriptor["supplemental-boot-data"] = vdu["supplemental-boot-data"] |
| 273 | if vdu.get("alarm"): |
| 274 | vdu_descriptor["alarm"] = vdu["alarm"] |
| 275 | if vdu.get("pdu-type"): |
| 276 | vdu_descriptor["pdu-type"] = vdu["pdu-type"] |
| 277 | |
| 278 | _add_im_vdu_images_to_sol006_vdu(vdu, vdu_descriptor) |
| 279 | _add_im_vdu_flavor_to_sol006_vdu(vdu, vdu_descriptor) |
| 280 | |
| 281 | vdu_int_cpds, vdu_ext_cpds = _get_int_and_ext_cpds_from_im_vdu(vdu, im_vnfd) |
| 282 | vdu_descriptor["int-cpd"] = vdu_int_cpds |
| 283 | ext_cpds.extend(vdu_ext_cpds) |
| 284 | |
| 285 | vdu_profile = _get_vdu_profile_from_im_vdu(vdu, im_vnfd) |
| 286 | vdu_level = _get_instantiation_level_vdu_level_from_im_vdu(vdu) |
| 287 | if vdu.get("vdu-configuration"): |
| 288 | vdu_configuration = vdu["vdu-configuration"] |
| bravof | 2eccea2 | 2021-02-12 16:17:54 -0300 | [diff] [blame] | 289 | vdu_configuration["id"] = vdu["id"] |
| garciaale | 0a517b9 | 2021-01-12 15:44:44 -0300 | [diff] [blame] | 290 | vdu_configurations.append(vdu_configuration) |
| 291 | df["vdu-profile"].append(vdu_profile) |
| 292 | df["instantiation-level"][0]["vdu-level"].append(vdu_level) |
| 293 | |
| 294 | vdus.append(vdu_descriptor) |
| 295 | |
| 296 | if len(vdus) > 0: |
| 297 | sol006_vnfd["vdu"] = vdus |
| 298 | sol006_vnfd["df"] = [df] |
| 299 | if len(ext_cpds) > 0: |
| 300 | sol006_vnfd["ext-cpd"] = ext_cpds |
| 301 | if len(vdu_configurations) > 0: |
| bravof | 2eccea2 | 2021-02-12 16:17:54 -0300 | [diff] [blame] | 302 | _prepare_dict_entries_for_configurations(sol006_vnfd) |
| 303 | sol006_vnfd["df"][0]["lcm-operations-configuration"]["operate-vnf-op-config"]["day1-2"].extend(vdu_configurations) |
| garciaale | 0a517b9 | 2021-01-12 15:44:44 -0300 | [diff] [blame] | 304 | |
| 305 | |
| 306 | def _add_im_vdu_images_to_sol006_vdu(im_vdu, sol006_vdu): |
| 307 | if im_vdu.get("image"): |
| 308 | sol006_vdu["sw-image-desc"] = im_vdu["image"] |
| 309 | alternative_images = [] |
| 310 | for alternative_image in im_vdu.get("alternative-images", ()): |
| 311 | alternative_images.append(alternative_image.get("image")) |
| 312 | if len(alternative_images) > 0: |
| 313 | sol006_vdu["alternative-sw-image-desc"] = alternative_images |
| 314 | |
| 315 | |
| 316 | def _add_im_vdu_flavor_to_sol006_vdu(im_vdu, sol006_vdu): |
| 317 | vdu_flavor = im_vdu.get("vm-flavor") |
| 318 | if vdu_flavor: |
| 319 | if vdu_flavor.get("vcpu-count") or vdu_flavor.get("memory-mb"): |
| 320 | sol006_vdu["virtual-compute-desc"] = "{}-compute".format(im_vdu["id"]) |
| 321 | if vdu_flavor.get("storage-gb"): |
| 322 | sol006_vdu["virtual-storage-desc"] = ["{}-storage".format(im_vdu["id"])] |
| 323 | |
| 324 | |
| 325 | def _get_int_and_ext_cpds_from_im_vdu(im_vdu, im_vnfd): |
| 326 | int_cpds = [] |
| 327 | ext_cpds = [] |
| 328 | for interface in im_vdu.get("interface", ()): |
| 329 | int_cpd = {"id": "{}-int".format(interface["name"])} |
| 330 | virtual_network_interface_requirement = {"name": interface["name"]} |
| 331 | if interface.get("virtual-interface"): |
| 332 | virtual_network_interface_requirement["virtual-interface"] = interface["virtual-interface"] |
| 333 | if "position" in interface: |
| 334 | virtual_network_interface_requirement["position"] = int(interface["position"]) |
| 335 | int_cpd["virtual-network-interface-requirement"] = [virtual_network_interface_requirement] |
| 336 | if interface.get("external-connection-point-ref"): |
| 337 | ext_cpd = { |
| 338 | "id": "{}-ext".format(interface["external-connection-point-ref"]), |
| 339 | "int-cpd": { |
| 340 | "vdu-id": im_vdu["id"], |
| 341 | "cpd": int_cpd["id"] |
| 342 | } |
| 343 | } |
| 344 | for cp in im_vnfd.get("connection-point", ()): |
| 345 | if cp.get("name", "") != interface["external-connection-point-ref"]: |
| 346 | continue |
| 347 | if "port-security-enabled" in cp: |
| 348 | ext_cpd["port-security-enabled"] = cp["port-security-enabled"] |
| 349 | if cp.get("port-security-disable-strategy"): |
| 350 | ext_cpd["port-security-disable-strategy"] = cp["port-security-disable-strategy"] |
| 351 | ext_cpds.append(ext_cpd) |
| 352 | |
| 353 | int_cpds.append(int_cpd) |
| 354 | |
| 355 | return int_cpds, ext_cpds |
| 356 | |
| 357 | |
| 358 | def _get_vdu_profile_from_im_vdu(im_vdu, im_vnfd): |
| 359 | vdu_profile = {"id": im_vdu["id"]} |
| 360 | initial_instances = int(im_vdu.get("count", 1)) |
| 361 | vdu_profile["min-number-of-instances"] = initial_instances |
| 362 | for scaling_group_descriptor in im_vnfd.get("scaling-group-descriptor", ()): |
| 363 | for sgd_vdu in scaling_group_descriptor.get("vdu", []): |
| 364 | if sgd_vdu.get("vdu-id-ref") == im_vdu["id"]: |
| 365 | sgd_max_instances = int(scaling_group_descriptor.get("max-instance-count", 1)) |
| 366 | sgd_min_instances = int(scaling_group_descriptor.get("min-instance-count", 0)) |
| 367 | vdu_profile["min-number-of-instances"] = sgd_min_instances + initial_instances |
| 368 | vdu_profile["max-number-of-instances"] = sgd_max_instances + initial_instances |
| garciaale | 0a517b9 | 2021-01-12 15:44:44 -0300 | [diff] [blame] | 369 | return vdu_profile |
| 370 | |
| 371 | |
| 372 | def _get_instantiation_level_vdu_level_from_im_vdu(im_vdu): |
| 373 | vdu_level = {"vdu-id": im_vdu["id"]} |
| 374 | vdu_level["number-of-instances"] = int(im_vdu.get("count", 1)) |
| 375 | return vdu_level |
| 376 | |
| 377 | |
| 378 | def _add_im_internal_vlds_to_sol006_vfnd(im_vnfd, sol006_vnfd): |
| 379 | int_virtual_link_descs = [] |
| 380 | for ivld in im_vnfd.get("internal-vld", ()): |
| 381 | int_virtual_link_desc = {"id": ivld["id"]} |
| 382 | _add_im_internal_vld_connection_point_refs_to_sol006_vnfd(ivld, im_vnfd, sol006_vnfd) |
| 383 | |
| 384 | int_virtual_link_descs.append(int_virtual_link_desc) |
| 385 | |
| 386 | if len(int_virtual_link_descs) > 0: |
| 387 | sol006_vnfd["int-virtual-link-desc"] = int_virtual_link_descs |
| 388 | |
| 389 | |
| 390 | def _add_im_internal_vld_connection_point_refs_to_sol006_vnfd(ivld, im_vnfd, sol006_vnfd): |
| 391 | all_int_cp_refs_interfaces = {} |
| 392 | for vdu in im_vnfd.get("vdu", ()): |
| 393 | for interface in vdu.get("interface", ()): |
| 394 | int_cp_ref = interface.get("internal-connection-point-ref") |
| 395 | if not int_cp_ref: |
| 396 | continue |
| 397 | all_int_cp_refs_interfaces[int_cp_ref] = (vdu["id"], interface["name"]) |
| 398 | |
| 399 | for int_cp in ivld.get("internal-connection-point", ()): |
| 400 | int_cp_ref = int_cp["id-ref"] |
| 401 | (vdu_id, interface_name) = all_int_cp_refs_interfaces[int_cp_ref] |
| 402 | sol006_int_cpd_id = "{}-int".format(interface_name) |
| 403 | # Search for this int_cp on sol006_vnfd and update it |
| 404 | for vdu in sol006_vnfd.get("vdu", ()): |
| 405 | if vdu["id"] != vdu_id: |
| 406 | continue |
| 407 | for int_cpd in vdu.get("int-cpd", ()): |
| 408 | if int_cpd["id"] == sol006_int_cpd_id: |
| 409 | int_cpd["int-virtual-link-desc"] = ivld["id"] |
| 410 | |
| bravof | 2eccea2 | 2021-02-12 16:17:54 -0300 | [diff] [blame] | 411 | def _prepare_dict_entries_for_configurations(sol006_vnfd): |
| 412 | sol006_vnfd["df"] = sol006_vnfd.get("df", [{}]) |
| 413 | if not sol006_vnfd["df"][0].get("lcm-operations-configuration"): |
| 414 | sol006_vnfd["df"][0]["lcm-operations-configuration"] = { |
| 415 | "operate-vnf-op-config": { |
| 416 | "day1-2": [] |
| 417 | } |
| 418 | } |
| garciaale | 0a517b9 | 2021-01-12 15:44:44 -0300 | [diff] [blame] | 419 | |
| 420 | def _add_im_vnf_configuration_to_sol006_vnfd(im_vnfd, sol006_vnfd): |
| 421 | vnf_configuration = im_vnfd.get("vnf-configuration") |
| 422 | if not vnf_configuration: |
| 423 | return |
| bravof | 2eccea2 | 2021-02-12 16:17:54 -0300 | [diff] [blame] | 424 | vnf_configuration["id"] = im_vnfd.get("id") |
| 425 | _prepare_dict_entries_for_configurations(sol006_vnfd) |
| 426 | sol006_vnfd["df"][0]["lcm-operations-configuration"]["operate-vnf-op-config"]["day1-2"].append(vnf_configuration) |
| garciaale | 0a517b9 | 2021-01-12 15:44:44 -0300 | [diff] [blame] | 427 | |
| 428 | |
| 429 | def _add_im_ip_profiles_to_sol006_vnfd(im_vnfd, sol006_vnfd): |
| 430 | all_ivlds_ip_profiles = {} |
| 431 | for ivld in im_vnfd.get("internal-vld", ()): |
| 432 | if ivld.get("ip-profile-ref"): |
| 433 | all_ivlds_ip_profiles[ivld["ip-profile-ref"]] = ivld["id"] |
| 434 | |
| 435 | virtual_link_profiles = [] |
| 436 | for ip_profile in im_vnfd.get("ip-profiles", ()): |
| 437 | virtual_link_profile = {"id": all_ivlds_ip_profiles[ip_profile["name"]], "flavour": ""} |
| 438 | ip_profile_params = ip_profile.get("ip-profile-params") |
| 439 | if ip_profile_params: |
| 440 | l3_protocol_data = {"name": "{}-l3-protocol-data".format(virtual_link_profile["id"])} |
| 441 | if ip_profile_params.get("ip-version"): |
| 442 | l3_protocol_data["ip-version"] = ip_profile_params["ip-version"] |
| 443 | if ip_profile_params.get("subnet-address"): |
| 444 | l3_protocol_data["cidr"] = ip_profile_params["subnet-address"] |
| 445 | if ip_profile_params.get("gateway-address"): |
| 446 | l3_protocol_data["gateway-ip"] = ip_profile_params["gateway-address"] |
| 447 | if ip_profile_params.get("security-group"): |
| 448 | l3_protocol_data["security-group"] = ip_profile_params["security-group"] |
| 449 | if ip_profile_params.get("dhcp-params", {}).get("enabled"): |
| 450 | l3_protocol_data["dhcp-enabled"] = ip_profile_params["dhcp-params"]["enabled"] |
| 451 | if ip_profile.get("description"): |
| 452 | l3_protocol_data["description"] = ip_profile["description"] |
| 453 | |
| 454 | virtual_link_profile["virtual-link-protocol-data"] = {"l3-protocol-data": l3_protocol_data} |
| 455 | |
| 456 | virtual_link_profiles.append(virtual_link_profile) |
| 457 | |
| 458 | if len(virtual_link_profiles) > 0: |
| 459 | sol006_vnfd["df"][0]["virtual-link-profile"] = virtual_link_profiles |
| 460 | |
| 461 | |
| 462 | def _add_im_vdu_monitoring_params_to_sol006_vnfd(im_vnfd, sol006_vnfd): |
| 463 | all_vdu_monitoring_param_metrics = {} |
| 464 | for vdu in im_vnfd.get("vdu", ()): |
| 465 | for monitoring_param in vdu.get("monitoring-param", ()): |
| 466 | monitoring_param_metric = monitoring_param.get("nfvi-metric") |
| 467 | if monitoring_param_metric: |
| 468 | all_vdu_monitoring_param_metrics[(vdu["id"], monitoring_param["id"])] = monitoring_param_metric |
| 469 | |
| 470 | for monitoring_param in im_vnfd.get("monitoring-param", ()): |
| 471 | sol006_mp = {"id": monitoring_param["id"]} |
| 472 | if monitoring_param.get("name"): |
| 473 | sol006_mp["name"] = monitoring_param["name"] |
| 474 | if monitoring_param.get("vdu-monitoring-param"): |
| 475 | monitoring_param_vdu_id = monitoring_param["vdu-monitoring-param"].get("vdu-ref") |
| 476 | monitoring_param_id = monitoring_param["vdu-monitoring-param"].get("vdu-monitoring-param-ref") |
| 477 | metric = all_vdu_monitoring_param_metrics.get((monitoring_param_vdu_id, monitoring_param_id)) |
| 478 | if metric: |
| 479 | sol006_mp["performance-metric"] = metric |
| 480 | # Find that vdu inside sol006_vnfd and update its monitoring-parameter list |
| 481 | for vdu in sol006_vnfd.get("vdu", ()): |
| 482 | if vdu["id"] != monitoring_param_vdu_id: |
| 483 | continue |
| 484 | if vdu.get("monitoring-parameter"): |
| 485 | vdu["monitoring-parameter"].append(sol006_mp) |
| 486 | else: |
| 487 | vdu["monitoring-parameter"] = [sol006_mp] |
| 488 | |
| 489 | |
| 490 | def _add_im_scaling_group_descriptors_to_sol006_vnfd(im_vnfd, sol006_vnfd): |
| 491 | scaling_aspects = [] |
| 492 | for scaling_group_descriptor in im_vnfd.get("scaling-group-descriptor", ()): |
| 493 | scaling_aspect = {"id": scaling_group_descriptor["name"], "name": scaling_group_descriptor["name"]} |
| 494 | if scaling_group_descriptor.get("max-instance-count"): |
| 495 | scaling_aspect["max-scale-level"] = int(scaling_group_descriptor["max-instance-count"]) |
| 496 | if scaling_group_descriptor.get("scaling-policy"): |
| 497 | scaling_aspect["scaling-policy"] = scaling_group_descriptor["scaling-policy"] |
| 498 | if scaling_group_descriptor.get("scaling-config-action"): |
| 499 | scaling_aspect["scaling-config-action"] = scaling_group_descriptor["scaling-config-action"] |
| 500 | |
| 501 | delta = {"id": "{}-delta".format(scaling_aspect["id"])} |
| 502 | vdu_deltas = [] |
| 503 | for vdu in scaling_group_descriptor.get("vdu", ()): |
| 504 | vdu_delta = {} |
| 505 | if vdu.get("count"): |
| 506 | vdu_delta["number-of-instances"] = int(vdu["count"]) |
| 507 | if vdu.get("vdu-id-ref"): |
| 508 | vdu_delta["id"] = vdu["vdu-id-ref"] |
| 509 | vdu_deltas.append(vdu_delta) |
| 510 | if len(vdu_deltas) > 0: |
| 511 | delta["vdu-delta"] = vdu_deltas |
| 512 | scaling_aspect["aspect-delta-details"] = {"deltas": [delta]} |
| 513 | |
| 514 | scaling_aspects.append(scaling_aspect) |
| 515 | |
| 516 | if len(scaling_aspects) > 0: |
| 517 | sol006_vnfd["df"][0]["scaling-aspect"] = scaling_aspects |
| 518 | |
| 519 | |
| 520 | def _add_im_kdus_to_sol006_vnfd(im_vnfd, sol006_vnfd): |
| 521 | if im_vnfd.get("kdu"): |
| 522 | sol006_vnfd["kdu"] = im_vnfd["kdu"] |
| bravof | 2eccea2 | 2021-02-12 16:17:54 -0300 | [diff] [blame] | 523 | kdu_configs = [] |
| 524 | for a_kdu in sol006_vnfd["kdu"]: |
| 525 | if "kdu-configuration" in a_kdu: |
| 526 | kdu_config = a_kdu.pop("kdu-configuration") |
| 527 | kdu_config["id"] = a_kdu["name"] |
| 528 | kdu_configs.append(kdu_config) |
| garciaale | 0a517b9 | 2021-01-12 15:44:44 -0300 | [diff] [blame] | 529 | if len(sol006_vnfd.get("df", ())) == 0: |
| 530 | sol006_vnfd["df"] = [{"id": "default-df"}] |
| bravof | 2eccea2 | 2021-02-12 16:17:54 -0300 | [diff] [blame] | 531 | if len(kdu_configs) > 0: |
| 532 | _prepare_dict_entries_for_configurations(sol006_vnfd) |
| 533 | sol006_vnfd["df"][0]["lcm-operations-configuration"]["operate-vnf-op-config"]["day1-2"].extend(kdu_configs) |
| 534 | |
| garciaale | 0a517b9 | 2021-01-12 15:44:44 -0300 | [diff] [blame] | 535 | |
| 536 | |
| 537 | def _add_im_k8s_clusters_to_sol006_vnfd(im_vnfd, sol006_vnfd): |
| 538 | im_k8s_cluster = im_vnfd.get("k8s-cluster") |
| 539 | if not im_k8s_cluster: |
| 540 | return |
| 541 | |
| 542 | sol006_k8s_cluster = {} |
| 543 | if im_k8s_cluster.get("version"): |
| 544 | sol006_k8s_cluster["version"] = im_k8s_cluster["version"] |
| 545 | if im_k8s_cluster.get("cni"): |
| 546 | sol006_k8s_cluster["cni"] = im_k8s_cluster["cni"] |
| 547 | |
| 548 | nets = [] |
| 549 | k8s_cluster_ext_cpds = [] |
| 550 | for net in im_k8s_cluster.get("nets", ()): |
| 551 | if net.get("external-connection-point-ref"): |
| 552 | ext_cpd = {"id": "{}-ext".format(net["external-connection-point-ref"]), "k8s-cluster-net": net["id"]} |
| 553 | k8s_cluster_ext_cpds.append(ext_cpd) |
| 554 | nets.append({"id": net["id"]}) |
| 555 | if len(nets) > 0: |
| 556 | sol006_k8s_cluster["nets"] = nets |
| 557 | |
| 558 | sol006_vnfd["k8s-cluster"] = sol006_k8s_cluster |
| 559 | if len(k8s_cluster_ext_cpds) > 0: |
| 560 | if not sol006_vnfd.get("ext-cpd"): |
| 561 | sol006_vnfd["ext-cpd"] = [] |
| 562 | sol006_vnfd["ext-cpd"].extend(k8s_cluster_ext_cpds) |
| 563 | |
| 564 | |
| 565 | def _add_im_placement_groups_to_sol006_vnfd(im_vnfd, sol006_vnfd): |
| 566 | if im_vnfd.get("placement-groups"): |
| 567 | sol006_vnfd["placement-groups"] = im_vnfd["placement-groups"] |
| 568 | |
| 569 | |
| 570 | # ******************** NSD translation private functions ******************** |
| 571 | |
| 572 | def _remove_im_nsd_envelope(im_nsd): |
| 573 | # Data is wrapped as { nsd-catalog: { nsd: [ <data> ] } } |
| 574 | return list(im_nsd.values())[0]["nsd"][0] |
| 575 | |
| 576 | |
| 577 | def _add_im_nsd_basic_data_to_sol006_nsd(im_nsd, sol006_nsd): |
| 578 | sol006_nsd["id"] = im_nsd["id"] |
| 579 | if im_nsd.get("name"): |
| 580 | sol006_nsd["name"] = im_nsd["name"] |
| 581 | if im_nsd.get("description"): |
| 582 | sol006_nsd["description"] = im_nsd["description"] |
| 583 | if im_nsd.get("vendor"): |
| 584 | sol006_nsd["designer"] = im_nsd["vendor"] |
| 585 | if im_nsd.get("version"): |
| 586 | sol006_nsd["version"] = im_nsd["version"] |
| 587 | |
| 588 | |
| 589 | def _add_im_constituent_vnfds_to_sol006_nsd(im_nsd, sol006_nsd): |
| 590 | vnfd_ids = set() |
| 591 | for constituent_vnfd in im_nsd.get("constituent-vnfd", ()): |
| 592 | if constituent_vnfd.get("vnfd-id-ref"): |
| 593 | vnfd_ids.add(constituent_vnfd["vnfd-id-ref"]) |
| 594 | |
| 595 | if len(vnfd_ids) > 0: |
| 596 | sol006_nsd["vnfd-id"] = list(vnfd_ids) |
| 597 | |
| 598 | |
| 599 | def _add_im_vlds_to_sol006_nsd(im_nsd, sol006_nsd): |
| 600 | vlds = im_nsd.get("vld", []) |
| 601 | flattened_vlds = [{**vld, **cp_ref} for vld in vlds for cp_ref in vld.get("vnfd-connection-point-ref", ())] |
| 602 | all_vlds_by_member_vnf_index = {} |
| 603 | for vld in flattened_vlds: |
| 604 | member_vnf_index = str(vld.get("member-vnf-index-ref", "")) |
| 605 | if member_vnf_index in all_vlds_by_member_vnf_index: |
| 606 | all_vlds_by_member_vnf_index[member_vnf_index].append(vld) |
| 607 | else: |
| 608 | all_vlds_by_member_vnf_index[member_vnf_index] = [vld] |
| 609 | |
| 610 | df = {"id": "default-df", "vnf-profile": []} |
| 611 | |
| 612 | for member_vnf_index in all_vlds_by_member_vnf_index: |
| 613 | vnf_profile = {"id": member_vnf_index} |
| 614 | vnf_profile["vnfd-id"] = all_vlds_by_member_vnf_index.get(member_vnf_index, [{}])[0].get("vnfd-id-ref") |
| 615 | vnf_profile["virtual-link-connectivity"] = [] |
| 616 | for vld in all_vlds_by_member_vnf_index[member_vnf_index]: |
| 617 | virtual_link_connectivity = {"virtual-link-profile-id": vld["id"]} |
| 618 | virtual_link_connectivity["constituent-cpd-id"] = [{ |
| 619 | "constituent-base-element-id": member_vnf_index, |
| 620 | "constituent-cpd-id": "{}-ext".format(vld.get("vnfd-connection-point-ref")) |
| 621 | }] |
| 622 | if vld.get("ip-address"): |
| 623 | virtual_link_connectivity["constituent-cpd-id"][0]["ip-address"] = vld["ip-address"] |
| 624 | vnf_profile["virtual-link-connectivity"].append(virtual_link_connectivity) |
| 625 | |
| 626 | vlcs_by_virtual_link_profile = {} |
| 627 | for vlc in vnf_profile.get("virtual-link-connectivity"): |
| 628 | vl_profile_id = vlc.get("virtual-link-profile-id") |
| 629 | if vl_profile_id in vlcs_by_virtual_link_profile: |
| 630 | vlc_constituent_cpds = vlcs_by_virtual_link_profile[vl_profile_id].get("constituent-cpd-id") |
| 631 | vlc_constituent_cpds.extend(vlc.get("constituent-cpd-id")) |
| 632 | else: |
| 633 | vlcs_by_virtual_link_profile[vl_profile_id] = vlc |
| 634 | |
| 635 | vnf_profile["virtual-link-connectivity"] = list(vlcs_by_virtual_link_profile.values()) |
| 636 | |
| 637 | df["vnf-profile"].append(vnf_profile) |
| 638 | |
| 639 | sol006_nsd["df"] = [df] |
| 640 | |
| 641 | virtual_link_descs = [] |
| 642 | for vld in im_nsd.get("vld", ()): |
| 643 | virtual_link_desc = {"id": vld["id"]} |
| 644 | if vld.get("mgmt-network"): |
| 645 | virtual_link_desc["mgmt-network"] = vld["mgmt-network"] |
| 646 | if vld.get("vim-network-name"): |
| 647 | virtual_link_desc["vim-network-name"] = vld["vim-network-name"] |
| 648 | virtual_link_descs.append(virtual_link_desc) |
| 649 | |
| 650 | if len(virtual_link_descs) > 0: |
| 651 | sol006_nsd["virtual-link-desc"] = virtual_link_descs |