fixing dockerfile.local
[osm/NBI.git] / osm_nbi / descriptor_topics.py
index 9e367c9..6285e38 100644 (file)
@@ -23,24 +23,36 @@ class DescriptorTopic(BaseTopic):
         BaseTopic.__init__(self, db, fs, msg)
 
     def check_conflict_on_edit(self, session, final_content, edit_content, _id, force=False):
-        # check that this id is not present
-        _filter = {"id": final_content["id"]}
-        if _id:
+        # 1. validate again with pyangbind
+        # 1.1. remove internal keys
+        internal_keys = {}
+        for k in ("_id", "_admin"):
+            if k in final_content:
+                internal_keys[k] = final_content.pop(k)
+        serialized = self._validate_input_new(final_content, force)
+        # 1.2. modify final_content with a serialized version
+        final_content.clear()
+        final_content.update(serialized)
+        # 1.3. restore internal keys
+        for k, v in internal_keys.items():
+            final_content[k] = v
+
+        # 2. check that this id is not present
+        if "id" in edit_content:
+            _filter = self._get_project_filter(session, write=False, show_all=False)
+            _filter["id"] = final_content["id"]
             _filter["_id.neq"] = _id
-
-        _filter.update(self._get_project_filter(session, write=False, show_all=False))
-        if self.db.get_one(self.topic, _filter, fail_on_empty=False):
-            raise EngineException("{} with id '{}' already exists for this project".format(self.topic[:-1],
-                                                                                           final_content["id"]),
-                                  HTTPStatus.CONFLICT)
-        # TODO validate with pyangbind. Load and dumps to convert data types
+            if self.db.get_one(self.topic, _filter, fail_on_empty=False):
+                raise EngineException("{} with id '{}' already exists for this project".format(self.topic[:-1],
+                                                                                               final_content["id"]),
+                                      HTTPStatus.CONFLICT)
 
     @staticmethod
     def format_on_new(content, project_id=None, make_public=False):
         BaseTopic.format_on_new(content, project_id=project_id, make_public=make_public)
         content["_admin"]["onboardingState"] = "CREATED"
         content["_admin"]["operationalState"] = "DISABLED"
-        content["_admin"]["usageSate"] = "NOT_IN_USE"
+        content["_admin"]["usageState"] = "NOT_IN_USE"
 
     def delete(self, session, _id, force=False, dry_run=False):
         """
@@ -389,6 +401,23 @@ class VnfdTopic(DescriptorTopic):
             clean_indata = clean_indata['vnfd:vnfd'][0]
         return clean_indata
 
+    def check_conflict_on_edit(self, session, final_content, edit_content, _id, force=False):
+        super().check_conflict_on_edit(session, final_content, edit_content, _id, force=force)
+
+        # set type of vnfd
+        contains_pdu = False
+        contains_vdu = False
+        for vdu in get_iterable(final_content.get("vdu")):
+            if vdu.get("pdu-type"):
+                contains_pdu = True
+            else:
+                contains_vdu = True
+        if contains_pdu:
+            final_content["_admin"]["type"] = "hnfd" if contains_vdu else "pnfd"
+        elif contains_vdu:
+            final_content["_admin"]["type"] = "vnfd"
+        # if neither vud nor pdu do not fill type
+
     def check_conflict_on_del(self, session, _id, force=False):
         """
         Check that there is not any NSD that uses this VNFD. Only NSDs belonging to this project are considered. Note
@@ -418,20 +447,20 @@ class VnfdTopic(DescriptorTopic):
             raise EngineException("There is soame NSD that depends on this VNFD", http_code=HTTPStatus.CONFLICT)
 
     def _validate_input_new(self, indata, force=False):
-        # TODO validate with pyangbind, serialize
         indata = self.pyangbind_validation("vnfds", indata, force)
         # Cross references validation in the descriptor
-        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"]),
+        if indata.get("vdu"):
+            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)
 
         for vdu in get_iterable(indata.get("vdu")):
             for interface in get_iterable(vdu.get("interface")):
