fix(vdu): vdu number of instances now is taking into account. Bug 1477
[osm/NBI.git] / osm_nbi / nbi.py
index 64f071e..ecd6a5a 100644 (file)
@@ -115,6 +115,8 @@ URL: /osm                                                       GET     POST
                 /<id>                                           O                       O       O
             /k8srepos                                           O       O
                 /<id>                                           O                               O
+            /osmrepos                                           O       O
+                /<id>                                           O                               O
 
         /nst/v1                                                 O       O
             /netslice_templates_content                         O       O
@@ -266,6 +268,12 @@ valid_url_methods = {
                                   "ROLE_PERMISSION": "k8srepos:id:"
                                   }
                          },
+            "osmrepos": {"METHODS": ("GET", "POST"),
+                         "ROLE_PERMISSION": "osmrepos:",
+                         "<ID>": {"METHODS": ("GET", "DELETE", "PATCH"),
+                                  "ROLE_PERMISSION": "osmrepos:id:"
+                                  }
+                         },
             "domains": {"METHODS": ("GET", ),
                         "ROLE_PERMISSION": "domains:",
                         },
@@ -299,9 +307,9 @@ valid_url_methods = {
                                         "nsd": {"METHODS": ("GET",),  # descriptor inside package
                                                 "ROLE_PERMISSION": "nsds:id:content:"
                                                 },
-                                        "artifacts": {"*": {"METHODS": ("GET",),
-                                                            "ROLE_PERMISSION": "nsds:id:nsd_artifact:"
-                                                            }
+                                        "artifacts": {"METHODS": ("GET",),
+                                                      "ROLE_PERMISSION": "nsds:id:nsd_artifact:",
+                                                      "*": None,
                                                       }
                                         }
                                },
@@ -336,9 +344,9 @@ valid_url_methods = {
                                       "vnfd": {"METHODS": ("GET", ),  # descriptor inside package
                                                "ROLE_PERMISSION": "vnfds:id:content:"
                                                },
-                                      "artifacts": {"*": {"METHODS": ("GET", ),
-                                                          "ROLE_PERMISSION": "vnfds:id:vnfd_artifact:"
-                                                          }
+                                      "artifacts": {"METHODS": ("GET", ),
+                                                    "ROLE_PERMISSION": "vnfds:id:vnfd_artifact:",
+                                                    "*": None,
                                                     },
                                       "action": {"METHODS": ("POST", ),
                                                  "ROLE_PERMISSION": "vnfds:id:action:"
@@ -400,6 +408,12 @@ valid_url_methods = {
                                        "ROLE_PERMISSION": "vnf_instances:id:"
                                        }
                               },
+            "subscriptions": {"METHODS": ("GET", "POST"),
+                              "ROLE_PERMISSION": "ns_subscriptions:",
+                              "<ID>": {"METHODS": ("GET", "DELETE"),
+                                       "ROLE_PERMISSION": "ns_subscriptions:id:"
+                                       }
+                              },
         }
     },
     "nst": {
@@ -420,9 +434,9 @@ valid_url_methods = {
                                             "nst": {"METHODS": ("GET",),  # descriptor inside package
                                                     "ROLE_PERMISSION": "slice_templates:id:content:"
                                                     },
-                                            "artifacts": {"*": {"METHODS": ("GET",),
-                                                                "ROLE_PERMISSION": "slice_templates:id:content:"
-                                                                }
+                                            "artifacts": {"METHODS": ("GET",),
+                                                          "ROLE_PERMISSION": "slice_templates:id:content:",
+                                                          "*": None
                                                           }
                                             }
                                    },
@@ -603,20 +617,14 @@ class Server(object):
             # TODO check that cherrypy close file. If not implement pending things to close  per thread next
             return data
         if accept:
-            if "application/json" in accept:
-                cherrypy.response.headers["Content-Type"] = 'application/json; charset=utf-8'
-                a = json.dumps(data, indent=4) + "\n"
-                return a.encode("utf8")
-            elif "text/html" in accept:
+            if "text/html" in accept:
                 return html.format(data, cherrypy.request, cherrypy.response, token_info)
-
-            elif "application/yaml" in accept or "*/*" in accept or "text/plain" in accept:
+            elif "application/yaml" in accept or "*/*" in accept:
                 pass
-            # if there is not any valid accept, raise an error. But if response is already an error, format in yaml
-            elif cherrypy.response.status >= 400:
-                raise cherrypy.HTTPError(HTTPStatus.NOT_ACCEPTABLE.value,
-                                         "Only 'Accept' of type 'application/json' or 'application/yaml' "
-                                         "for output format are available")
+            elif "application/json" in accept or (cherrypy.response.status and cherrypy.response.status >= 300):
+                cherrypy.response.headers["Content-Type"] = 'application/json; charset=utf-8'
+                a = json.dumps(data, indent=4) + "\n"
+                return a.encode("utf8") 
         cherrypy.response.headers["Content-Type"] = 'application/yaml'
         return yaml.safe_dump(data, explicit_start=True, indent=4, default_flow_style=False, tags=False,
                               encoding='utf-8', allow_unicode=True)  # , canonical=True, default_style='"'
@@ -807,8 +815,9 @@ class Server(object):
                         return_text += "  {}: {}\n".format(k, v)
                 elif cherrypy.request.method == 'GET':
                     for k, v in kwargs.items():
-                        self.engine.msg.write(main_topic, k, yaml.load(v), Loader=yaml.SafeLoader)
-                        return_text += "  {}: {}\n".format(k, yaml.load(v), Loader=yaml.SafeLoader)
+                        v_dict = yaml.load(v, Loader=yaml.SafeLoader)
+                        self.engine.msg.write(main_topic, k, v_dict)
+                        return_text += "  {}: {}\n".format(k, v_dict)
             except Exception as e:
                 return_text += "Error: " + str(e)
             return_text += "</pre></html>\n"
@@ -852,7 +861,9 @@ class Server(object):
             elif "<ID>" in reference:
                 reference = reference["<ID>"]
             elif "*" in reference:
-                reference = reference["*"]
+                # if there is content
+                if reference["*"]:
+                    reference = reference["*"]
                 break
             else:
                 raise NbiException("Unexpected URL item {}".format(arg), HTTPStatus.METHOD_NOT_ALLOWED)
@@ -997,8 +1008,7 @@ class Server(object):
             engine_session = self._manage_admin_query(token_info, kwargs, method, _id)
             indata = self._format_in(kwargs)
             engine_topic = topic
-            if topic == "subscriptions":
-                engine_topic = main_topic + "_" + topic
+
             if item and topic != "pm_jobs":
                 engine_topic = item
 
@@ -1027,6 +1037,9 @@ class Server(object):
             if engine_topic == "vims":   # TODO this is for backward compatibility, it will be removed in the future
                 engine_topic = "vim_accounts"
 
+            if topic == "subscriptions":
+                engine_topic = main_topic + "_" + topic
+
             if method == "GET":
                 if item in ("nsd_content", "package_content", "artifacts", "vnfd", "nsd", "nst", "nst_content"):
                     if item in ("vnfd", "nsd", "nst"):
@@ -1041,12 +1054,12 @@ class Server(object):
                                                          cherrypy.request.headers.get("Accept"))
                     outdata = file
                 elif not _id:
