Adding flake8 test. Fix needed corrections 59/6159/5
authortierno <alfonso.tiernosepulveda@telefonica.com>
Wed, 16 May 2018 17:05:16 +0000 (19:05 +0200)
committertierno <alfonso.tiernosepulveda@telefonica.com>
Thu, 17 May 2018 08:58:39 +0000 (08:58 +0000)
Change-Id: I78fc3b8ff2522fec0ba603335a83409664aff3c6
Signed-off-by: tierno <alfonso.tiernosepulveda@telefonica.com>
devops-stages/stage-test.sh
osm_nbi/engine.py
osm_nbi/html_out.py
osm_nbi/html_public/version
osm_nbi/nbi.py
osm_nbi/test/test.py
osm_nbi/test/upload.py
osm_nbi/validation.py
setup.py
tox.ini

index 0333d84..4784abd 100755 (executable)
@@ -1,2 +1,2 @@
 #!/bin/sh
-#tox
+tox -e flake8
index 4d611cc..219becf 100644 (file)
@@ -41,7 +41,7 @@ def _deep_update(dict_to_change, dict_reference):
         if dict_reference[k] is None:   # None->Anything
             if k in dict_to_change:
                 del dict_to_change[k]
-        elif not isinstance(dict_reference[k], dict):  #  NotDict->Anything
+        elif not isinstance(dict_reference[k], dict):  # NotDict->Anything
             dict_to_change[k] = dict_reference[k]
         elif k not in dict_to_change:  # Dict->Empty
             dict_to_change[k] = deepcopy(dict_reference[k])
@@ -321,7 +321,10 @@ class Engine(object):
         elif item == "nsrs":
             pass
         elif item == "vim_accounts" or item == "sdns":
-            if self.db.get_one(item, {"name": indata.get("name")}, fail_on_empty=False, fail_on_more=False):
+            filter = {"name": indata.get("name")}
+            if id:
+                filter["_id.neq"] = id
+            if self.db.get_one(item, filter, fail_on_empty=False, fail_on_more=False):
                 raise EngineException("name '{}' already exists for {}".format(indata["name"], item),
                                       HTTPStatus.CONFLICT)
 
@@ -342,11 +345,11 @@ class Engine(object):
                     break
             else:
                 raise EngineException("Invalid parameter member_vnf_index='{}' is not one of the nsd "
-                                          "constituent-vnfd".format(indata["member_vnf_index"]))
+                                      "constituent-vnfd".format(indata["member_vnf_index"]))
 
     def _format_new_data(self, session, item, indata):
         now = time()
-        if not "_admin" in indata:
+        if "_admin" not in indata:
             indata["_admin"] = {}
         indata["_admin"]["created"] = now
         indata["_admin"]["modified"] = now
@@ -476,7 +479,8 @@ class Engine(object):
                         storage["pkg-dir"] = tarname_path[0]
                         if len(tarname_path) == 2:
                             if descriptor_file_name:
-                                raise EngineException("Found more than one descriptor file at package descriptor tar.gz")
+                                raise EngineException(
+                                    "Found more than one descriptor file at package descriptor tar.gz")
                             descriptor_file_name = tarname
                 if not descriptor_file_name:
                     raise EngineException("Not found any descriptor file at package descriptor tar.gz")
@@ -547,11 +551,12 @@ class Engine(object):
                 "description": ns_request.get("nsDescription", ""),
                 "constituent-vnfr-ref": [],
 
-                "operational-status": "init",    #  typedef ns-operational-
-                "config-status": "init",         #  typedef config-states
+                "operational-status": "init",    # typedef ns-operational-
+                "config-status": "init",         # typedef config-states
                 "detailed-status": "scheduled",
 
-                "orchestration-progress": {},  # {"networks": {"active": 0, "total": 0}, "vms": {"active": 0, "total": 0}},
+                "orchestration-progress": {},
+                # {"networks": {"active": 0, "total": 0}, "vms": {"active": 0, "total": 0}},
 
                 "crete-time": now,
                 "nsd-name-ref": nsd["name"],
@@ -590,7 +595,7 @@ class Engine(object):
                     "nsr-id-ref": nsr_id,
                     "member-vnf-index-ref": member_vnf["member-vnf-index"],
                     "created-time": now,
-                    # "vnfd": vnfd,        # at OSM model. TODO can it be removed in the future to avoid data duplication?
+                    # "vnfd": vnfd,        # at OSM model.but removed to avoid data duplication TODO: revise
                     "vnfd-ref": vnfd_id,
                     "vnfd-id": vnfr_id,    # not at OSM model, but useful
                     "vim-account-id": None,
@@ -650,15 +655,16 @@ class Engine(object):
     @staticmethod
     def _update_descriptor(desc, kwargs):
         """
-        Update descriptor with the kwargs
-        :param kwargs:
+        Update descriptor with the kwargs. It contains dot separated keys
+        :param desc: dictionary to be updated
+        :param kwargs: plain dictionary to be used for updating.
         :return:
         """
         if not kwargs:
             return
         try:
             for k, v in kwargs.items():
-                update_content = content
+                update_content = desc
                 kitem_old = None
                 klist = k.split(".")
                 for kitem in klist:
@@ -834,7 +840,7 @@ class Engine(object):
         content = self.get_item(session, item, _id)
         if content["_admin"]["onboardingState"] != "ONBOARDED":
             raise EngineException("Cannot get content because this resource is not at 'ONBOARDED' state. "
-                "onboardingState is {}".format(content["_admin"]["onboardingState"]),
+                                  "onboardingState is {}".format(content["_admin"]["onboardingState"]),
                                   http_code=HTTPStatus.CONFLICT)
         storage = content["_admin"]["storage"]
         if path is not None and path != "$DESCRIPTOR":   # artifacts
