move version package to __init__
[osm/NBI.git] / osm_nbi / admin_topics.py
index 5b37bf0..90c5d08 100644 (file)
@@ -302,12 +302,13 @@ class CommonVimWimSdn(BaseTopic):
 
         return "{}:0".format(content["_id"])
 
-    def delete(self, session, _id, dry_run=False):
+    def delete(self, session, _id, dry_run=False, not_send_msg=None):
         """
         Delete item by its internal _id
         :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
         :param _id: server internal id
         :param dry_run: make checking but do not delete
+        :param not_send_msg: To not send message (False) or store content (list) instead
         :return: operation id if it is ordered to delete. None otherwise
         """
 
@@ -344,7 +345,7 @@ class CommonVimWimSdn(BaseTopic):
         if session["force"]:
             self.db.del_one(self.topic, {"_id": _id})
             op_id = None
-            self._send_msg("deleted", {"_id": _id, "op_id": op_id})
+            self._send_msg("deleted", {"_id": _id, "op_id": op_id}, not_send_msg=not_send_msg)
         else:
             update_dict["_admin.to_delete"] = True
             self.db.set_one(self.topic, {"_id": _id},
@@ -354,7 +355,7 @@ class CommonVimWimSdn(BaseTopic):
             # the number of operations is the operation_id. db_content does not contains the new operation inserted,
             # so the -1 is not needed
             op_id = "{}:{}".format(db_content["_id"], len(db_content["_admin"]["operations"]))
-            self._send_msg("delete", {"_id": _id, "op_id": op_id})
+            self._send_msg("delete", {"_id": _id, "op_id": op_id}, not_send_msg=not_send_msg)
         return op_id
 
 
@@ -403,6 +404,25 @@ class SdnTopic(CommonVimWimSdn):
     password_to_encrypt = "password"
     config_to_encrypt = {}
 
+    def _obtain_url(self, input, create):
+        if input.get("ip") or input.get("port"):
+            if not input.get("ip") or not input.get("port") or input.get('url'):
+                raise ValidationError("You must provide both 'ip' and 'port' (deprecated); or just 'url' (prefered)")
+            input['url'] = "http://{}:{}/".format(input["ip"], input["port"])
+            del input["ip"]
+            del input["port"]
+        elif create and not input.get('url'):
+            raise ValidationError("You must provide 'url'")
+        return input
+
+    def _validate_input_new(self, input, force=False):
+        input = super()._validate_input_new(input, force)
+        return self._obtain_url(input, True)
+
+    def _validate_input_edit(self, input, force=False):
+        input = super()._validate_input_edit(input, force)
+        return self._obtain_url(input, False)
+
 
 class K8sClusterTopic(CommonVimWimSdn):
     topic = "k8sclusters"
@@ -581,7 +601,7 @@ class UserTopicAuth(UserTopic):
 
             rollback.append({"topic": self.topic, "_id": _id})
             # del content["password"]
-            # self._send_msg("created", content)
+            # self._send_msg("created", content, not_send_msg=not_send_msg)
             return _id, None
         except ValidationError as e:
             raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
@@ -733,7 +753,7 @@ class UserTopicAuth(UserTopic):
             user_list = [usr for usr in user_list if usr["username"] == session["username"]]
         return user_list
 
-    def delete(self, session, _id, dry_run=False):
+    def delete(self, session, _id, dry_run=False, not_send_msg=None):
         """
         Delete item by its internal _id
 
@@ -741,6 +761,7 @@ class UserTopicAuth(UserTopic):
         :param _id: server internal id
         :param force: indicates if deletion must be forced in case of conflict
         :param dry_run: make checking but do not delete
+        :param not_send_msg: To not send message (False) or store content (list) instead
         :return: dictionary with deleted item _id. It raises EngineException on error: not found, conflict, ...
         """
         # Allow _id to be a name or uuid
@@ -865,7 +886,7 @@ class ProjectTopicAuth(ProjectTopic):
             self.format_on_new(content, project_id=session["project_id"], make_public=session["public"])
             _id = self.auth.create_project(content)
             rollback.append({"topic": self.topic, "_id": _id})
-            # self._send_msg("created", content)
+            # self._send_msg("created", content, not_send_msg=not_send_msg)
             return _id, None
         except ValidationError as e:
             raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
@@ -905,13 +926,14 @@ class ProjectTopicAuth(ProjectTopic):
             project_list = [proj for proj in project_list if proj["_id"] in projects]
         return project_list
 
-    def delete(self, session, _id, dry_run=False):
+    def delete(self, session, _id, dry_run=False, not_send_msg=None):
         """
         Delete item by its internal _id
 
         :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
         :param _id: server internal id
         :param dry_run: make checking but do not delete
+        :param not_send_msg: To not send message (False) or store content (list) instead
         :return: dictionary with deleted item _id. It raises EngineException on error: not found, conflict, ...
         """
         # Allow _id to be a name or uuid
@@ -1085,11 +1107,12 @@ class RoleTopicAuth(BaseTopic):
             raise EngineException("You cannot delete role '{}'".format(role["name"]), http_code=HTTPStatus.FORBIDDEN)
 
         # If any user is using this role, raise CONFLICT exception
-        for user in self.auth.get_user_list():
-            for prm in user.get("project_role_mappings"):
-                if prm["role"] == _id:
-                    raise EngineException("Role '{}' ({}) is being used by user '{}'"
-                                          .format(role["name"], _id, user["username"]), HTTPStatus.CONFLICT)
+        if not session["force"]:
+            for user in self.auth.get_user_list():
+                for prm in user.get("project_role_mappings"):
+                    if prm["role"] == _id:
+                        raise EngineException("Role '{}' ({}) is being used by user '{}'"
+                                              .format(role["name"], _id, user["username"]), HTTPStatus.CONFLICT)
 
     @staticmethod
     def format_on_new(content, project_id=None, make_public=False):   # TO BE REMOVED ?
@@ -1194,18 +1217,19 @@ class RoleTopicAuth(BaseTopic):
             content["_id"] = rid
             # _id = self.db.create(self.topic, content)
             rollback.append({"topic": self.topic, "_id": rid})
-            # self._send_msg("created", content)
+            # self._send_msg("created", content, not_send_msg=not_send_msg)
             return rid, None
         except ValidationError as e:
             raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
 
-    def delete(self, session, _id, dry_run=False):
+    def delete(self, session, _id, dry_run=False, not_send_msg=None):
         """
         Delete item by its internal _id
 
         :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
         :param _id: server internal id
         :param dry_run: make checking but do not delete
+        :param not_send_msg: To not send message (False) or store content (list) instead
         :return: dictionary with deleted item _id. It raises EngineException on error: not found, conflict, ...
         """
         filter_q = {BaseTopic.id_field(self.topic, _id): _id}