X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FNBI.git;a=blobdiff_plain;f=osm_nbi%2Fdescriptor_topics.py;h=bcd6a039385476a9c3c7d1b5181164186b590354;hp=18ce3e7c0126393d42c4cb8f4a8442b677c33591;hb=0f9b9661f5c7080ea85b158ffa418c1842e96ad2;hpb=26301bb2f455452e6daa3aec0d21288f6af246cb diff --git a/osm_nbi/descriptor_topics.py b/osm_nbi/descriptor_topics.py index 18ce3e7..bcd6a03 100644 --- a/osm_nbi/descriptor_topics.py +++ b/osm_nbi/descriptor_topics.py @@ -39,6 +39,27 @@ class DescriptorTopic(BaseTopic): def check_conflict_on_edit(self, session, final_content, edit_content, _id): super().check_conflict_on_edit(session, final_content, edit_content, _id) + + def _check_unique_id_name(descriptor, position=""): + for desc_key, desc_item in descriptor.items(): + if isinstance(desc_item, list) and desc_item: + used_ids = [] + desc_item_id = None + for index, list_item in enumerate(desc_item): + if isinstance(list_item, dict): + _check_unique_id_name(list_item, "{}.{}[{}]" + .format(position, desc_key, index)) + # Base case + if index == 0 and (list_item.get("id") or list_item.get("name")): + desc_item_id = "id" if list_item.get("id") else "name" + if desc_item_id and list_item.get(desc_item_id): + if list_item[desc_item_id] in used_ids: + position = "{}.{}[{}]".format(position, desc_key, index) + raise EngineException("Error: identifier {} '{}' is not unique and repeats at '{}'" + .format(desc_item_id, list_item[desc_item_id], + position), HTTPStatus.UNPROCESSABLE_ENTITY) + used_ids.append(list_item[desc_item_id]) + _check_unique_id_name(final_content) # 1. validate again with pyangbind # 1.1. remove internal keys internal_keys = {} @@ -73,12 +94,13 @@ class DescriptorTopic(BaseTopic): content["_admin"]["operationalState"] = "DISABLED" content["_admin"]["usageState"] = "NOT_IN_USE" - def delete_extra(self, session, _id, db_content): + def delete_extra(self, session, _id, db_content, not_send_msg=None): """ Deletes file system storage associated with the descriptor :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 + :param not_send_msg: To not send message (False) or store content (list) instead :return: None if ok or raises EngineException with the problem """ self.fs.file_delete(_id, ignore_non_exist=True) @@ -487,8 +509,17 @@ class VnfdTopic(DescriptorTopic): http_code=HTTPStatus.UNPROCESSABLE_ENTITY) for vdu in get_iterable(indata.get("vdu")): + 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 @@ -498,8 +529,14 @@ class VnfdTopic(DescriptorTopic): .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