@@ -858,12 +864,12 @@ class Engine(object):
             return self.fs.file_open((storage['folder'], storage['descriptor']), "r"), "text/plain"
         elif storage.get('pkg-dir') and not accept_zip:
             raise EngineException("Packages that contains several files need to be retrieved with 'application/zip'"
-                                      "Accept header", http_code=HTTPStatus.NOT_ACCEPTABLE)
+                                  "Accept header", http_code=HTTPStatus.NOT_ACCEPTABLE)
         else:
             if not storage.get('zipfile'):
                 # TODO generate zipfile if not present
-                raise EngineException("Only allowed 'text/plain' Accept header for this descriptor. To be solved in future versions"
-                                      "", http_code=HTTPStatus.NOT_ACCEPTABLE)
+                raise EngineException("Only allowed 'text/plain' Accept header for this descriptor. To be solved in "
+                                      "future versions", http_code=HTTPStatus.NOT_ACCEPTABLE)
             return self.fs.file_open((storage['folder'], storage['zipfile']), "rb"), "application/zip"
 
     def get_item_list(self, session, item, filter={}):
@@ -889,7 +895,6 @@ class Engine(object):
         :param _id: server id of the item
         :return: dictionary, raise exception if not found.
         """
-        database_item = item
         filter = {"_id": _id}
         # TODO add admin to filter, validate rights
         # TODO transform data for SOL005 URL requests
@@ -1033,7 +1038,7 @@ class Engine(object):
                 raise EngineException(
                     "Invalid query string '{}'. Index '{}' out of  range".format(k, kitem_old))
         try:
-            validate_input(content, item, new=False)
+            validate_input(indata, item, new=False)
         except ValidationError as e:
             raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
 
@@ -1064,4 +1069,3 @@ class Engine(object):
 
         content = self.get_item(session, item, _id)
         return self._edit_item(session, item, _id, content, indata, kwargs, force)
-
index 7a079a4..a5b1bca 100644 (file)
@@ -17,7 +17,8 @@ html_start = """
 <body>
   <div id="osm_topmenu">
     <div>
-      <a href="https://osm.etsi.org"> <img src="/osm/static/OSM-logo.png" height="42" width="100" style="vertical-align:middle"> </a>
+      <a href="https://osm.etsi.org"> <img src="/osm/static/OSM-logo.png" height="42" width="100"
+        style="vertical-align:middle"> </a>
       <a>( {} )</a>
       <a href="/osm/vnfpkgm/v1/vnf_packages_content">VNFDs </a>
       <a href="/osm/nsd/v1/ns_descriptors_content">NSDs </a>
@@ -37,13 +38,12 @@ html_body = """
 
 html_end = """
 </body>
-</html> 
+</html>
 """
 
 html_body_error = "<h2> Error <pre>{}</pre> </h2>"
 
 
-
 html_auth2 = """
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
@@ -133,7 +133,8 @@ def format(data, request, response, session):
         if "Location" in response.headers:
             body += '<a href="{}"> show </a>'.format(response.headers["Location"])
         else:
-            body += '<a href="/osm/{}?METHOD=DELETE"> <img src="/osm/static/delete.png" height="25" width="25"> </a>'.format(request.path_info)
+            body += '<a href="/osm/{}?METHOD=DELETE"> <img src="/osm/static/delete.png" height="25" width="25"> </a>'\
+                .format(request.path_info)
             if request.path_info.startswith("/nslcm/v1/ns_instances_content/") or \
                     request.path_info.startswith("/nslcm/v1/ns_instances/"):
                 _id = request.path_info[request.path_info.rfind("/")+1:]
@@ -151,8 +152,6 @@ def format(data, request, response, session):
         if session.get("project_id"):
             user_text += ", project: {}".format(session.get("project_id"))
     return html_start.format(user_text) + body + html_end
-    #yaml.safe_dump(data, explicit_start=True, indent=4, default_flow_style=False)
+    # yaml.safe_dump(data, explicit_start=True, indent=4, default_flow_style=False)
     # tags=False,
     # encoding='utf-8', allow_unicode=True)
-
-
index 467f3b9..c2cb1af 100644 (file)
@@ -15,9 +15,7 @@ from osm_common.dbbase import DbException
 from osm_common.fsbase import FsException
 from osm_common.msgbase import MsgException
 from base64 import standard_b64decode
-#from os import getenv
 from http import HTTPStatus
-#from http.client import responses as http_responses
 from codecs import getreader
 from os import environ, path
 
@@ -32,8 +30,8 @@ database_version = '1.0'
 North Bound Interface  (O: OSM specific; 5,X: SOL005 not implemented yet; O5: SOL005 implemented)
 URL: /osm                                                       GET     POST    PUT     DELETE  PATCH
         /nsd/v1                                                 O       O
-            /ns_descriptors_content                             O       O       
-                /<nsdInfoId>                                    O       O       O       O     
+            /ns_descriptors_content                             O       O
+                /<nsdInfoId>                                    O       O       O       O
             /ns_descriptors                                     O5      O5
                 /<nsdInfoId>                                    O5                      O5      5
                     /nsd_content                                O5              O5
@@ -47,7 +45,7 @@ URL: /osm                                                       GET     POST
 
         /vnfpkgm/v1
             /vnf_packages_content                               O       O
-                /<vnfPkgId>                                     O                       O     
+                /<vnfPkgId>                                     O                       O
             /vnf_packages                                       O5      O5
                 /<vnfPkgId>                                     O5                      O5      5
                     /package_content                            O5               O5
@@ -59,9 +57,9 @@ URL: /osm                                                       GET     POST
 
         /nslcm/v1
             /ns_instances_content                               O       O