@@ -551,10 +580,11 @@ class VnfdTopic(DescriptorTopic):
                                           "vnf-configuration:config-primitive:name"
                                           .format(sgd["name"], sca["vnf-config-primitive-name-ref"]),
                                           http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
+        # TODO validata that if contains cloud-init-file or charms, have artifacts _admin.storage."pkg-dir" is not none
         return indata
 
     def _validate_input_edit(self, indata, force=False):
-        # TODO validate with pyangbind, serialize
+        # not needed to validate with pyangbind becuase it will be validated at check_conflict_on_edit
         return indata
 
 
@@ -586,13 +616,12 @@ class NsdTopic(DescriptorTopic):
         return clean_indata
 
     def _validate_input_new(self, indata, force=False):
-
-        # TODO validate with pyangbind, serialize
         indata = self.pyangbind_validation("nsds", indata, force)
+        # TODO validata that if contains cloud-init-file or charms, have artifacts _admin.storage."pkg-dir" is not none
         return indata
 
     def _validate_input_edit(self, indata, force=False):
-        # TODO validate with pyangbind, serialize
+        # not needed to validate with pyangbind becuase it will be validated at check_conflict_on_edit
         return indata
 
     def _check_descriptor_dependencies(self, session, descriptor):
@@ -615,7 +644,8 @@ class NsdTopic(DescriptorTopic):
     def check_conflict_on_edit(self, session, final_content, edit_content, _id, force=False):
         super().check_conflict_on_edit(session, final_content, edit_content, _id, force=force)
 
-        self._check_descriptor_dependencies(session, final_content)
+        if not force:
+            self._check_descriptor_dependencies(session, final_content)
 
     def check_conflict_on_del(self, session, _id, force=False):
         """
@@ -657,16 +687,6 @@ class NstTopic(DescriptorTopic):
             clean_indata = clean_indata['nst'][0]
         return clean_indata
 
-    def _validate_input_new(self, indata, force=False):
-        # transform netslice-subnet:nsd-ref to string
-        if indata.get("netslice-subnet"):
-            for nsd_ref in indata["netslice-subnet"]:
-                if "nsd-ref" in nsd_ref:
-                    nsd_ref["nsd-ref"] = str(nsd_ref["nsd-ref"])
-
-        # TODO validate with pyangbind, serialize
-        return indata
-
     def _validate_input_edit(self, indata, force=False):
         # TODO validate with pyangbind, serialize
         return indata
@@ -698,15 +718,21 @@ class NstTopic(DescriptorTopic):
         Check that there is not any NSIR that uses this NST. Only NSIRs belonging to this project are considered. Note
         that NST can be public and be used by other projects.
         :param session:
-        :param _id: nsd internal id
+        :param _id: nst internal id
         :param force: Avoid this checking
         :return: None or raises EngineException with the conflict
         """
         # TODO: Check this method
         if force:
             return
+        # Get Network Slice Template from Database
         _filter = self._get_project_filter(session, write=False, show_all=False)
-        _filter["nst"] = _id
+        _filter["_id"] = _id
+        nst = self.db.get_one("nst", _filter)
+        
+        # Search NSIs using NST via nst-ref
+        _filter = self._get_project_filter(session, write=False, show_all=False)
+        _filter["nst-ref"] = nst["id"]
         if self.db.get_list("nsis", _filter):
             raise EngineException("There is some NSIS that depends on this NST", http_code=HTTPStatus.CONFLICT)
 
@@ -722,10 +748,10 @@ class PduTopic(BaseTopic):
 
     @staticmethod
     def format_on_new(content, project_id=None, make_public=False):
-        BaseTopic.format_on_new(content, project_id=None, make_public=make_public)
+        BaseTopic.format_on_new(content, project_id=project_id, make_public=make_public)
         content["_admin"]["onboardingState"] = "CREATED"
-        content["_admin"]["operationalState"] = "DISABLED"
-        content["_admin"]["usageSate"] = "NOT_IN_USE"
+        content["_admin"]["operationalState"] = "ENABLED"
+        content["_admin"]["usageState"] = "NOT_IN_USE"
 
     def check_conflict_on_del(self, session, _id, force=False):
         if force: