diff options
author | liangke <lokyse@163.com> | 2017-08-18 21:28:36 +0800 |
---|---|---|
committer | liangke <lokyse@163.com> | 2017-08-22 17:20:40 +0800 |
commit | c0d164ec6185892fb0f7b6d618715c8e3397e8ca (patch) | |
tree | d5a5cc01a980d2d953261ab395b17d81cc9e5695 | |
parent | 306ce4df0e635d0bfafe1ae1756ef3f7e298863b (diff) |
Add openstack proxy function
Change-Id: I6b4439df4905a391ebd2e4eec3b8491e0c06ead4
Issue-Id: MULTICLOUD-55
Signed-off-by: liangke <lokyse@163.com>
-rw-r--r-- | vio/vio/pub/exceptions.py | 57 | ||||
-rw-r--r-- | vio/vio/pub/utils/syscomm.py | 33 | ||||
-rw-r--r-- | vio/vio/swagger/urls.py | 47 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/__init__.py | 11 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/heat/__init__.py | 11 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/heat/views.py | 54 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/httpclient.py | 182 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/identity/__init__.py | 11 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/identity/views.py | 183 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/image/__init__.py | 11 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/image/views.py | 50 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/neutron/__init__.py | 11 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/neutron/views.py | 39 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/nova/__init__.py | 11 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/nova/views.py | 43 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/volumn/__init__.py | 11 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/volumn/views.py | 53 |
17 files changed, 813 insertions, 5 deletions
diff --git a/vio/vio/pub/exceptions.py b/vio/vio/pub/exceptions.py index 077b72d..097d785 100644 --- a/vio/vio/pub/exceptions.py +++ b/vio/vio/pub/exceptions.py @@ -11,9 +11,58 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -class VimDriverVioException(Exception): - def __init__(self, message, status_code="", content=""): - super(VimDriverVioException, self).__init__(message) +class ClientException(Exception): + + message = "ClientException" + + def __init__(self, message=None): + self.message = message or self.message + super(ClientException, self).__init__(self.message) + +class ServerException(Exception): + + message = "ServerException" + + def __init__(self, message=None, status_code="", content=""): + super(ServerException, self).__init__(message) + self.message = message or self.message self.status_code = status_code self.content = content - pass + +class RetriableConnectionFailure(Exception): + + pass + + +class ConnectionError(ClientException): + message = "Cannot connect to API service." + + +class ConnectTimeout(ConnectionError, RetriableConnectionFailure): + message = "Timed out connecting to service." + + +class ConnectFailure(ConnectionError, RetriableConnectionFailure): + message = "Connection failure that may be retried." + + +class SSLError(ConnectionError): + message = "An SSL error occurred." + + + + +class UnknownConnectionError(ConnectionError): + + def __init__(self, msg, original): + super(UnknownConnectionError, self).__init__(msg) + self.original = original + + + +class NotFoundError(ServerException): + message = "Cannot find value" + +class VimDriverVioException(ServerException): + message = "Cannot find vim driver" + diff --git a/vio/vio/pub/utils/syscomm.py b/vio/vio/pub/utils/syscomm.py index 833a290..fd99ac6 100644 --- a/vio/vio/pub/utils/syscomm.py +++ b/vio/vio/pub/utils/syscomm.py @@ -11,7 +11,38 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. import inspect - +import json +from collections import defaultdict def fun_name(): return inspect.stack()[1][3] + + +def jsonResponse(data,encoding='utf-8'): + + content_type = "application/json" + try: + res = json.loads(data,encoding=encoding) + except Exception as e: + res = data + content_type = "text/plain" + return (res,content_type) + + +class Catalogs(object): + + def __init__(self): + self.ct=defaultdict(dict) + + + def storeEndpoint(self,vimid,endpoints): + self.ct.setdefault(vimid,endpoints) + + def getEndpointBy(self,vimid,serverType,interface='public'): + + vim = self.ct.get(vimid) + return vim.get(serverType).get(interface,"") if vim else "" + + + +catalog = Catalogs() diff --git a/vio/vio/swagger/urls.py b/vio/vio/swagger/urls.py index 1740c03..26a739f 100644 --- a/vio/vio/swagger/urls.py +++ b/vio/vio/swagger/urls.py @@ -28,6 +28,14 @@ from vio.swagger.views.network.views import CreateNetworkView, DeleteNetworkView from vio.swagger.views.subnet.views import CreateSubnetView, DeleteSubnetView from vio.swagger.views.port.views import CreatePortView, DeletePortView +#proxy +from vio.swagger.views.proxyplugin.identity.views import TokenView,IdentityServer +from vio.swagger.views.proxyplugin.nova.views import ComputeServer +from vio.swagger.views.proxyplugin.image.views import ImageServer +from vio.swagger.views.proxyplugin.neutron.views import NetWorkServer +from vio.swagger.views.proxyplugin.volumn.views import VolumeServer +from vio.swagger.views.proxyplugin.heat.views import HeatServer + urlpatterns = [ url(r'^openoapi/multivim-vio/v1/swagger.json$', SwaggerJsonView.as_view()), url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z_-]+)/' @@ -79,6 +87,45 @@ urlpatterns = [ url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z\-\_]+)/(?P<tenantid>[0-9a-zA-Z\-\_]+)/ports/' r'(?P<portid>[0-9a-zA-Z\-\_]+)$', DeletePortView.as_view()), + + # proxy + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-z-A-Z\-\_]+)/identity/v3', + TokenView.as_view()), + + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-z-A-Z\-\_]+)/identity$', + IdentityServer.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-z-A-Z\-\_]+)/identity/(?P<other>(.*))$', + IdentityServer.as_view()), + + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-z-A-Z\-\_]+)/glance/(?P<other>(.*))$', + ImageServer.as_view()), + + url( + r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-z-A-Z\-\_]+)/cinder/(?P<tenantid>[0-9a-z-A-Z\-\_]+)/(?P<other>(.*))$', + VolumeServer.as_view()), + + url( + r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-z-A-Z\-\_]+)/cinderv2/(?P<tenantid>[0-9a-z-A-Z\-\_]+)/(?P<other>(.*))$', + VolumeServer.as_view()), + + url( + r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-z-A-Z\-\_]+)/cinderv3/(?P<tenantid>[0-9a-z-A-Z\-\_]+)/(?P<other>(.*))$', + VolumeServer.as_view()), + + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-z-A-Z\-\_]+)/neutron$', + NetWorkServer.as_view()), + + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-z-A-Z\-\_]+)/neutron/(?P<other>(.*))$', + NetWorkServer.as_view()), + + url( + r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-z-A-Z\-\_]+)/heat/(?P<tenantid>[0-9a-z-A-Z\-\_]+)/(?P<other>(.*))$', + HeatServer.as_view()), + + url( + r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-z-A-Z\-\_]+)/nova/(?P<tenantid>[0-9a-z-A-Z\-\_]+)/(?P<other>(.*))$', + ComputeServer.as_view()), + ] urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/vio/vio/swagger/views/proxyplugin/__init__.py b/vio/vio/swagger/views/proxyplugin/__init__.py new file mode 100644 index 0000000..9ac359f --- /dev/null +++ b/vio/vio/swagger/views/proxyplugin/__init__.py @@ -0,0 +1,11 @@ +# 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.
\ No newline at end of file diff --git a/vio/vio/swagger/views/proxyplugin/heat/__init__.py b/vio/vio/swagger/views/proxyplugin/heat/__init__.py new file mode 100644 index 0000000..9ac359f --- /dev/null +++ b/vio/vio/swagger/views/proxyplugin/heat/__init__.py @@ -0,0 +1,11 @@ +# 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.
\ No newline at end of file diff --git a/vio/vio/swagger/views/proxyplugin/heat/views.py b/vio/vio/swagger/views/proxyplugin/heat/views.py new file mode 100644 index 0000000..b60cb7b --- /dev/null +++ b/vio/vio/swagger/views/proxyplugin/heat/views.py @@ -0,0 +1,54 @@ +# 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. + +from vio.swagger.views.proxyplugin.httpclient import BaseClient + + +class HeatServer(BaseClient): + + serverType = "heat" + + def get(self,request,vimid,tenantid,other): + + return self.send(request=request,method="GET",vimid=vimid,tenantid=tenantid,other=other) + + def post(self,request,vimid,tenantid,other): + + return self.send(request=request,method="POST",vimid=vimid,tenantid=tenantid,other=other) + + + def put(self,request,vimid,tenantid,other): + + return self.send(request=request, method="PUT",vimid=vimid, tenantid=tenantid, other=other) + + + def delete(self,request,vimid,tenantid,other): + + return self.send(request=request, method="DELETE",vimid=vimid, tenantid=tenantid, other=other) + + def patch(self, request, vimid, tenantid,other): + + return self.send(request=request, method="PATCH",vimid=vimid, tenantid=tenantid, other=other) + + + + + + + + + + + + + + diff --git a/vio/vio/swagger/views/proxyplugin/httpclient.py b/vio/vio/swagger/views/proxyplugin/httpclient.py new file mode 100644 index 0000000..b335d4a --- /dev/null +++ b/vio/vio/swagger/views/proxyplugin/httpclient.py @@ -0,0 +1,182 @@ +# 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 +import requests +import json +import socket +import time + +from rest_framework import status +from rest_framework.views import APIView +from rest_framework.response import Response + + +from vio.pub.utils.syscomm import catalog,jsonResponse +import vio.pub.exceptions as exceptions + + +logger = logging.getLogger(__name__) + +class TCPKeepAliveAdapter(requests.adapters.HTTPAdapter): + """The custom adapter used to set TCP Keep-Alive on all connections.""" + + def init_poolmanager(self, *args, **kwargs): + if 'socket_options' not in kwargs and tuple(int(v) for v in requests.__version__.split('.')) >= (2, 4, 1): + socket_options = [ + # Keep Nagle's algorithm off + (socket.IPPROTO_TCP, socket.TCP_NODELAY, 1), + # Turn on TCP Keep-Alive + (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), + ] + + if hasattr(socket, 'TCP_KEEPIDLE'): + socket_options += [ + # Wait 60 seconds before sending keep-alive probes + (socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60) + ] + + if hasattr(socket, 'TCP_KEEPINTVL'): + socket_options += [ + # Send keep-alive probes every 15 seconds + (socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 15), + ] + + kwargs['socket_options'] = socket_options + super(TCPKeepAliveAdapter, self).init_poolmanager(*args, **kwargs) + + +class BaseClient(APIView): + + def __init__(self): + super(BaseClient,self).__init__() + + self.session = requests.Session() + for schema in list(self.session.adapters): + self.session.mount(schema,TCPKeepAliveAdapter()) + + def buildRequest(self,request,vimid,tenantid="",tail=None): + + preUrl = catalog.getEndpointBy(vimid, serverType=self.serverType,interface="public") + token = request.META.get('HTTP_X_AUTH_TOKEN', "") + tail = "/" + tail if tail else "" + tenantid = "/" + tenantid if tenantid else "" + endPointURL = preUrl + tenantid + tail + + headers = {"X-Auth-Token": token} + headers['Content-Type'] = request.META.get("CONTENT_TYPE","application/json") + try: + json_req = json.loads(request.body) + except Exception as e: + json_req = "" + + return (endPointURL,headers,json_req) + + + def _request(self, url, method,redirect=20, + connect_retries=0, connect_retry_delay=0.5, **kwargs): + + try: + try: + logger.info("%(method)s Request to %(url)s ",{'url':url,'method':method}) + resp = self.session.request(method, url,verify=False,timeout=30,**kwargs) + except requests.exceptions.SSLError as e: + msg = 'SSL exception connecting to %(url)s: %(error)s' % { + 'url': url, 'error': e} + raise exceptions.SSLError(msg) + except requests.exceptions.Timeout: + msg = 'Request to %s timed out' % url + raise exceptions.ConnectTimeout(msg) + except requests.exceptions.ConnectionError as e: + msg = 'Unable to establish connection to %s: %s' % (url, e) + raise exceptions.ConnectionError(msg) + except requests.exceptions.RequestException as e: + msg = 'Unexpected exception for %(url)s: %(error)s' % { + 'url': url, 'error': e} + raise exceptions.UnknownConnectionError(msg, e) + + except exceptions.RetriableConnectionFailure as e: + if connect_retries <= 0: + return Response(data={"error":str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + logger.info('Failure: %(e)s. Retrying in %(delay).1fs.', + {'e': e, 'delay': connect_retry_delay}) + time.sleep(connect_retry_delay) + + return self._request( + url, method, redirect, + connect_retries=connect_retries - 1, + connect_retry_delay=connect_retry_delay * 2, + **kwargs) + + + if resp.status_code in [301, 302, 303, 305, 307, 308]: + + if isinstance(redirect, bool): + redirect_allowed = redirect + else: + redirect -= 1 + redirect_allowed = redirect >= 0 + + if not redirect_allowed: + return resp + + try: + location = resp.headers['location'] + except KeyError: + logger.warning("Failed to redirect request to %s as new " + "location was not provided.", resp.url) + pass + + else: + new_resp = self._request( + location, method, redirect, + connect_retries=connect_retries, + **kwargs) + + if not isinstance(new_resp.history, list): + new_resp.history = list(new_resp.history) + new_resp.history.insert(0, resp) + resp = new_resp + + data,content_type = jsonResponse(resp.content) + return Response(data=data, status=resp.status_code,content_type=content_type) + + + def send(self,request,method,vimid,tenantid="",other="",**kwargs): + + (url, headers, data) = self.buildRequest(request, vimid, tenantid=tenantid, tail=other) + kwargs.setdefault('headers', headers) + + if method in ["POST","PUT","PATCH"]: + kwargs.setdefault('data', json.dumps(data, encoding='utf-8')) + + return self._request(url,method,**kwargs) + + + def get(self,request,vimid): + raise NotImplementedError() + + def post(self,request,vimid): + raise NotImplementedError() + + def put(self,request,vimid): + raise NotImplementedError() + + def patch(self,request,vimid): + raise NotImplementedError() + + def delete(self,request,vimid): + raise NotImplementedError() + + def head(self,request,vimid): + raise NotImplementedError() diff --git a/vio/vio/swagger/views/proxyplugin/identity/__init__.py b/vio/vio/swagger/views/proxyplugin/identity/__init__.py new file mode 100644 index 0000000..9ac359f --- /dev/null +++ b/vio/vio/swagger/views/proxyplugin/identity/__init__.py @@ -0,0 +1,11 @@ +# 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.
\ No newline at end of file diff --git a/vio/vio/swagger/views/proxyplugin/identity/views.py b/vio/vio/swagger/views/proxyplugin/identity/views.py new file mode 100644 index 0000000..c7addc9 --- /dev/null +++ b/vio/vio/swagger/views/proxyplugin/identity/views.py @@ -0,0 +1,183 @@ +# 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 rest_framework import status +from rest_framework.response import Response + +from vio.pub.msapi import extsys +from vio.pub.exceptions import VimDriverVioException +from vio.pub.utils.syscomm import catalog +from vio.pub.config.config import MSB_SERVICE_PORT,MSB_SERVICE_IP +import json +import requests +from collections import defaultdict +from copy import deepcopy + +from vio.swagger.views.proxyplugin.httpclient import BaseClient + +logger = logging.getLogger(__name__) + +MSB_ADDRESS = MSB_SERVICE_IP+":"+MSB_SERVICE_PORT+"/api" + + +class IdentityServer(BaseClient): + + serverType = 'keystone' + + def get(self,request,vimid,other=None): + + (url,headers,_) = self.buildRequest(request,vimid,tail=other) + + query = "" + for k,v in request.GET.items(): + query+= (k+"="+v) + query+="&" + + if query!="": + query = query[:-1] + url+="/?"+query + return self._request(url,method="GET",headers=headers) + + def patch(self,request,vimid,other): + + return self.send(request=request,method="PATCH",vimid=vimid,other=other) + + def post(self,request,vimid,other): + + return self.send(request=request,method="POST",vimid=vimid,other=other) + + def delete(self,request,vimid,other): + + return self.send(request=request,method="DELETE",vimid=vimid,other=other) + + def head(self,request,vimid,other): + + return self.send(request=request,method="HEAD",vimid=vimid,other=other) + + + +class TokenView(BaseClient): + + serverType = 'identity' + + + def get(self,request,vimid): + + url_path = request.get_full_path() + if url_path[url_path.rfind("identity"):]!="identity/v3": + return Response(data={"error":"method not allowed"},status=status.HTTP_405_METHOD_NOT_ALLOWED) + + try: + vim_info = extsys.get_vim_by_id(vim_id=vimid) + except VimDriverVioException as e: + return Response(data={"error": str(e)}, status=e.status_code) + except Exception as e: + logging.exception("error %s" % e) + return Response(data={"error":str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + + keystoneURL = vim_info['url'] + logger.info("vimid(%(vimid)s) get keystone url %(url)s ", {"vimid": vimid, "url": keystoneURL}) + try: + res = requests.get(url=keystoneURL).json() + res['version']['links'][0]['href']="http://"+MSB_ADDRESS+"/multivim-vio/v1/"+vimid +"/identity/v3" + + + except Exception as e: + logging.exception("error %s" % e) + return Response(data={"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + return Response(data=res, status=status.HTTP_200_OK) + + + def delete(self,request,vimid): + + (url, headers, _) = self.buildRequest(request, vimid) + + subject_token = request.META.get("HTTP_X_SUBJECT_TOKEN","") + + url+="/auth/tokens" + headers["X-Subject-Token"] = subject_token + return self._request(url,method="DELETE",headers=headers) + + + def post(self,request,vimid): + + url_path = request.get_full_path() + if url_path[url_path.rfind("identity"):] != "identity/v3/auth/tokens": + return Response(data={"error": "method not allowed"}, status=status.HTTP_405_METHOD_NOT_ALLOWED) + + try: + create_req = json.loads(request.body) + except Exception as e: + return Response(data={'error': 'Fail to decode request body %s.' %e}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + + + try: + vim_info = extsys.get_vim_by_id(vimid) + except VimDriverVioException as e: + return Response(data={'error': str(e)}, status=e.status_code) + except Exception as e: + logging.exception("error %s" % e) + return Response(data={"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + url = vim_info['url']+"/auth/tokens" + headers = {"Content-Type": "application/json"} + logger.info("vimid(%(vimid)s) request token url %(url)s ", {"vimid": vimid, "url": url}) + + try: + res = requests.post(url=url, data=json.dumps(create_req), headers=headers) + tokenInfo = res.json() + resHeader = dict(res.headers) + except Exception as e: + logging.exception("error %s" % e) + return Response(data={'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + + + try: + + tenantid = tokenInfo['token']['project']['id'] + vimEndpoints = defaultdict(dict) + + for i in tokenInfo['token']['catalog']: + for j in i['endpoints']: + tmp = j['url'] + ends = deepcopy(j['url']) + ends = ends.split("/") + version = "/"+ends[3] if len(ends) > 3 else "" + ends = ends[0]+"//"+ends[2]+version + vimEndpoints[i['name']][j['interface']]=ends + res=tmp.split("/") + if i['type'] in ['image','network','cloudformation','identity']: + if i['type'] != 'identity': + res[2] = MSB_ADDRESS+"/multivim-vio/v1/" + vimid + "/" + i['name'] + else: + # use identity instead of keystone + res[2] = MSB_ADDRESS + "/multivim-vio/v1/" + vimid + "/" + i['type'] + else: + res[2]= MSB_ADDRESS+"/multivim-vio/v1/"+vimid+"/"+i['name']+"/"+tenantid + j['url']="http:"+"//"+res[2] + except Exception as e: + logging.exception("error %s" % e) + return Response(data={'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + logger.info("vimid(%(vimid)s) service enpoints %(endpoint)s ",{"vimid":vimid,"endpoint":vimEndpoints}) + tokenInfo['token']['value'] = resHeader['X-Subject-Token'] + catalog.storeEndpoint(vimid=vimid, endpoints=vimEndpoints) + Res = Response(data=tokenInfo,status=status.HTTP_200_OK) + Res['X-Subject-Token']=resHeader['X-Subject-Token'] + return Res + diff --git a/vio/vio/swagger/views/proxyplugin/image/__init__.py b/vio/vio/swagger/views/proxyplugin/image/__init__.py new file mode 100644 index 0000000..9ac359f --- /dev/null +++ b/vio/vio/swagger/views/proxyplugin/image/__init__.py @@ -0,0 +1,11 @@ +# 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.
\ No newline at end of file diff --git a/vio/vio/swagger/views/proxyplugin/image/views.py b/vio/vio/swagger/views/proxyplugin/image/views.py new file mode 100644 index 0000000..ff14eaf --- /dev/null +++ b/vio/vio/swagger/views/proxyplugin/image/views.py @@ -0,0 +1,50 @@ +# 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. + +from vio.swagger.views.proxyplugin.httpclient import BaseClient + + +class ImageServer(BaseClient): + + serverType = "glance" + + def get(self,request,vimid,other): + + (url, headers, _) = self.buildRequest(request, vimid, tail=other) + + query = "" + for k, v in request.GET.items(): + query += (k + "=" + v) + query += "&" + + if query != "": + query = query[:-1] + url += "?" + query + return self._request(url, method="GET", headers=headers) + + + def post(self, request, vimid, other): + + return self.send(request=request,method="POST",vimid=vimid,other=other) + + + def patch(self, request, vimid, other): + + return self.send(request=request,method="PATCH",vimid=vimid,other=other) + + def put(self,request,vimid,other): + + return self.send(request=request,method="PUT",vimid=vimid,other=other) + + def delete(self, request, vimid, other): + + return self.send(request=request,method="DELETE",vimid=vimid,other=other)
\ No newline at end of file diff --git a/vio/vio/swagger/views/proxyplugin/neutron/__init__.py b/vio/vio/swagger/views/proxyplugin/neutron/__init__.py new file mode 100644 index 0000000..9ac359f --- /dev/null +++ b/vio/vio/swagger/views/proxyplugin/neutron/__init__.py @@ -0,0 +1,11 @@ +# 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.
\ No newline at end of file diff --git a/vio/vio/swagger/views/proxyplugin/neutron/views.py b/vio/vio/swagger/views/proxyplugin/neutron/views.py new file mode 100644 index 0000000..23d01ad --- /dev/null +++ b/vio/vio/swagger/views/proxyplugin/neutron/views.py @@ -0,0 +1,39 @@ +# 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. + +from vio.swagger.views.proxyplugin.httpclient import BaseClient + + + +class NetWorkServer(BaseClient): + + serverType = "neutron" + + def get(self,request,vimid,other=None): + + return self.send(request=request,method="GET",vimid=vimid,other=other) + + def post(self,request,vimid,other): + + return self.send(request=request,method="POST",vimid=vimid,other=other) + + def patch(self, request, vimid, other): + + return self.send(request=request,method="PATCH",vimid=vimid,other=other) + + def put(self, request, vimid, other): + + return self.send(request=request,method="PUT",vimid=vimid,other=other) + + def delete(self, request, vimid, other): + + return self.send(request=request,method="DELETE",vimid=vimid,other=other)
\ No newline at end of file diff --git a/vio/vio/swagger/views/proxyplugin/nova/__init__.py b/vio/vio/swagger/views/proxyplugin/nova/__init__.py new file mode 100644 index 0000000..9ac359f --- /dev/null +++ b/vio/vio/swagger/views/proxyplugin/nova/__init__.py @@ -0,0 +1,11 @@ +# 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.
\ No newline at end of file diff --git a/vio/vio/swagger/views/proxyplugin/nova/views.py b/vio/vio/swagger/views/proxyplugin/nova/views.py new file mode 100644 index 0000000..6a0a93d --- /dev/null +++ b/vio/vio/swagger/views/proxyplugin/nova/views.py @@ -0,0 +1,43 @@ +# 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. + +from vio.swagger.views.proxyplugin.httpclient import BaseClient + + +class ComputeServer(BaseClient): + + serverType = "nova" + + def get(self,request,vimid,tenantid,other): + + (url, headers, _) = self.buildRequest(request, vimid, tenantid=tenantid,tail=other) + query = "" + for k, v in request.GET.items(): + query += (k + "=" + v) + query += "&" + + if query != "": + query = query[:-1] + url += "?" + query + return self._request(url, method="GET", headers=headers) + + def post(self,request,vimid,tenantid,other): + + return self.send(request=request,method="POST",vimid=vimid,tenantid=tenantid,other=other) + + def put(self,request,vimid,tenantid,other): + + return self.send(request=request,method="PUT",vimid=vimid,tenantid=tenantid,other=other) + + def delete(self,request,vimid,tenantid,other): + + return self.send(request=request,method="DELETE",vimid=vimid,tenantid=tenantid,other=other) diff --git a/vio/vio/swagger/views/proxyplugin/volumn/__init__.py b/vio/vio/swagger/views/proxyplugin/volumn/__init__.py new file mode 100644 index 0000000..9ac359f --- /dev/null +++ b/vio/vio/swagger/views/proxyplugin/volumn/__init__.py @@ -0,0 +1,11 @@ +# 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.
\ No newline at end of file diff --git a/vio/vio/swagger/views/proxyplugin/volumn/views.py b/vio/vio/swagger/views/proxyplugin/volumn/views.py new file mode 100644 index 0000000..8eccce9 --- /dev/null +++ b/vio/vio/swagger/views/proxyplugin/volumn/views.py @@ -0,0 +1,53 @@ +# 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. + +from vio.swagger.views.proxyplugin.httpclient import BaseClient + + +class VolumeServer(BaseClient): + + serverType = "cinder" + + def get(self,request,vimid,tenantid,other): + + return self.send(request=request,method="GET",vimid=vimid,tenantid=tenantid,other=other) + + def post(self,request,vimid,tenantid,other): + + return self.send(request=request,method="POST",vimid=vimid,tenantid=tenantid,other=other) + + def put(self, request, vimid, tenantid, other): + + return self.send(request=request,method="PUT",vimid=vimid,tenantid=tenantid,other=other) + + def delete(self, request, vimid, tenantid, other): + + return self.send(request=request,method="DELETE",vimid=vimid,tenantid=tenantid,other=other) + + def patch(self, request, vimid, tenantid, other): + + return self.send(request=request,method="PATCH",vimid=vimid,tenantid=tenantid,other=other) + + +class VolumeServer2(VolumeServer): + serverType = "cinderv2" + +class VolumeServer3(VolumeServer): + serverType = "volumev3" + + + + + + + + |