-                /<nsInstanceId>                                 O                       O     
+                /<nsInstanceId>                                 O                       O
             /ns_instances                                       5       5
-                /<nsInstanceId>                                 5                       5     
+                /<nsInstanceId>                                 5                       5
                     instantiate                                         O5
                     terminate                                           O5
                     action                                              O
@@ -76,51 +74,59 @@ URL: /osm                                                       GET     POST
                 /<subscriptionId>                               5                       X
         /admin/v1
             /tokens                                             O       O
-                /<id>                                           O                       O     
+                /<id>                                           O                       O
             /users                                              O       O
-                /<id>                                           O                       O     
+                /<id>                                           O                       O
             /projects                                           O       O
-                /<id>                                           O                       O     
+                /<id>                                           O                       O
             /vims_accounts  (also vims for compatibility)       O       O
-                /<id>                                           O                       O       O     
+                /<id>                                           O                       O       O
             /sdns                                               O       O
-                /<id>                                           O                       O       O     
-
-query string.
-    <attrName>[.<attrName>...]*[.<op>]=<value>[,<value>...]&...
-    op: "eq"(or empty to one or the values) | "neq" (to any of the values) | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
-    all_fields, fields=x,y,.., exclude_default, exclude_fields=x,y,...
+                /<id>                                           O                       O       O
+
+query string:
+    Follows SOL005 section 4.3.2 It contains extra METHOD to override http method, FORCE to force.
+    For filtering inside array, it must select the element of the array, or add ANYINDEX to apply the filtering over any
+    item of the array, that is, pass if any item of the array pass the filter.
+    It allows both ne and neq for not equal
+    TODO: 4.3.3 Attribute selectors
+        all_fields, fields=x,y,.., exclude_default, exclude_fields=x,y,...
         (none) … same as “exclude_default”
         all_fields     … all attributes.
-        fields=<list>  … all attributes except all complex attributes with minimum cardinality of zero that are not conditionally mandatory, and that are not provided in <list>.
-        exclude_fields=<list>  … all attributes except those complex attributes with a minimum cardinality of zero that are not conditionally mandatory, and that are provided in <list>.
-        exclude_default        … all attributes except those complex attributes with a minimum cardinality of zero that are not conditionally mandatory, and that are part of the "default exclude set" defined in the present specification for the particular resource
-        exclude_default and include=<list>     … all attributes except those complex attributes with a minimum cardinality of zero that are not conditionally mandatory and that are part of the "default exclude set" defined in the present specification for the particular resource, but that are not part of <list>
+        fields=<list>  … all attributes except all complex attributes with minimum cardinality of zero that are not
+        conditionally mandatory, and that are not provided in <list>.
+        exclude_fields=<list>  … all attributes except those complex attributes with a minimum cardinality of zero that
+        are not conditionally mandatory, and that are provided in <list>.
+        exclude_default        … all attributes except those complex attributes with a minimum cardinality of zero that are not
+        conditionally mandatory, and that are part of the "default exclude set" defined in the present specification for
+        the particular resource
+        exclude_default and include=<list>     … all attributes except those complex attributes with a minimum cardinality
+        of zero that are not conditionally mandatory and that are part of the "default exclude set" defined in the
+        present specification for the particular resource, but that are not part of <list>
 Header field name      Reference       Example Descriptions
     Accept     IETF RFC 7231 [19]      application/json        Content-Types that are acceptable for the response.
     This header field shall be present if the response is expected to have a non-empty message body.
     Content-Type       IETF RFC 7231 [19]      application/json        The MIME type of the body of the request.
     This header field shall be present if the request has a non-empty message body.
-    Authorization      IETF RFC 7235 [22]      Bearer mF_9.B5f-4.1JqM  The authorization token for the request. Details are specified in clause 4.5.3.
+    Authorization      IETF RFC 7235 [22]      Bearer mF_9.B5f-4.1JqM  The authorization token for the request.
+    Details are specified in clause 4.5.3.
     Range      IETF RFC 7233 [21]      1000-2000       Requested range of bytes from a file
 Header field name      Reference       Example Descriptions
     Content-Type       IETF RFC 7231 [19]      application/json        The MIME type of the body of the response.
     This header field shall be present if the response has a non-empty message body.
-    Location   IETF RFC 7231 [19]      http://www.example.com/vnflcm/v1/vnf_instances/123      Used in redirection, or when a new resource has been created.
+    Location   IETF RFC 7231 [19]      http://www.example.com/vnflcm/v1/vnf_instances/123      Used in redirection, or when a
+    new resource has been created.
     This header field shall be present if the response status code is 201 or 3xx.
-    In the present document this header field is also used if the response status code is 202 and a new resource was created.
-    WWW-Authenticate   IETF RFC 7235 [22]      Bearer realm="example"  Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.
-    Accept-Ranges      IETF RFC 7233 [21]      bytes   Used by the Server to signal whether or not it supports ranges for certain resources.
-    Content-Range      IETF RFC 7233 [21]      bytes 21010-47021/ 47022        Signals the byte range that is contained in the response, and the total length of the file.
+    In the present document this header field is also used if the response status code is 202 and a new resource was
+    created.
+    WWW-Authenticate   IETF RFC 7235 [22]      Bearer realm="example"  Challenge if the corresponding HTTP request has not
+    provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization
+    token.
+    Accept-Ranges      IETF RFC 7233 [21]      bytes   Used by the Server to signal whether or not it supports ranges for
+    certain resources.
+    Content-Range      IETF RFC 7233 [21]      bytes 21010-47021/ 47022        Signals the byte range that is contained in the
+    response, and the total length of the file.
     Retry-After        IETF RFC 7231 [19]      Fri, 31 Dec 1999 23:59:59 GMT
