From d6a43c98dc02287838d52d816d96d45794e4c354 Mon Sep 17 00:00:00 2001 From: liangke Date: Wed, 3 Jan 2018 16:21:01 +0800 Subject: Replace internal endpoint and Refactor identity Change-Id: I4faad06666d545b88c7482a63dcc4312c882f681 Issue-ID: MULTICLOUD-135 Signed-off-by: liangke --- vio/vio/pub/utils/syscomm.py | 6 + vio/vio/swagger/urls.py | 13 +- vio/vio/swagger/views/proxyplugin/dns/views.py | 42 +++ .../swagger/views/proxyplugin/identity/views.py | 316 ++++++++------------- vio/vio/swagger/views/proxyplugin/image/views.py | 40 +++ vio/vio/swagger/views/proxyplugin/neutron/views.py | 40 +++ 6 files changed, 259 insertions(+), 198 deletions(-) diff --git a/vio/vio/pub/utils/syscomm.py b/vio/vio/pub/utils/syscomm.py index a3b782a..6108ae3 100644 --- a/vio/vio/pub/utils/syscomm.py +++ b/vio/vio/pub/utils/syscomm.py @@ -13,6 +13,8 @@ import inspect import json from collections import defaultdict +from rest_framework import status + keystoneV2Json = \ { @@ -26,6 +28,10 @@ keystoneV2Json = \ } +SUCCESS_STATE = [status.HTTP_200_OK, status.HTTP_201_CREATED, + status.HTTP_202_ACCEPTED] + + def fun_name(): return inspect.stack()[1][3] diff --git a/vio/vio/swagger/urls.py b/vio/vio/swagger/urls.py index d768333..ca13ffb 100644 --- a/vio/vio/swagger/urls.py +++ b/vio/vio/swagger/urls.py @@ -33,12 +33,16 @@ from vio.swagger.views.port.views import CreatePortView, DeletePortView from vio.swagger.views.proxyplugin.identity.views import TokenView from vio.swagger.views.proxyplugin.identity.views import TokenV2View from vio.swagger.views.proxyplugin.identity.views import IdentityServer +from vio.swagger.views.proxyplugin.identity.views import IdentityVersionLink from vio.swagger.views.proxyplugin.nova.views import ComputeServer from vio.swagger.views.proxyplugin.image.views import ImageServer +from vio.swagger.views.proxyplugin.image.views import ImageVersionLink from vio.swagger.views.proxyplugin.neutron.views import NetWorkServer +from vio.swagger.views.proxyplugin.neutron.views import NetworkVersionLink from vio.swagger.views.proxyplugin.volumn.views import VolumeServer from vio.swagger.views.proxyplugin.heat.views import HeatServer from vio.swagger.views.proxyplugin.dns.views import DesignateServer +from vio.swagger.views.proxyplugin.dns.views import DesignateVersionLink # Registry from vio.swagger.views.registry.views import Registry @@ -234,12 +238,15 @@ urlpatterns = [ r'/identity/v2.0/tokens$', TokenV2View.as_view()), url(r'^api/multicloud-vio/v0/(?P[0-9a-z-A-Z\-\_]+)/identity$', - IdentityServer.as_view()), + IdentityVersionLink.as_view()), # handler the rest of identity requests url(r'^api/multicloud-vio/v0/(?P[0-9a-z-A-Z\-\_]+)/' r'identity/(?P(.*))$', IdentityServer.as_view()), + url(r'^api/multicloud-vio/v0/(?P[0-9a-z-A-Z\-\_]+)/glance$', + ImageVersionLink.as_view()), + url(r'^api/multicloud-vio/v0/(?P[0-9a-z-A-Z\-\_]+)/' r'glance/(?P(.*))$', ImageServer.as_view()), @@ -260,7 +267,7 @@ urlpatterns = [ VolumeServer.as_view()), url(r'^api/multicloud-vio/v0/(?P[0-9a-z-A-Z\-\_]+)/neutron$', - NetWorkServer.as_view()), + NetworkVersionLink.as_view()), url(r'^api/multicloud-vio/v0/(?P[0-9a-z-A-Z\-\_]+)/' r'neutron/(?P(.*))$', @@ -277,7 +284,7 @@ urlpatterns = [ ComputeServer.as_view()), url(r'^api/multicloud-vio/v0/(?P[0-9a-z-A-Z\-\_]+)/designate$', - DesignateServer.as_view()), + DesignateVersionLink.as_view()), url(r'^api/multicloud-vio/v0/(?P[0-9a-z-A-Z\-\_]+)/' r'designate/(?P(.*))$', diff --git a/vio/vio/swagger/views/proxyplugin/dns/views.py b/vio/vio/swagger/views/proxyplugin/dns/views.py index 60914b0..a298fec 100644 --- a/vio/vio/swagger/views/proxyplugin/dns/views.py +++ b/vio/vio/swagger/views/proxyplugin/dns/views.py @@ -10,7 +10,49 @@ # 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.swagger.views.proxyplugin.httpclient import BaseClient +from vio.pub.config.config import MSB_SERVICE_PORT, MSB_SERVICE_IP + + +logger = logging.getLogger(__name__) + + +MSB_ADDRESS = MSB_SERVICE_IP + ":" + MSB_SERVICE_PORT + "/api" + + +class DesignateVersionLink(BaseClient): + + serverType = 'designate' + + def get(self, request, vimid): + (url, headers, _) = self.buildRequest(request, vimid, tail=None, + method="GET") + + try: + res = self._request(url, method="GET", headers=headers) + if res.status_code != status.HTTP_200_OK: + return Response(data={"error": res.data}, + status=res.status_code) + res = res.data + # replace designate endpoint url with multicloud + # endpoint url. + # Look: this may contains many version + for item in res['versions']['values']: + + version = item['id'] + item['links'][0]['href'] = \ + "http://" + MSB_ADDRESS + "/multicloud-vio/v0/" \ + + vimid + "/designate/" + version + + 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) class DesignateServer(BaseClient): diff --git a/vio/vio/swagger/views/proxyplugin/identity/views.py b/vio/vio/swagger/views/proxyplugin/identity/views.py index 6652c3e..49920d3 100644 --- a/vio/vio/swagger/views/proxyplugin/identity/views.py +++ b/vio/vio/swagger/views/proxyplugin/identity/views.py @@ -19,6 +19,7 @@ from vio.pub.exceptions import VimDriverVioException from vio.pub.utils.syscomm import catalog from vio.pub.utils.syscomm import verifyKeystoneV2 from vio.pub.utils.syscomm import keystoneVersion +from vio.pub.utils.syscomm import SUCCESS_STATE from vio.pub.config.config import MSB_SERVICE_PORT, MSB_SERVICE_IP import json import requests @@ -31,14 +32,16 @@ logger = logging.getLogger(__name__) MSB_ADDRESS = MSB_SERVICE_IP + ":" + MSB_SERVICE_PORT + "/api" +NO_TENANTID_SERVICE_TYPE = ['image', 'network', 'cloudformation', + 'identity', 'dns'] -class IdentityServer(BaseClient): - serverType = 'keystone' +class IdentityVersionLink(BaseClient): - def get(self, request, vimid, other=None): + serverType = 'keystone' - (url, headers, _) = self.buildRequest(request, vimid, tail=other, + def get(self, request, vimid): + (url, headers, _) = self.buildRequest(request, vimid, tail=None, method="GET") try: @@ -47,12 +50,11 @@ class IdentityServer(BaseClient): return Response(data={"error": res.data}, status=res.status_code) res = res.data - # replace keystone auth url with multicloud - # identity url - if other is None: - res['version']['links'][0]['href'] = \ - "http://" + MSB_ADDRESS + "/multicloud-vio/v0/" \ - + vimid + "/identity" + # replace keystone endpoint url with multicloud + # endpoint url, the default version is V3 + res['version']['links'][0]['href'] = \ + "http://" + MSB_ADDRESS + "/multicloud-vio/v0/" \ + + vimid + "/identity" except Exception as e: logging.exception("error %s" % e) @@ -61,6 +63,18 @@ class IdentityServer(BaseClient): return Response(data=res, status=status.HTTP_200_OK) + +class IdentityServer(BaseClient): + + serverType = 'keystone' + + def get(self, request, vimid, other=None): + + (url, headers, _) = self.buildRequest(request, vimid, tail=other, + method="GET") + + return self._request(url, method="GET", headers=headers) + def patch(self, request, vimid, other): return self.send(request=request, method="PATCH", @@ -107,9 +121,7 @@ class TokenView(BaseClient): {"vimid": vimid, "url": url}) try: res = requests.get(url=url, verify=False) - if res.status_code not in [status.HTTP_200_OK, - status.HTTP_201_CREATED, - status.HTTP_202_ACCEPTED]: + if res.status_code not in SUCCESS_STATE: return Response(data={"error": res.content}, status=res.status_code) res = res.json() @@ -145,9 +157,11 @@ class TokenView(BaseClient): url_path = request.get_full_path() + # if request boy formatter match token v2, + # It change to use v2 authorization. if verifyKeystoneV2(create_req): - return self._keystoneV2Token(url_path, vimid, - create_req=create_req) + return _keystoneV2Token(url_path, vimid, + create_req=create_req) try: vim_info = extsys.get_vim_by_id(vimid) @@ -171,9 +185,7 @@ class TokenView(BaseClient): try: res = requests.post(url=url, data=json.dumps(create_req), headers=headers, verify=False) - if res.status_code not in [status.HTTP_200_OK, - status.HTTP_201_CREATED, - status.HTTP_202_ACCEPTED]: + if res.status_code not in SUCCESS_STATE: return Response(data={"error": res.content}, status=res.status_code) @@ -198,8 +210,7 @@ class TokenView(BaseClient): ends = ends[0] + "//" + ends[2] + version vimEndpoints[i['name']][j['interface']] = ends res = tmp.split("/") - if i['type'] in ['image', 'network', - 'cloudformation', 'identity', 'dns']: + if i['type'] in NO_TENANTID_SERVICE_TYPE: if i['type'] != 'identity': res[2] = MSB_ADDRESS + "/multicloud-vio/v0/" + \ vimid + "/" + i['name'] @@ -224,94 +235,6 @@ class TokenView(BaseClient): Res['X-Subject-Token'] = resHeader['X-Subject-Token'] return Res - def _keystoneV2Token(self, url, vimid=None, create_req=None): - - 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) - - if url[url.rfind("identity"):] != "identity/v3/tokens": - return Response(data={"error": "method not allowed"}, - status=status.HTTP_405_METHOD_NOT_ALLOWED) - # replace to v2.0 - url = keystoneVersion(url=vim_info["url"], version="v2.0") - url += "/tokens" - headers = {"Content-Type": "application/json"} - logger.info("vimid(%(vimid)s) request V2 token url %(url)s ", - {"vimid": vimid, "url": url}) - - try: - res = requests.post(url=url, data=json.dumps(create_req), - headers=headers, verify=False) - if res.status_code not in [status.HTTP_200_OK, - status.HTTP_201_CREATED, - status.HTTP_202_ACCEPTED]: - return Response(data={"error": res.content}, - status=res.status_code) - tokenInfo = res.json() - 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['access']['token']['tenant']['id'] - vimEndpoints = defaultdict(dict) - for cal in tokenInfo['access']['serviceCatalog']: - # endpoint urls - item = cal['endpoints'][0] - adminurl = deepcopy(item['adminURL']).split('/') - internalurl = deepcopy(item['internalURL']).split('/') - publicurl = deepcopy(item['publicURL']).split('/') - # VIO identity url use v3 as default even got token by v2, - # need change to v2.0 - if cal['type'] == 'identity': - adminurl[-1] = "v2.0" - publicurl[-1] = "v2.0" - internalurl[-1] = "v2.0" - adminurl = adminurl[0] + "//" + adminurl[2] + ( - "/" + adminurl[3] if len(adminurl) > 3 else "") - internalurl = internalurl[0] + "//"+internalurl[2] + ( - "/" + internalurl[3] if len(internalurl) > 3 else "") - publicurl = publicurl[0] + "//"+publicurl[2] + ( - "/" + publicurl[3] if len(publicurl) > 3 else "") - - for (key, urlname) in zip(('admin', 'internal', 'public'), - (adminurl, internalurl, - publicurl)): - vimEndpoints[cal['name']][key] = urlname - - if cal['type'] in ['image', 'network', - 'cloudformation', 'identity', 'dns']: - name = cal['name'] if cal['type'] != 'identity' \ - else cal['type'] - for i in ("adminURL", "internalURL", "publicURL"): - item[i] = "http://" + MSB_ADDRESS + \ - "/multicloud-vio/v0/" + vimid + "/" + name - else: - for i in ("adminURL", "internalURL", "publicURL"): - item[i] = "http://" + MSB_ADDRESS + \ - "/multicloud-vio/v0/" + vimid + \ - "/" + cal["name"] + "/"+tenantid - - 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}) - - catalog.storeEndpoint(vimid=vimid, endpoints=vimEndpoints) - Res = Response(data=tokenInfo, status=status.HTTP_200_OK) - return Res - class TokenV2View(BaseClient): @@ -338,9 +261,7 @@ class TokenV2View(BaseClient): {"vimid": vimid, "url": url}) try: res = requests.get(url=url, verify=False) - if res.status_code not in [status.HTTP_200_OK, - status.HTTP_201_CREATED, - status.HTTP_202_ACCEPTED]: + if res.status_code not in SUCCESS_STATE: return Response(data={"error": res.content}, status=res.status_code) res = res.json() @@ -366,88 +287,93 @@ class TokenV2View(BaseClient): url_path = request.get_full_path() - 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) - - if url_path[url_path.rfind("identity"):] != "identity/v2.0/tokens": - return Response(data={"error": "method not allowed"}, - status=status.HTTP_405_METHOD_NOT_ALLOWED) - # replace to v2.0 - url = keystoneVersion(url=vim_info['url'], version="v2.0") - url += "/tokens" - headers = {"Content-Type": "application/json"} - logger.info("vimid(%(vimid)s) request V2 token url %(url)s ", - {"vimid": vimid, "url": url}) - - try: - res = requests.post(url=url, data=json.dumps(create_req), - headers=headers, verify=False) - if res.status_code not in [status.HTTP_200_OK, - status.HTTP_201_CREATED, - status.HTTP_202_ACCEPTED]: - return Response(data={"error": res.content}, - status=res.status_code) - tokenInfo = res.json() - 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['access']['token']['tenant']['id'] - vimEndpoints = defaultdict(dict) - for cal in tokenInfo['access']['serviceCatalog']: - # endpoint urls - item = cal['endpoints'][0] - adminurl = deepcopy(item['adminURL']).split('/') - internalurl = deepcopy(item['internalURL']).split('/') - publicurl = deepcopy(item['publicURL']).split('/') - # VIO identity url use v3 as default even got token by v2, - # need change to v2.0 - if cal['type'] == 'identity': - adminurl[-1] = "v2.0" - publicurl[-1] = "v2.0" - internalurl[-1] = "v2.0" - adminurl = adminurl[0] + "//" + adminurl[2] + ( - "/" + adminurl[3] if len(adminurl) > 3 else "") - internalurl = internalurl[0] + "//" + internalurl[2] + ( - "/" + internalurl[3] if len(internalurl) > 3 else "") - publicurl = publicurl[0] + "//" + publicurl[2] + ( - "/" + publicurl[3] if len(publicurl) > 3 else "") - - for (key, urlname) in zip(('admin', 'internal', 'public'), - (adminurl, internalurl, - publicurl)): - vimEndpoints[cal['name']][key] = urlname - - if cal['type'] in ['image', 'network', - 'cloudformation', 'identity', 'dns']: - name = cal['name'] if cal['type'] != 'identity' \ - else cal['type'] - for i in ("adminURL", "internalURL", "publicURL"): - item[i] = "http://" + MSB_ADDRESS + \ - "/multicloud-vio/v0/" + vimid + "/" + name - else: - for i in ("adminURL", "internalURL", "publicURL"): - item[i] = "http://" + MSB_ADDRESS + \ - "/multicloud-vio/v0/" + vimid + \ - "/" + cal["name"] + "/" + tenantid - - 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}) - - catalog.storeEndpoint(vimid=vimid, endpoints=vimEndpoints) - Res = Response(data=tokenInfo, status=status.HTTP_200_OK) + return _keystoneV2Token(url=url_path, + vimid=vimid, + create_req=create_req) + + +def _keystoneV2Token(url, vimid=None, create_req=None): + + 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) + + if url[url.rfind("identity"):] not in ["identity/v3/tokens", + "identity/v2.0/tokens"]: + return Response(data={"error": "method not allowed"}, + status=status.HTTP_405_METHOD_NOT_ALLOWED) + # replace to v2.0 + url = keystoneVersion(url=vim_info["url"], version="v2.0") + url += "/tokens" + headers = {"Content-Type": "application/json"} + logger.info("vimid(%(vimid)s) request V2 token url %(url)s ", + {"vimid": vimid, "url": url}) + + try: + res = requests.post(url=url, data=json.dumps(create_req), + headers=headers, verify=False) + if res.status_code not in SUCCESS_STATE: + return Response(data={"error": res.content}, + status=res.status_code) + tokenInfo = res.json() + 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['access']['token']['tenant']['id'] + vimEndpoints = defaultdict(dict) + for cal in tokenInfo['access']['serviceCatalog']: + # endpoint urls + item = cal['endpoints'][0] + adminurl = deepcopy(item['adminURL']).split('/') + internalurl = deepcopy(item['internalURL']).split('/') + publicurl = deepcopy(item['publicURL']).split('/') + # VIO identity url use v3 as default even got token by v2, + # need change to v2.0 + if cal['type'] == 'identity': + adminurl[-1] = "v2.0" + publicurl[-1] = "v2.0" + internalurl[-1] = "v2.0" + adminurl = adminurl[0] + "//" + adminurl[2] + ( + "/" + adminurl[3] if len(adminurl) > 3 else "") + internalurl = internalurl[0] + "//"+internalurl[2] + ( + "/" + internalurl[3] if len(internalurl) > 3 else "") + publicurl = publicurl[0] + "//"+publicurl[2] + ( + "/" + publicurl[3] if len(publicurl) > 3 else "") + + for (key, urlname) in zip(('admin', 'internal', 'public'), + (adminurl, internalurl, + publicurl)): + vimEndpoints[cal['name']][key] = urlname + + if cal['type'] in NO_TENANTID_SERVICE_TYPE: + name = cal['name'] if cal['type'] != 'identity' \ + else cal['type'] + for i in ("adminURL", "internalURL", "publicURL"): + item[i] = "http://" + MSB_ADDRESS + \ + "/multicloud-vio/v0/" + vimid + "/" + name + else: + for i in ("adminURL", "internalURL", "publicURL"): + item[i] = "http://" + MSB_ADDRESS + \ + "/multicloud-vio/v0/" + vimid + \ + "/" + cal["name"] + "/"+tenantid + + 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}) - return Res + catalog.storeEndpoint(vimid=vimid, endpoints=vimEndpoints) + Res = Response(data=tokenInfo, status=status.HTTP_200_OK) + return Res diff --git a/vio/vio/swagger/views/proxyplugin/image/views.py b/vio/vio/swagger/views/proxyplugin/image/views.py index 67a45c4..a44308e 100644 --- a/vio/vio/swagger/views/proxyplugin/image/views.py +++ b/vio/vio/swagger/views/proxyplugin/image/views.py @@ -10,7 +10,47 @@ # 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.swagger.views.proxyplugin.httpclient import BaseClient +from vio.pub.config.config import MSB_SERVICE_PORT, MSB_SERVICE_IP + + +logger = logging.getLogger(__name__) + + +MSB_ADDRESS = MSB_SERVICE_IP + ":" + MSB_SERVICE_PORT + "/api" + + +class ImageVersionLink(BaseClient): + + serverType = 'glance' + + def get(self, request, vimid): + (url, headers, _) = self.buildRequest(request, vimid, tail=None, + method="GET") + + try: + res = self._request(url, method="GET", headers=headers) + res = res.data + # replace glance endpoint url with multicloud + # endpoint url. + # Look: this may contains many version + for item in res['versions']: + + version = item['id'] + version = version[:2] if len(version) > 2 else version + item['links'][0]['href'] = \ + "http://" + MSB_ADDRESS + "/multicloud-vio/v0/" \ + + vimid + "/glance//" + version + "/" + + except Exception as e: + logging.exception("error %s" % e) + return Response(data={"error": str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + # MARK: this response status is 301 + return Response(data=res, status=status.HTTP_300_MULTIPLE_CHOICES) class ImageServer(BaseClient): diff --git a/vio/vio/swagger/views/proxyplugin/neutron/views.py b/vio/vio/swagger/views/proxyplugin/neutron/views.py index fc52dcc..3bc3cc8 100644 --- a/vio/vio/swagger/views/proxyplugin/neutron/views.py +++ b/vio/vio/swagger/views/proxyplugin/neutron/views.py @@ -10,7 +10,47 @@ # 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.swagger.views.proxyplugin.httpclient import BaseClient +from vio.pub.config.config import MSB_SERVICE_PORT, MSB_SERVICE_IP + + +logger = logging.getLogger(__name__) + + +MSB_ADDRESS = MSB_SERVICE_IP + ":" + MSB_SERVICE_PORT + "/api" + + +class NetworkVersionLink(BaseClient): + + serverType = 'neutron' + + def get(self, request, vimid): + (url, headers, _) = self.buildRequest(request, vimid, tail=None, + method="GET") + + try: + res = self._request(url, method="GET", headers=headers) + if res.status_code != status.HTTP_200_OK: + return Response(data={"error": res.data}, + status=res.status_code) + res = res.data + # replace neutron endpoint url with multicloud + # endpoint url. + for item in res['versions']: + version = item['id'] + item['links'][0]['href'] = \ + "http://" + MSB_ADDRESS + "/multicloud-vio/v0/" \ + + vimid + "/neutron/" + version + "/" + + 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) class NetWorkServer(BaseClient): -- cgit 1.2.3-korg