+ @staticmethod
+ def validate_mgmt_interfaces_connection_points(indata):
+ if not indata.get("vdu"):
+ return
+ if not indata.get("mgmt-interface"):
+ raise EngineException("'mgmt-interface' is a mandatory field and it is not defined",
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+ if indata["mgmt-interface"].get("cp"):
+ for cp in get_iterable(indata.get("connection-point")):
+ if cp["name"] == indata["mgmt-interface"]["cp"]:
+ break
+ else:
+ raise EngineException("mgmt-interface:cp='{}' must match an existing connection-point"
+ .format(indata["mgmt-interface"]["cp"]),
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+
+ @staticmethod
+ def validate_vdu_connection_point_refs(vdu, indata):
+ icp_refs = []
+ ecp_refs = []
+ for interface in get_iterable(vdu.get("interface")):
+ if interface.get("external-connection-point-ref"):
+ if interface.get("external-connection-point-ref") in ecp_refs:
+ raise EngineException("vdu[id='{}']:interface[name='{}']:external-connection-point-ref='{}' "
+ "is referenced by other interface"
+ .format(vdu["id"], interface["name"],
+ interface["external-connection-point-ref"]),
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+ ecp_refs.append(interface.get("external-connection-point-ref"))
+ for cp in get_iterable(indata.get("connection-point")):
+ if cp["name"] == interface["external-connection-point-ref"]:
+ break
+ else:
+ raise EngineException("vdu[id='{}']:interface[name='{}']:external-connection-point-ref='{}' "
+ "must match an existing connection-point"
+ .format(vdu["id"], interface["name"],
+ interface["external-connection-point-ref"]),
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+ elif interface.get("internal-connection-point-ref"):
+ if interface.get("internal-connection-point-ref") in icp_refs:
+ raise EngineException("vdu[id='{}']:interface[name='{}']:internal-connection-point-ref='{}' "
+ "is referenced by other interface"
+ .format(vdu["id"], interface["name"],
+ interface["internal-connection-point-ref"]),
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+ icp_refs.append(interface.get("internal-connection-point-ref"))
+ for internal_cp in get_iterable(vdu.get("internal-connection-point")):
+ if interface["internal-connection-point-ref"] == internal_cp.get("id"):
+ break
+ else:
+ raise EngineException("vdu[id='{}']:interface[name='{}']:internal-connection-point-ref='{}' "
+ "must match an existing vdu:internal-connection-point"
+ .format(vdu["id"], interface["name"],
+ interface["internal-connection-point-ref"]),
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+
+ def _validate_vdu_charms_in_package(self, storage_params, vdu, indata):
+ if not vdu.get("vdu-configuration"):
+ return
+ if vdu["vdu-configuration"].get("juju"):
+ if not self._validate_package_folders(storage_params, 'charms'):
+ raise EngineException("Charm defined in vnf[id={}]:vdu[id={}] but not present in "
+ "package".format(indata["id"], vdu["id"]))
+
+ def _validate_vdu_cloud_init_in_package(self, storage_params, vdu, indata):
+ if not vdu.get("cloud-init-file"):
+ return
+ if not self._validate_package_folders(storage_params, 'cloud_init', vdu["cloud-init-file"]):
+ raise EngineException("Cloud-init defined in vnf[id={}]:vdu[id={}] but not present in "
+ "package".format(indata["id"], vdu["id"]))
+
+ def _validate_vnf_charms_in_package(self, storage_params, indata):
+ if not indata.get("vnf-configuration"):
+ return
+ if indata["vnf-configuration"].get("juju"):
+ if not self._validate_package_folders(storage_params, 'charms'):
+ raise EngineException("Charm defined in vnf[id={}] but not present in "
+ "package".format(indata["id"]))
+
+ def _validate_package_folders(self, storage_params, folder, file=None):
+ if not storage_params or not storage_params.get("pkg-dir"):
+ return False
+ else:
+ if self.fs.file_exists("{}_".format(storage_params["folder"]), 'dir'):
+ f = "{}_/{}/{}".format(storage_params["folder"], storage_params["pkg-dir"], folder)
+ else:
+ f = "{}/{}/{}".format(storage_params["folder"], storage_params["pkg-dir"], folder)
+ if file:
+ return self.fs.file_exists("{}/{}".format(f, file), 'file')
+ else:
+ if self.fs.file_exists(f, 'dir'):
+ if self.fs.dir_ls(f):
+ return True
+ return False
+
+ @staticmethod
+ def validate_internal_vlds(indata):
+ vld_names = [] # For detection of duplicated VLD names
+ for ivld in get_iterable(indata.get("internal-vld")):
+ ivld_name = ivld.get("name")
+ if ivld_name and ivld_name in vld_names:
+ raise EngineException("Duplicated VLD name '{}' in vnfd[id={}]:internal-vld[id={}]"
+ .format(ivld["name"], indata["id"], ivld["id"]),
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+ else:
+ vld_names.append(ivld_name)
+
+ for icp in get_iterable(ivld.get("internal-connection-point")):
+ icp_mark = False
+ for vdu in get_iterable(indata.get("vdu")):
+ for internal_cp in get_iterable(vdu.get("internal-connection-point")):
+ if icp["id-ref"] == internal_cp["id"]:
+ icp_mark = True
+ break
+ if icp_mark:
+ break
+ else:
+ raise EngineException("internal-vld[id='{}']:internal-connection-point='{}' must match an existing "
+ "vdu:internal-connection-point".format(ivld["id"], icp["id-ref"]),
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+ if ivld.get("ip-profile-ref"):
+ for ip_prof in get_iterable(indata.get("ip-profiles")):
+ if ip_prof["name"] == get_iterable(ivld.get("ip-profile-ref")):
+ break
+ else:
+ raise EngineException("internal-vld[id='{}']:ip-profile-ref='{}' does not exist".format(
+ ivld["id"], ivld["ip-profile-ref"]),
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+
+ @staticmethod
+ def validate_monitoring_params(indata):
+ for mp in get_iterable(indata.get("monitoring-param")):
+ if mp.get("vdu-monitoring-param"):
+ mp_vmp_mark = False
+ for vdu in get_iterable(indata.get("vdu")):
+ for vmp in get_iterable(vdu.get("monitoring-param")):
+ if vmp["id"] == mp["vdu-monitoring-param"].get("vdu-monitoring-param-ref") and vdu["id"] == \
+ mp["vdu-monitoring-param"]["vdu-ref"]:
+ mp_vmp_mark = True
+ break
+ if mp_vmp_mark:
+ break
+ else:
+ raise EngineException("monitoring-param:vdu-monitoring-param:vdu-monitoring-param-ref='{}' not "
+ "defined at vdu[id='{}'] or vdu does not exist"
+ .format(mp["vdu-monitoring-param"]["vdu-monitoring-param-ref"],
+ mp["vdu-monitoring-param"]["vdu-ref"]),
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+ elif mp.get("vdu-metric"):
+ mp_vm_mark = False
+ for vdu in get_iterable(indata.get("vdu")):
+ if vdu.get("vdu-configuration"):
+ for metric in get_iterable(vdu["vdu-configuration"].get("metrics")):
+ if metric["name"] == mp["vdu-metric"]["vdu-metric-name-ref"] and vdu["id"] == \
+ mp["vdu-metric"]["vdu-ref"]:
+ mp_vm_mark = True
+ break
+ if mp_vm_mark:
+ break
+ else:
+ raise EngineException("monitoring-param:vdu-metric:vdu-metric-name-ref='{}' not defined at "
+ "vdu[id='{}'] or vdu does not exist"
+ .format(mp["vdu-metric"]["vdu-metric-name-ref"],
+ mp["vdu-metric"]["vdu-ref"]),
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+
+ @staticmethod
+ def validate_scaling_group_descriptor(indata):
+ for sgd in get_iterable(indata.get("scaling-group-descriptor")):
+ for sp in get_iterable(sgd.get("scaling-policy")):
+ for sc in get_iterable(sp.get("scaling-criteria")):
+ for mp in get_iterable(indata.get("monitoring-param")):
+ if mp["id"] == get_iterable(sc.get("vnf-monitoring-param-ref")):
+ break
+ else:
+ raise EngineException("scaling-group-descriptor[name='{}']:scaling-criteria[name='{}']:"
+ "vnf-monitoring-param-ref='{}' not defined in any monitoring-param"
+ .format(sgd["name"], sc["name"], sc["vnf-monitoring-param-ref"]),
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+ for sgd_vdu in get_iterable(sgd.get("vdu")):
+ sgd_vdu_mark = False
+ for vdu in get_iterable(indata.get("vdu")):
+ if vdu["id"] == sgd_vdu["vdu-id-ref"]:
+ sgd_vdu_mark = True
+ break
+ if sgd_vdu_mark:
+ break
+ else:
+ raise EngineException("scaling-group-descriptor[name='{}']:vdu-id-ref={} does not match any vdu"
+ .format(sgd["name"], sgd_vdu["vdu-id-ref"]),
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+ for sca in get_iterable(sgd.get("scaling-config-action")):
+ if not indata.get("vnf-configuration"):
+ raise EngineException("'vnf-configuration' not defined in the descriptor but it is referenced by "
+ "scaling-group-descriptor[name='{}']:scaling-config-action"
+ .format(sgd["name"]),
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+ for primitive in get_iterable(indata["vnf-configuration"].get("config-primitive")):
+ if primitive["name"] == sca["vnf-config-primitive-name-ref"]:
+ break
+ else:
+ raise EngineException("scaling-group-descriptor[name='{}']:scaling-config-action:vnf-config-"
+ "primitive-name-ref='{}' does not match any "
+ "vnf-configuration:config-primitive:name"
+ .format(sgd["name"], sca["vnf-config-primitive-name-ref"]),
+ http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+
+ def delete_extra(self, session, _id, db_content, not_send_msg=None):
+ """
+ Deletes associate file system storage (via super)
+ Deletes associated vnfpkgops from database.
+ :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
+ :param _id: server internal id
+ :param db_content: The database content of the descriptor
+ :return: None
+ :raises: FsException in case of error while deleting associated storage
+ """
+ super().delete_extra(session, _id, db_content, not_send_msg)
+ self.db.del_list("vnfpkgops", {"vnfPkgId": _id})
+
+ def sol005_projection(self, data):
+ data["onboardingState"] = data["_admin"]["onboardingState"]
+ data["operationalState"] = data["_admin"]["operationalState"]
+ data["usageState"] = data["_admin"]["usageState"]
+
+ links = {}
+ links["self"] = {"href": "/vnfpkgm/v1/vnf_packages/{}".format(data["_id"])}
+ links["vnfd"] = {"href": "/vnfpkgm/v1/vnf_packages/{}/vnfd".format(data["_id"])}
+ links["packageContent"] = {"href": "/vnfpkgm/v1/vnf_packages/{}/package_content".format(data["_id"])}
+ data["_links"] = links
+
+ return super().sol005_projection(data)
+