-
-    or
-
-    120        Used to indicate how long the user agent ought to wait before making a follow-up request.
-    It can be used with 503 responses.
-    The value of this field can be an HTTP-date or a number of seconds to delay after the response is received.
-
-    #TODO http header for partial uploads: Content-Range: "bytes 0-1199/15000". Id is returned first time and send in following chunks
 """
 
 
@@ -143,87 +149,85 @@ class Server(object):
             "admin": {
                 "v1": {
                     "tokens": {"METHODS": ("GET", "POST", "DELETE"),
-                        "<ID>": { "METHODS": ("GET", "DELETE")}
-                    },
+                               "<ID>": {"METHODS": ("GET", "DELETE")}
+                               },
                     "users": {"METHODS": ("GET", "POST"),
-                        "<ID>": {"METHODS": ("GET", "POST", "DELETE")}
-                    },
+                              "<ID>": {"METHODS": ("GET", "POST", "DELETE")}
+                              },
                     "projects": {"METHODS": ("GET", "POST"),
-                        "<ID>": {"METHODS": ("GET", "DELETE")}
-                    },
+                                 "<ID>": {"METHODS": ("GET", "DELETE")}
+                                 },
                     "vims": {"METHODS": ("GET", "POST"),
-                        "<ID>": {"METHODS": ("GET", "DELETE")}
-                    },
+                             "<ID>": {"METHODS": ("GET", "DELETE")}
+                             },
                     "vim_accounts": {"METHODS": ("GET", "POST"),
-                        "<ID>": {"METHODS": ("GET", "DELETE", "PATCH")}
-                    },
+                                     "<ID>": {"METHODS": ("GET", "DELETE", "PATCH")}
+                                     },
                     "sdns": {"METHODS": ("GET", "POST"),
-                        "<ID>": {"METHODS": ("GET", "DELETE", "PATCH")}
-                    },
+                             "<ID>": {"METHODS": ("GET", "DELETE", "PATCH")}
+                             },
                 }
             },
             "nsd": {
                 "v1": {
-                    "ns_descriptors_content": { "METHODS": ("GET", "POST"),
-                        "<ID>": {"METHODS": ("GET", "PUT", "DELETE")}
-                    },
-                    "ns_descriptors": { "METHODS": ("GET", "POST"),
-                        "<ID>": {"METHODS": ("GET", "DELETE"), "TODO": "PATCH",
-                            "nsd_content": { "METHODS": ("GET", "PUT")},
-                            "nsd": {"METHODS": "GET"},  # descriptor inside package
-                            "artifacts": {"*": {"METHODS": "GET"}}
-                        }
-
-                    },
+                    "ns_descriptors_content": {"METHODS": ("GET", "POST"),
+                                               "<ID>": {"METHODS": ("GET", "PUT", "DELETE")}
+                                               },
+                    "ns_descriptors": {"METHODS": ("GET", "POST"),
+                                       "<ID>": {"METHODS": ("GET", "DELETE"), "TODO": "PATCH",
+                                                "nsd_content": {"METHODS": ("GET", "PUT")},
+                                                "nsd": {"METHODS": "GET"},  # descriptor inside package
+                                                "artifacts": {"*": {"METHODS": "GET"}}
+                                                }
+                                       },
                     "pnf_descriptors": {"TODO": ("GET", "POST"),
-                       "<ID>": {"TODO": ("GET", "DELETE", "PATCH"),
-                            "pnfd_content": {"TODO": ("GET", "PUT")}
-                        }
-                    },
+                                        "<ID>": {"TODO": ("GET", "DELETE", "PATCH"),
+                                                 "pnfd_content": {"TODO": ("GET", "PUT")}
+                                                 }
+                                        },
                     "subscriptions": {"TODO": ("GET", "POST"),
-                        "<ID>": {"TODO": ("GET", "DELETE"),}
-                    },
+                                      "<ID>": {"TODO": ("GET", "DELETE")}
+                                      },
                 }
             },
             "vnfpkgm": {
                 "v1": {
-                    "vnf_packages_content": { "METHODS": ("GET", "POST"),
-                        "<ID>": {"METHODS": ("GET", "PUT", "DELETE")}
-                    },
-                    "vnf_packages": { "METHODS": ("GET", "POST"),
-                        "<ID>": { "METHODS": ("GET", "DELETE"), "TODO": "PATCH",  # GET: vnfPkgInfo
-                            "package_content": { "METHODS": ("GET", "PUT"),         # package
-                                "upload_from_uri": {"TODO": "POST"}
-                            },
-                            "vnfd": {"METHODS": "GET"},                    # descriptor inside package
-                            "artifacts": {"*": {"METHODS": "GET"}}
-                        }
-
-                    },
+                    "vnf_packages_content": {"METHODS": ("GET", "POST"),
+                                             "<ID>": {"METHODS": ("GET", "PUT", "DELETE")}
+                                             },
+                    "vnf_packages": {"METHODS": ("GET", "POST"),
+                                     "<ID>": {"METHODS": ("GET", "DELETE"), "TODO": "PATCH",  # GET: vnfPkgInfo
+                                              "package_content": {"METHODS": ("GET", "PUT"),         # package
+                                                                  "upload_from_uri": {"TODO": "POST"}
+                                                                  },
+                                              "vnfd": {"METHODS": "GET"},                    # descriptor inside package
+                                              "artifacts": {"*": {"METHODS": "GET"}}
+                                              }
+                                     },
                     "subscriptions": {"TODO": ("GET", "POST"),
-                        "<ID>": {"TODO": ("GET", "DELETE"),}
-                    },
+                                      "<ID>": {"TODO": ("GET", "DELETE")}
+                                      },
                 }
             },
             "nslcm": {
                 "v1": {
                     "ns_instances_content": {"METHODS": ("GET", "POST"),
-                        "<ID>": {"METHODS": ("GET", "DELETE")}
-                    },
+                                             "<ID>": {"METHODS": ("GET", "DELETE")}
+                                             },
                     "ns_instances": {"METHODS": ("GET", "POST"),
-                        "<ID>": {"TODO": ("GET", "DELETE"),
-                             "scale": {"TODO": "POST"},
-                             "terminate": {"METHODS": "POST"},
-                             "instantiate": {"METHODS": "POST"},
-                             "action": {"METHODS": "POST"},
-                        }
-                    },
+                                     "<ID>": {"TODO": ("GET", "DELETE"),
+                                              "scale": {"TODO": "POST"},
+                                              "terminate": {"METHODS": "POST"},
+                                              "instantiate": {"METHODS": "POST"},
+                                              "action": {"METHODS": "POST"},
+                                              }
+                                     },
                     "ns_lcm_op_occs": {"METHODS": "GET",
-                        "<ID>": {"METHODS": "GET"},
-                    },
+                                       "<ID>": {"METHODS": "GET"},
+                                       },
                     "vnfrs": {"METHODS": ("GET"),
-                        "<ID>": {"METHODS": ("GET")}
-                    },
+                              "<ID>": {"METHODS": ("GET")}
+                              },
                 }
             },
         }
@@ -400,7 +404,7 @@ class Server(object):
                 outdata = "Index page"
             else:
                 raise cherrypy.HTTPError(HTTPStatus.METHOD_NOT_ALLOWED.value,
-                                 "Method {} not allowed for tokens".format(cherrypy.request.method))
+                                         "Method {} not allowed for tokens".format(cherrypy.request.method))
 
             return self._format_out(outdata, session)
 
@@ -462,7 +466,6 @@ class Server(object):
                     session = self._authorization()
                     token_id = session["_id"]
                 outdata = self.engine.del_token(token_id)
-                oudata = None
                 session = None
                 cherrypy.session['Authorization'] = "logout"
                 # cherrypy.response.cookie["Authorization"] = token_id
@@ -588,7 +591,7 @@ class Server(object):
                 raise NbiException("Unexpected URL item {}".format(arg), HTTPStatus.METHOD_NOT_ALLOWED)
         if "TODO" in reference and method in reference["TODO"]:
             raise NbiException("Method {} not supported yet for this URL".format(method), HTTPStatus.NOT_IMPLEMENTED)
-        elif "METHODS" in reference and not method in reference["METHODS"]:
+        elif "METHODS" in reference and method not in reference["METHODS"]:
             raise NbiException("Method {} not supported for this URL".format(method), HTTPStatus.METHOD_NOT_ALLOWED)
         return
 
@@ -669,7 +672,7 @@ class Server(object):
                     else:
                         path = None
                     file, _format = self.engine.get_file(session, engine_item, _id, path,
-                                                            cherrypy.request.headers.get("Accept"))
+                                                         cherrypy.request.headers.get("Accept"))
                     outdata = file
                 elif not _id:
                     outdata = self.engine.get_item_list(session, engine_item, kwargs)
@@ -682,7 +685,8 @@ class Server(object):
                         _id = self.engine.new_item(session, engine_item, {}, None, cherrypy.request.headers,
                                                    force=force)
                         rollback = {"session": session, "item": engine_item, "_id": _id, "force": True}
-                    completed = self.engine.upload_content(session, engine_item, _id, indata, kwargs, cherrypy.request.headers)
+                    completed = self.engine.upload_content(session, engine_item, _id, indata, kwargs,
+                                                           cherrypy.request.headers)
                     if completed:
                         self._set_location_header(topic, version, item, _id)
                     else:
@@ -727,7 +731,8 @@ class Server(object):
                     raise NbiException("Nothing to update. Provide payload and/or query string",
                                        HTTPStatus.BAD_REQUEST)
                 if item2 in ("nsd_content", "package_content"):
-                    completed = self.engine.upload_content(session, engine_item, _id, indata, kwargs, cherrypy.request.headers)
+                    completed = self.engine.upload_content(session, engine_item, _id, indata, kwargs,
+                                                           cherrypy.request.headers)
                     if not completed:
                         cherrypy.response.headers["Transaction-Id"] = id
                     cherrypy.response.status = HTTPStatus.NO_CONTENT.value
@@ -851,7 +856,7 @@ def _start_service():
         logger_module = logging.getLogger(logname)
         if "logfile" in engine_config[k1]:
             file_handler = logging.handlers.RotatingFileHandler(engine_config[k1]["logfile"],
-                                                             maxBytes=100e6, backupCount=9, delay=0)
+                                                                maxBytes=100e6, backupCount=9, delay=0)
             file_handler.setFormatter(log_formatter_simple)
             logger_module.addHandler(file_handler)
         if "loglevel" in engine_config[k1]:
@@ -873,6 +878,7 @@ def _stop_service():
     cherrypy.tree.apps['/osm'].root.engine.stop()
     cherrypy.log.error("Stopping osm_nbi")
 
+
 def nbi(config_file):
     # conf = {
     #     '/': {
@@ -901,8 +907,8 @@ def usage():
         -c|--config [configuration_file]: loads the configuration file (default: ./nbi.cfg)
         -h|--help: shows this help
         """.format(sys.argv[0]))
