Merge "update project info for `git review`"
authorxinhuili <lxinhui@vmware.com>
Thu, 24 Aug 2017 07:03:57 +0000 (07:03 +0000)
committerGerrit Code Review <gerrit@onap.org>
Thu, 24 Aug 2017 07:03:57 +0000 (07:03 +0000)
multivimbroker/multivimbroker/forwarder/base.py [new file with mode: 0644]
multivimbroker/multivimbroker/forwarder/urls.py
multivimbroker/multivimbroker/forwarder/views.py
multivimbroker/multivimbroker/pub/exceptions.py
multivimbroker/multivimbroker/pub/msapi/extsys.py
multivimbroker/multivimbroker/pub/utils/restcall.py
multivimbroker/multivimbroker/pub/utils/syscomm.py
multivimbroker/multivimbroker/swagger/multivim.identity.swagger.json [new file with mode: 0644]
multivimbroker/multivimbroker/swagger/views.py

diff --git a/multivimbroker/multivimbroker/forwarder/base.py b/multivimbroker/multivimbroker/forwarder/base.py
new file mode 100644 (file)
index 0000000..8f70c8b
--- /dev/null
@@ -0,0 +1,65 @@
+# Copyright (c) 2017 VMware, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+import logging
+
+from django.http import HttpResponse
+from rest_framework import status
+
+import multivimbroker.pub.exceptions as exceptions
+from multivimbroker.pub.utils.syscomm import getHeadersKeys
+from multivimbroker.pub.utils.syscomm import getMultivimDriver
+from multivimbroker.pub.utils.restcall import req_by_msb
+
+
+logger = logging.getLogger(__name__)
+
+class BaseHandler(object):
+
+    def _request(self,route_uri,method,body="",headers=None):
+
+        try:
+            retcode, content, status_code, resp = \
+                req_by_msb(route_uri, method, body, headers)
+            if retcode != 0:
+                # Execptions are handled within req_by_msb
+                logger.error("Status code is %s, detail is %s.",
+                             status_code, content)
+
+        except exceptions.NotFound as e:
+            return HttpResponse(str(e), status=status.HTTP_404_NOT_FOUND)
+
+        except Exception as e:
+            content = e
+            status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
+            logger.exception("exception: %s" % e)
+
+        response = HttpResponse(content, status=status_code)
+        for k in getHeadersKeys(resp):
+            response[k] = resp[k]
+        return response
+
+
+    def send(self,vimid,full_path,body,method,headers=None):
+
+            try:
+                url = getMultivimDriver(vimid,full_path=full_path)
+
+            except exceptions.VimBrokerException as e:
+                logging.exception("vimbroker exception: %s"%e)
+                return HttpResponse(e.content,status=e.status_code)
+            except Exception as e:
+                logging.exception("unkown exception: %s" %e)
+                return HttpResponse(str(e),status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+
+            return  self._request(url,method,body=body,headers=headers)
+
index 5598c44..be20280 100644 (file)
 from django.conf.urls import url
 from rest_framework.urlpatterns import format_suffix_patterns
 
-from . import views
+from multivimbroker.forwarder.views import Forward
+from multivimbroker.forwarder.views import Identity
+
 
 urlpatterns = [
-    url(r'^openoapi/multivim/v1/(?P<vimid>[0-9a-zA-Z_-]+)', views.route)
+
+    url(r'^openoapi/multivim/v1/(?P<vimid>[0-9a-zA-Z_-]+)/identity/v3$',Identity.as_view()),
+    url(r'^openoapi/multivim/v1/(?P<vimid>[0-9a-zA-Z_-]+)/identity/v3/auth/tokens$',Identity.as_view()),
+    url(r'^openoapi/multivim/v1/(?P<vimid>[0-9a-zA-Z_-]+)', Forward.as_view()),
+
 ]
 
 urlpatterns = format_suffix_patterns(urlpatterns)
index ca93b8e..82759e5 100644 (file)
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-import logging
-import re
-
-from django.http import HttpResponse
-from django.views.decorators.csrf import csrf_exempt
-
-from rest_framework import status
-
-from multivimbroker.pub.utils.restcall import req_by_msb
-from multivimbroker.pub.msapi.extsys import get_vim_by_id
-
-logger = logging.getLogger(__name__)
-
-
-@csrf_exempt
-def route(request, vimid=''):
-    """ get vim info from vimid from local cache first
-        and then to ESR if cache miss
-    """
-    content = ""
-    status_code = status.HTTP_200_OK
-    try:
-        vim = get_vim_by_id(vimid)
-        if vim["type"] and vim["version"]:
-            pass
-
-    except Exception as e:
-        logger.error("get_vim_by_id, exception: %s" % e)
-        return HttpResponse("Not a valid VIM instance", status=status.HTTP_404_NOT_FOUND)
-
-    try:
-        if vim and vim["type"] == "openstack":
-            if vim["version"] == "kilo":
-                multivimdriver = "multivim-kilo"
-            elif vim["version"] == "newton":
-                multivimdriver = "multivim-newton"
-            else:
-                # if vim type is openstack, use latest "newton" version as default
-                multivimdriver = "multivim-newton"
-        elif vim and vim["type"] == "vmware":
-            multivimdriver = "multivim-vio"
-        else:
-            logger.error("wrong vim id: %s, return from extsys:%s" %
-                         vimid, vim)
-            return HttpResponse("Not support VIM type", status=status.HTTP_404_NOT_FOUND)
-
-        route_uri = re.sub('multivim', multivimdriver, request.get_full_path())
-
-        retcode, content, status_code = \
-            req_by_msb(route_uri, request.method, request.body)
-        if retcode != 0:
-            # Execptions are handled within req_by_msb
-            logger.error("Status code is %s, detail is %s.",
-                         status_code, content)
-    except Exception as e:
-        content = e
-        status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
-        logger.error("exception: %s" % e)
-    return HttpResponse(content, status=status_code)
+
+from rest_framework.views import  APIView
+from multivimbroker.forwarder.base import BaseHandler
+
+#
+class BaseServer(BaseHandler,APIView):
+
+
+    def get(self,request,vimid):
+        raise NotImplementedError()
+
+    def post(self,request,vimid):
+        raise NotImplementedError()
+
+    def put(self,request,vimid):
+        raise NotImplementedError()
+
+    def delete(self,request,vimid):
+        raise NotImplementedError()
+
+    def head(self,request,vimid):
+        raise NotImplementedError()
+
+    def patch(self,request,vimid):
+        raise NotImplementedError()
+
+
+#  vio proxy handler
+class Identity(BaseServer):
+
+    def get(self,request,vimid):
+
+        return self.send(vimid,request.get_full_path(),request.body,"GET")
+
+    def post(self,request,vimid):
+
+        return self.send(vimid,request.get_full_path(),request.body,"POST")
+
+
+# forward  handler
+class Forward(BaseServer):
+
+    def get(self,request,vimid):
+
+        return self.send(vimid,request.get_full_path(),request.body,"GET")
+
+    def post(self,request,vimid):
+
+        return self.send(vimid,request.get_full_path(),request.body,"POST",headers=None)
+
+    def patch(self,request,vimid):
+
+        return self.send(vimid,request.get_full_path(),request.body,"PATCH",headers=None)
+
+    def delete(self,request,vimid):
+
+        return self.send(vimid,request.get_full_path(),request.body,"DELETE",headers=None)
+
+    def head(self,request,vimid):
+
+        return self.send(vimid,request.get_full_path(),request.body,"HEAD")
+
+    def put(self,request,vimid):
+
+        return self.send(vimid,request.get_full_path(),request.body,"PUT",headers=None)
+
index f11bb16..d2b2c80 100644 (file)
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
 
-class VimBrokerException(Exception):
-    pass
+
+class BaseException(Exception):
+
+    message = "Exception"
+
+    def __init__(self, message=None, status_code="", content=""):
+        super(BaseException, self).__init__(message)
+        self.message = message or self.message
+        self.status_code = status_code
+        self.content = content
+
+class VimBrokerException(BaseException):
+
+        message = "vim error"
+
+
+class NotFound(BaseException):
+
+        message = "not found error"
+
+
index ac2fa13..1baa08a 100644 (file)
@@ -23,7 +23,7 @@ def get_vims():
     ret = req_by_msb(ESR_GET_VIM_URI, "GET")
     if ret[0] != 0:
         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
-        raise VimBrokerException("Failed to query VIMs from extsys.")
+        raise VimBrokerException(status_code=404 ,content="Failed to query VIMs from extsys.")
     return json.JSONDecoder().decode(ret[1])
 
 
@@ -31,6 +31,6 @@ def get_vim_by_id(vim_id):
     ret = req_by_msb("%s/%s" % (ESR_GET_VIM_URI, vim_id), "GET")
     if ret[0] != 0:
         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
-        raise VimBrokerException(
+        raise VimBrokerException(status_code=404,content=
             "Failed to query VIM with id (%s) from extsys." % vim_id)
     return json.JSONDecoder().decode(ret[1])
index 0b76bae..dc0b822 100644 (file)
@@ -16,6 +16,7 @@ import urllib2
 import uuid
 import httplib2
 
+
 from multivimbroker.pub.config.config import MSB_SERVICE_IP, MSB_SERVICE_PORT
 
 rest_no_auth, rest_oneway_auth, rest_bothway_auth = 0, 1, 2
@@ -26,15 +27,22 @@ HTTP_404_NOTFOUND, HTTP_403_FORBIDDEN, HTTP_401_UNAUTHORIZED, HTTP_400_BADREQUES
 logger = logging.getLogger(__name__)
 
 
-def call_req(base_url, user, passwd, auth_type, resource, method, content=''):
+def call_req(base_url, user, passwd, auth_type, resource, method, content='',headers=None):
     callid = str(uuid.uuid1())
 #    logger.debug("[%s]call_req('%s','%s','%s',%s,'%s','%s','%s')" % (
 #        callid, base_url, user, passwd, auth_type, resource, method, content))
     ret = None
     resp_status = ''
+    resp = ""
+    full_url = ""
+
+
     try:
         full_url = combine_url(base_url, resource)
-        headers = {'content-type': 'application/json', 'accept': 'application/json'}
+        if headers == None:
+            headers = {}
+            headers['content-type']='application/json'
+
         if user:
             headers['Authorization'] = 'Basic ' + ('%s:%s' % (user, passwd)).encode("base64")
         ca_certs = None
@@ -42,42 +50,41 @@ def call_req(base_url, user, passwd, auth_type, resource, method, content=''):
             http = httplib2.Http(ca_certs=ca_certs, disable_ssl_certificate_validation=(auth_type == rest_no_auth))
             http.follow_all_redirects = True
             try:
-#                logger.debug("request=%s)" % full_url)
+                logger.debug("request=%s)" % full_url)
                 resp, resp_content = http.request(full_url, method=method.upper(), body=content, headers=headers)
                 resp_status, resp_body = resp['status'], resp_content.decode('UTF-8')
-#                logger.debug("[%s][%d]status=%s,resp_body=%s)" % (callid, retry_times, resp_status, resp_body))
+
                 if resp_status in status_ok_list:
-                    ret = [0, resp_body, resp_status]
+                    ret = [0, resp_body, resp_status, resp]
                 else:
-                    ret = [1, resp_body, resp_status]
+                    ret = [1, resp_body, resp_status, resp]
                 break
             except Exception as ex:
                 if 'httplib.ResponseNotReady' in str(sys.exc_info()):
-#                    logger.debug("retry_times=%d", retry_times)
                     logger.error(traceback.format_exc())
-                    ret = [1, "Unable to connect to %s" % full_url, resp_status]
+                    ret = [1, "Unable to connect to %s" % full_url, resp_status, resp]
                     continue
                 raise ex
     except urllib2.URLError as err:
-        ret = [2, str(err), resp_status]
+        ret = [2, str(err), resp_status, resp]
     except Exception as ex:
         logger.error(traceback.format_exc())
         logger.error("[%s]ret=%s" % (callid, str(sys.exc_info())))
         res_info = str(sys.exc_info())
         if 'httplib.ResponseNotReady' in res_info:
             res_info = "The URL[%s] request failed or is not responding." % full_url
-        ret = [3, res_info, resp_status]
+        ret = [3, res_info, resp_status, resp]
     except:
         logger.error(traceback.format_exc())
-        ret = [4, str(sys.exc_info()), resp_status]
+        ret = [4, str(sys.exc_info()), resp_status, resp]
 
 #    logger.debug("[%s]ret=%s" % (callid, str(ret)))
     return ret
 
 
-def req_by_msb(resource, method, content=''):
+def req_by_msb(resource, method, content='',headers=None):
     base_url = "http://%s:%s/" % (MSB_SERVICE_IP, MSB_SERVICE_PORT)
-    return call_req(base_url, "", "", rest_no_auth, resource, method, content)
+    return call_req(base_url, "", "", rest_no_auth, resource, method, content,headers)
 
 
 def combine_url(base_url, resource):
index 735129a..07606bf 100644 (file)
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
 import inspect
+import re
 
-
+import multivimbroker.pub.exceptions as  exceptions
+from multivimbroker.pub.msapi.extsys import get_vim_by_id
 def fun_name():
     return inspect.stack()[1][3]
+
+
+
+
+# Which headers are hop-by-hop headers by default
+HOP_BY_HOP = ['connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization', 'te', 'trailers', 'transfer-encoding', 'upgrade']
+def getHeadersKeys(response):
+    hopbyhop = HOP_BY_HOP
+    hopbyhop.extend([x.strip() for x in response.get('connection', '').split(',')])
+    return [header for header in response.keys() if header not in hopbyhop]
+
+
+
+def findMultivimDriver(vim=None):
+
+    if vim and vim["type"] == "openstack":
+        if vim["version"] == "kilo":
+            multivimdriver = "multivim-kilo"
+        elif vim["version"] == "newton":
+            multivimdriver = "multivim-newton"
+        else:
+            # if vim type is openstack, use latest "newton" version as default
+            multivimdriver = "multivim-newton"
+    elif vim and vim["type"] == "vmware":
+        multivimdriver = "multivim-vio"
+    else:
+        raise  exceptions.NotFound("Not support VIM type")
+    return  multivimdriver
+
+
+
+def  getMultivimDriver(vimid,full_path=""):
+
+    multivim = "multivim"
+    vim = get_vim_by_id(vimid)
+    if vim["type"] and vim["version"]:
+        pass
+
+    multivimdriver = findMultivimDriver(vim=vim)
+    return re.sub(multivim, multivimdriver, full_path)
diff --git a/multivimbroker/multivimbroker/swagger/multivim.identity.swagger.json b/multivimbroker/multivimbroker/swagger/multivim.identity.swagger.json
new file mode 100644 (file)
index 0000000..923924e
--- /dev/null
@@ -0,0 +1,145 @@
+{
+    "swagger": "2.0",
+    "info": {
+        "version": "1.0.0",
+        "title": "MultiVIM Service rest API"
+    },
+    "basePath": "/openoapi/multivim/v1/",
+    "tags": [
+        {
+            "name": "MultiVIM services"
+        }
+    ],
+    "paths": {
+        "/{vimid}/identity/v3": {
+            "get": {
+                "tags": [
+                    "vim identity"
+                ],
+                "summary": "query vim  identity  server ",
+                "description": "query vim  identity  server",
+                "operationId": "query_vim_identity",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "vimid",
+                        "in": "path",
+                        "description": "vim instance id",
+                        "required": true,
+                        "type": "string"
+                    }
+
+
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/IdentityInfo"
+                        }
+                    },
+                    "404": {
+                        "description": "the vim id is wrong"
+                    },
+                    "500": {
+                        "description": "the vim tenants is not accessable"
+                    }
+                }
+            }
+        },
+        "/{vimid}/identity/v3/auth/tokens":{
+           "post": {
+                "tags": [
+                    "vim identity"
+                ],
+                "summary": "get  vim token ",
+                "description": "get  vim token",
+                "operationId": "get_vim_token",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "vimid",
+                        "in": "path",
+                        "description": "vim instance id",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                      "name": "body",
+                      "in": "body",
+                      "description": "authrication data",
+                      "required": true,
+                      "type": "string"
+                    }
+
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/TokenInfo"
+                        }
+                    },
+                    "404": {
+                        "description": "the vim id is wrong"
+                    },
+                    "500": {
+                        "description": "the vim tenants is not accessable"
+                    }
+                }
+            }
+        }
+    },
+    "definitions": {
+        "IdentityInfo": {
+            "type": "object",
+            "required": [
+                "href",
+                "id"
+            ],
+            "properties": {
+                "href": {
+                    "type": "string",
+                    "description": "keystone url"
+                },
+                "id": {
+                    "type": "string",
+                    "description": "keystone version"
+                }
+            }
+        },
+        "TokenInfo": {
+            "type": "object",
+            "required": [
+                "value",
+                "endpoints"
+            ],
+            "properties": {
+                "value": {
+                    "type": "string",
+                    "description": "token uuid"
+                },
+                "endpoints": {
+                    "type": "string",
+                    "description": "serivce endpoints"
+                }
+            }
+        }
+    }
+}
+
+
+
+
+
+
index 8e8a2bf..5fcfb53 100644 (file)
@@ -83,5 +83,12 @@ class SwaggerJsonView(APIView):
         f.close()
         json_data["paths"].update(json_data_temp["paths"])
         json_data["definitions"].update(json_data_temp["definitions"])
+        #
+        json_file = os.path.join(os.path.dirname(__file__), 'multivim.identity.swagger.json')
+        f = open(json_file)
+        json_data_temp = json.JSONDecoder().decode(f.read())
+        f.close()
+        json_data["paths"].update(json_data_temp["paths"])
+        json_data["definitions"].update(json_data_temp["definitions"])
         return Response(json_data)