-                    outdata = self.engine.get_item_list(engine_session, engine_topic, kwargs)
+                    outdata = self.engine.get_item_list(engine_session, engine_topic, kwargs, api_req=True)
                 else:
                     if item == "reports":
                         # TODO check that project_id (_id in this context) has permissions
                         _id = args[0]
-                    outdata = self.engine.get_item(engine_session, engine_topic, _id)
+                    outdata = self.engine.get_item(engine_session, engine_topic, _id, True)
 
             elif method == "POST":
                 cherrypy.response.status = HTTPStatus.CREATED.value
@@ -1100,6 +1113,14 @@ class Server(object):
                     self._set_location_header(main_topic, version, "vnfpkg_op_occs", _id)
                     outdata = {"id": _id}
                     cherrypy.response.status = HTTPStatus.ACCEPTED.value
+                elif topic == "subscriptions":
+                    _id, _ = self.engine.new_item(rollback, engine_session, engine_topic, indata, kwargs)
+                    self._set_location_header(main_topic, version, topic, _id)
+                    link = {}
+                    link["self"] = cherrypy.response.headers["Location"]
+                    outdata = {"id": _id, "filter": indata["filter"], "callbackUri": indata["CallbackUri"],
+                               "_links": link}
+                    cherrypy.response.status = HTTPStatus.CREATED.value
                 else:
                     _id, op_id = self.engine.new_item(rollback, engine_session, engine_topic, indata, kwargs,
                                                       cherrypy.request.headers)
@@ -1192,6 +1213,9 @@ class Server(object):
                     if rollback_item.get("operation") == "set":
                         self.engine.db.set_one(rollback_item["topic"], {"_id": rollback_item["_id"]},
                                                rollback_item["content"], fail_on_empty=False)
+                    elif rollback_item.get("operation") == "del_list":
+                        self.engine.db.del_list(rollback_item["topic"], rollback_item["filter"], 
+                                                fail_on_empty=False)
                     else:
                         self.engine.db.del_one(rollback_item["topic"], {"_id": rollback_item["_id"]},
                                                fail_on_empty=False)