-        # --log-socket-host HOST: send logs to this host")
-        # --log-socket-port PORT: send logs using this port (default: 9022)")
+    # --log-socket-host HOST: send logs to this host")
+    # --log-socket-port PORT: send logs using this port (default: 9022)")
 
 
 if __name__ == '__main__':
index 2519953..88d57e9 100755 (executable)
@@ -4,16 +4,12 @@
 import getopt
 import sys
 import requests
-#import base64
-#from os.path import getsize, basename
-#from hashlib import md5
 import json
 import logging
 import yaml
-#import json
+# import json
 import tarfile
 from os import makedirs
-from copy import deepcopy
 
 __author__ = "Alfonso Tierno, alfonso.tiernosepulveda@telefonica.com"
 __date__ = "$2018-03-01$"
@@ -61,9 +57,12 @@ test_not_authorized_list = (
 
 # test ones authorized
 test_authorized_list = (
-    ("AU1", "Invalid vnfd id", "GET", "/vnfpkgm/v1/vnf_packages/non-existing-id", headers_json, None, 404, r_header_json, "json"),
-    ("AU2","Invalid nsd id", "GET", "/nsd/v1/ns_descriptors/non-existing-id", headers_yaml, None, 404, r_header_yaml, "yaml"),
-    ("AU3","Invalid nsd id", "DELETE", "/nsd/v1/ns_descriptors_content/non-existing-id", headers_yaml, None, 404, r_header_yaml, "yaml"),
+    ("AU1", "Invalid vnfd id", "GET", "/vnfpkgm/v1/vnf_packages/non-existing-id",
+     headers_json, None, 404, r_header_json, "json"),
+    ("AU2", "Invalid nsd id", "GET", "/nsd/v1/ns_descriptors/non-existing-id",
+     headers_yaml, None, 404, r_header_yaml, "yaml"),
+    ("AU3", "Invalid nsd id", "DELETE", "/nsd/v1/ns_descriptors_content/non-existing-id",
+     headers_yaml, None, 404, r_header_yaml, "yaml"),
 )
 
 vim = {
@@ -83,7 +82,8 @@ vim_bad = vim.copy()
 vim_bad.pop("name")
 
 test_admin_list1 = (
-    ("VIM1", "Create VIM", "POST", "/admin/v1/vim_accounts", headers_json, vim, (201, 204), {"Location": "/admin/v1/vim_accounts/", "Content-Type": "application/json"}, "json"),
+    ("VIM1", "Create VIM", "POST", "/admin/v1/vim_accounts", headers_json, vim, (201, 204),
+     {"Location": "/admin/v1/vim_accounts/", "Content-Type": "application/json"}, "json"),
     ("VIM2", "Create VIM bad schema", "POST", "/admin/v1/vim_accounts", headers_json, vim_bad, 422, None, headers_json),
     ("VIM2", "Create VIM name repeated", "POST", "/admin/v1/vim_accounts", headers_json, vim, 409, None, headers_json),
     ("VIM4", "Show VIMs", "GET", "/admin/v1/vim_accounts", headers_yaml, None, 200, r_header_yaml, "yaml"),
@@ -91,6 +91,7 @@ test_admin_list1 = (
     ("VIM6", "Delete VIM", "DELETE", "/admin/v1/vim_accounts/{VIM1}", headers_yaml, None, 202, None, 0),
 )
 
+
 class TestException(Exception):
     pass
 
@@ -108,7 +109,8 @@ class TestRest:
     def set_header(self, header):
         self.s.headers.update(header)
 
-    def test(self, name, description, method, url, headers, payload, expected_codes, expected_headers, expected_payload):
+    def test(self, name, description, method, url, headers, payload, expected_codes, expected_headers,
+             expected_payload):
         """
         Performs an http request and check http code response. Exit if different than allowed. It get the returned id
         that can be used by following test in the URL with {name} where name is the name of the test
@@ -154,7 +156,7 @@ class TestRest:
                             payload = f.read()
                 elif isinstance(payload, dict):
                     payload = json.dumps(payload)
-    
+
             test = "Test {} {} {} {}".format(name, description, method, url)
             logger.warning(test)
             stream = False
@@ -205,7 +207,7 @@ class TestRest:
                 elif expected_payload == "text":
                     if len(r.content) == 0:
                         raise TestException("Expected some response payload, but got empty")
-                    #r.text
+                    # r.text
             location = r.headers.get("Location")
             if location:
                 _id = location[location.rfind("/") + 1:]
@@ -240,24 +242,24 @@ if __name__ == "__main__":
 
         for o, a in opts:
             if o == "--version":
-                print ("test version " + __version__ + ' ' + version_date)
+                print("test version " + __version__ + ' ' + version_date)
                 sys.exit()
             elif o in ("-v", "--verbose"):
                 verbose += 1
-            elif o in ("no-verbose"):
+            elif o == "no-verbose":
                 verbose = -1
             elif o in ("-h", "--help"):
                 usage()
                 sys.exit()
-            elif o in ("--url"):
+            elif o == "--url":
                 url = a
             elif o in ("-u", "--user"):
                 user = a
             elif o in ("-p", "--password"):
                 password = a
-            elif o in ("--project"):
+            elif o == "--project":
                 project = a
-            elif o in ("--insecure"):
+            elif o == "--insecure":
                 verify = False
             else:
                 assert False, "Unhandled option"
@@ -298,15 +300,18 @@ if __name__ == "__main__":
         # print(location, vnfd_id)
 
         # vnfd UPLOAD test
-        r = test_rest.test("VNFD2", "Onboard VNFD step 2 as TEXT", "PUT", "/vnfpkgm/v1/vnf_packages/{}/package_content".format(vnfd_id),
+        r = test_rest.test("VNFD2", "Onboard VNFD step 2 as TEXT", "PUT",
+                           "/vnfpkgm/v1/vnf_packages/{}/package_content".format(vnfd_id),
                            r_header_text, "@./cirros_vnf/cirros_vnfd.yaml", 204, None, 0)
 
         # vnfd SHOW OSM format
-        r = test_rest.test("VNFD3", "Show VNFD OSM format", "GET", "/vnfpkgm/v1/vnf_packages_content/{}".format(vnfd_id),
+        r = test_rest.test("VNFD3", "Show VNFD OSM format", "GET",
+                           "/vnfpkgm/v1/vnf_packages_content/{}".format(vnfd_id),
                            headers_json, None, 200, r_header_json, "json")
 
         # vnfd SHOW text
-        r = test_rest.test("VNFD4", "Show VNFD SOL005 text", "GET", "/vnfpkgm/v1/vnf_packages/{}/package_content".format(vnfd_id),
+        r = test_rest.test("VNFD4", "Show VNFD SOL005 text", "GET",
+                           "/vnfpkgm/v1/vnf_packages/{}/package_content".format(vnfd_id),
                            headers_text, None, 200, r_header_text, "text")
 
         # vnfd UPLOAD ZIP
@@ -314,25 +319,31 @@ if __name__ == "__main__":
         tar = tarfile.open("temp/cirros_vnf.tar.gz", "w:gz")
         tar.add("cirros_vnf")
         tar.close()
-        r = test_rest.test("VNFD5", "Onboard VNFD step 3 replace with ZIP", "PUT", "/vnfpkgm/v1/vnf_packages/{}/package_content".format(vnfd_id),
+        r = test_rest.test("VNFD5", "Onboard VNFD step 3 replace with ZIP", "PUT",
+                           "/vnfpkgm/v1/vnf_packages/{}/package_content".format(vnfd_id),
                            r_header_zip, "@b./temp/cirros_vnf.tar.gz", 204, None, 0)
 
         # vnfd SHOW OSM format
-        r = test_rest.test("VNFD6", "Show VNFD OSM format", "GET", "/vnfpkgm/v1/vnf_packages_content/{}".format(vnfd_id),
+        r = test_rest.test("VNFD6", "Show VNFD OSM format", "GET",
+                           "/vnfpkgm/v1/vnf_packages_content/{}".format(vnfd_id),
                            headers_json, None, 200, r_header_json, "json")
 
         # vnfd SHOW zip
-        r = test_rest.test("VNFD7", "Show VNFD SOL005 zip", "GET", "/vnfpkgm/v1/vnf_packages/{}/package_content".format(vnfd_id),
+        r = test_rest.test("VNFD7", "Show VNFD SOL005 zip", "GET",
+                           "/vnfpkgm/v1/vnf_packages/{}/package_content".format(vnfd_id),
                            headers_zip, None, 200, r_header_zip, "zip")
         # vnfd SHOW descriptor
-        r = test_rest.test("VNFD8", "Show VNFD descriptor", "GET", "/vnfpkgm/v1/vnf_packages/{}/vnfd".format(vnfd_id),
+        r = test_rest.test("VNFD8", "Show VNFD descriptor", "GET",
+                           "/vnfpkgm/v1/vnf_packages/{}/vnfd".format(vnfd_id),
                            headers_text, None, 200, r_header_text, "text")
         # vnfd SHOW actifact
-        r = test_rest.test("VNFD9", "Show VNFD artifact", "GET", "/vnfpkgm/v1/vnf_packages/{}/artifacts/icons/cirros-64.png".format(vnfd_id),
+        r = test_rest.test("VNFD9", "Show VNFD artifact", "GET",
+                           "/vnfpkgm/v1/vnf_packages/{}/artifacts/icons/cirros-64.png".format(vnfd_id),
                            headers_text, None, 200, r_header_octect, "text")
 
         # # vnfd DELETE
-        # r = test_rest.test("VNFD10", "Delete VNFD SOL005 text", "DELETE", "/vnfpkgm/v1/vnf_packages/{}".format(vnfd_id),
+        # r = test_rest.test("VNFD10", "Delete VNFD SOL005 text", "DELETE",
+        # "/vnfpkgm/v1/vnf_packages/{}".format(vnfd_id),
         #                    headers_yaml, None, 204, None, 0)
 
         # nsd CREATE
@@ -343,14 +354,18 @@ if __name__ == "__main__":
         # print(location, nsd_id)
 
         # nsd UPLOAD test
-        r = test_rest.test("NSD2", "Onboard NSD with missing vnfd", "PUT", "/nsd/v1/ns_descriptors/{}/nsd_content?constituent-vnfd.0.vnfd-id-ref=NONEXISTING-VNFD".format(nsd_id),
+        r = test_rest.test("NSD2", "Onboard NSD with missing vnfd", "PUT",
+                           "/nsd/v1/ns_descriptors/{}/nsd_content?constituent-vnfd.0.vnfd-id-ref"
+                           "=NONEXISTING-VNFD".format(nsd_id),
                            r_header_text, "@./cirros_ns/cirros_nsd.yaml", 409, r_header_yaml, "yaml")
 
         # # VNF_CREATE
-        # r = test_rest.test("VNFD5", "Onboard VNFD step 3 replace with ZIP", "PUT", "/vnfpkgm/v1/vnf_packages/{}/package_content".format(vnfd_id),
+        # r = test_rest.test("VNFD5", "Onboard VNFD step 3 replace with ZIP", "PUT",
+        # "/vnfpkgm/v1/vnf_packages/{}/package_content".format(vnfd_id),
         #                    r_header_zip, "@b./temp/cirros_vnf.tar.gz", 204, None, 0)
 
-        r = test_rest.test("NSD2", "Onboard NSD step 2 as TEXT", "PUT", "/nsd/v1/ns_descriptors/{}/nsd_content".format(nsd_id),
+        r = test_rest.test("NSD2", "Onboard NSD step 2 as TEXT", "PUT",
+                           "/nsd/v1/ns_descriptors/{}/nsd_content".format(nsd_id),
                            r_header_text, "@./cirros_ns/cirros_nsd.yaml", 204, None, 0)
 
         # nsd SHOW OSM format
@@ -358,7 +373,8 @@ if __name__ == "__main__":
                            headers_json, None, 200, r_header_json, "json")
 
         # nsd SHOW text
-        r = test_rest.test("NSD4", "Show NSD SOL005 text", "GET", "/nsd/v1/ns_descriptors/{}/nsd_content".format(nsd_id),
+        r = test_rest.test("NSD4", "Show NSD SOL005 text", "GET",
+                           "/nsd/v1/ns_descriptors/{}/nsd_content".format(nsd_id),
                            headers_text, None, 200, r_header_text, "text")
 
         # nsd UPLOAD ZIP
@@ -366,7 +382,8 @@ if __name__ == "__main__":
         tar = tarfile.open("temp/cirros_ns.tar.gz", "w:gz")
         tar.add("cirros_ns")
         tar.close()
-        r = test_rest.test("NSD5", "Onboard NSD step 3 replace with ZIP", "PUT", "/nsd/v1/ns_descriptors/{}/nsd_content".format(nsd_id),
+        r = test_rest.test("NSD5", "Onboard NSD step 3 replace with ZIP", "PUT",
+                           "/nsd/v1/ns_descriptors/{}/nsd_content".format(nsd_id),
                            r_header_zip, "@b./temp/cirros_ns.tar.gz", 204, None, 0)
 
         # nsd SHOW OSM format
@@ -381,7 +398,8 @@ if __name__ == "__main__":
         r = test_rest.test("NSD8", "Show NSD descriptor", "GET", "/nsd/v1/ns_descriptors/{}/nsd".format(nsd_id),
                            headers_text, None, 200, r_header_text, "text")
         # nsd SHOW actifact
-        r = test_rest.test("NSD9", "Show NSD artifact", "GET", "/nsd/v1/ns_descriptors/{}/artifacts/icons/osm_2x.png".format(nsd_id),
+        r = test_rest.test("NSD9", "Show NSD artifact", "GET",
+                           "/nsd/v1/ns_descriptors/{}/artifacts/icons/osm_2x.png".format(nsd_id),
                            headers_text, None, 200, r_header_octect, "text")
 
         # vnfd DELETE
@@ -396,7 +414,6 @@ if __name__ == "__main__":
         r = test_rest.test("VNFD10", "Delete VNFD SOL005 text", "DELETE", "/vnfpkgm/v1/vnf_packages/{}".format(vnfd_id),
                            headers_yaml, None, 204, None, 0)
 
-
         print("PASS")
 
     except Exception as e:
index 6f91b23..742f973 100755 (executable)
@@ -1,12 +1,9 @@
 #! /usr/bin/python3
 # -*- coding: utf-8 -*-
 
-import os.path
 import getopt
 import sys
-import base64
 import requests
-import json
 from os.path import getsize, basename
 from hashlib import md5
 
@@ -28,8 +25,7 @@ def usage():
     return
 
 
-if __name__=="__main__":
-
+if __name__ == "__main__":
     try:
         # load parameters and configuration
         opts, args = getopt.getopt(sys.argv[1:], "hvu:s:f:t:",
@@ -42,7 +38,7 @@ if __name__=="__main__":
 
         for o, a in opts:
             if o == "--version":
-                print ("upload version " + __version__ + ' ' + version_date)
+                print("upload version " + __version__ + ' ' + version_date)
                 sys.exit()
             elif o in ("-v", "--verbose"):
                 verbose += 1
index 70003a9..91549e0 100644 (file)
@@ -18,7 +18,8 @@ name_schema = {"type": "string", "minLength": 1, "maxLength": 255, "pattern": "^
 xml_text_schema = {"type": "string", "minLength": 1, "maxLength": 1000, "pattern": "^[^']+$"}
 description_schema = {"type": ["string", "null"], "maxLength": 255, "pattern": "^[^'\"]+$"}
 id_schema_fake = {"type": "string", "minLength": 2,
-                  "maxLength": 36}  # "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
+                  "maxLength": 36}
+# "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
 id_schema = {"type": "string", "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"}
 pci_schema = {"type": "string", "pattern": "^[0-9a-fA-F]{4}(:[0-9a-fA-F]{2}){2}\.[0-9a-fA-F]$"}
 http_schema = {"type": "string", "pattern": "^https?://[^'\"=]+$"}
@@ -35,7 +36,8 @@ mac_schema = {"type": "string",
 ip_schema = {"type": "string",
              "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"}
 ip_prefix_schema = {"type": "string",
-                    "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/(30|[12]?[0-9])$"}
+                    "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}"
+                               "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/(30|[12]?[0-9])$"}
 port_schema = {"type": "integer", "minimum": 1, "maximum": 65534}
 object_schema = {"type": "object"}
 schema_version_2 = {"type": "integer", "minimum": 2, "maximum": 2}
index 3e17a5a..2a206b8 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -44,4 +44,3 @@ setup(
     #     osm=osm_nbi.nbi:nbi
     #     ''',
 )
-
diff --git a/tox.ini b/tox.ini
index ef1f5eb..0d0dce8 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -11,7 +11,7 @@ commands=nosetests
 basepython = python3
 deps = flake8
 commands =
-    flake8 setup.py
+    flake8 setup.py --max-line-length 120 --exclude .svn,CVS,.gz,.git,__pycache__,.tox,local,temp
 
 [testenv:build]
 basepython = python3