From e82128c24dfea09863088594bc1bba35427db433 Mon Sep 17 00:00:00 2001 From: liangke Date: Tue, 24 Oct 2017 14:40:39 +0800 Subject: Fix issue of KeystoneV2 Change-Id: I2d670b6d68af436adf7b8519487189f2f0ca428f Issue-id: MULTICLOUD-114 Signed-off-by: liangke --- vio/vio/pub/utils/fileutil.py | 2 +- vio/vio/pub/utils/restcall.py | 4 - vio/vio/swagger/urls.py | 12 + .../views/fakeplugin/fakeData/fakeResponse.py | 324 ++++++++++++++++++++- vio/vio/swagger/views/fakeplugin/heat/views.py | 2 +- vio/vio/swagger/views/fakeplugin/identity/views.py | 39 ++- .../swagger/views/proxyplugin/identity/views.py | 141 +++++++++ 7 files changed, 512 insertions(+), 12 deletions(-) (limited to 'vio') diff --git a/vio/vio/pub/utils/fileutil.py b/vio/vio/pub/utils/fileutil.py index 07b5124..dabf198 100644 --- a/vio/vio/pub/utils/fileutil.py +++ b/vio/vio/pub/utils/fileutil.py @@ -44,7 +44,7 @@ def download_file_from_http(url, local_dir, file_name): save_file.close() req.close() is_download_ok = True - except: + except Exception: logger.error(traceback.format_exc()) logger.error("Failed to download %s to %s.", url, local_file_name) return is_download_ok, local_file_name diff --git a/vio/vio/pub/utils/restcall.py b/vio/vio/pub/utils/restcall.py index 15dd90b..ee84447 100644 --- a/vio/vio/pub/utils/restcall.py +++ b/vio/vio/pub/utils/restcall.py @@ -93,10 +93,6 @@ def call_req(base_url, user, passwd, auth_type, resource, method, content='', res_info = ("The URL[%s] request failed or is not responding." % full_url) ret = [3, res_info, resp_status, resp] - except: - logger.error(traceback.format_exc()) - ret = [4, str(sys.exc_info()), resp_status, resp] - # logger.debug("[%s]ret=%s" % (callid, str(ret))) return ret diff --git a/vio/vio/swagger/urls.py b/vio/vio/swagger/urls.py index e40bc77..5bf474f 100644 --- a/vio/vio/swagger/urls.py +++ b/vio/vio/swagger/urls.py @@ -31,6 +31,7 @@ from vio.swagger.views.port.views import CreatePortView, DeletePortView # proxy 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.nova.views import ComputeServer from vio.swagger.views.proxyplugin.image.views import ImageServer @@ -48,6 +49,7 @@ from vio.swagger.views.extensions.views import Extensions # fake from vio.swagger.views.fakeplugin.identity.views import FakeProjects from vio.swagger.views.fakeplugin.identity.views import FakeToken +from vio.swagger.views.fakeplugin.identity.views import FakeTokenV2 from vio.swagger.views.fakeplugin.image.views import FakeImage from vio.swagger.views.fakeplugin.image.views import FakeImageDetail from vio.swagger.views.fakeplugin.image.views import FakeImageSchema @@ -137,6 +139,8 @@ urlpatterns = [ # fake urls url(r'^api/multicloud-vio/v0/vmware_fake/identity/v3', FakeToken.as_view()), + url(r'api/multicloud-vio/v0/vmware_fake/identity/v2.0', + FakeTokenV2.as_view()), url(r'^api/multicloud-vio/v0/vmware_fake/identity/projects$', FakeProjects.as_view()), url(r'^api/multicloud-vio/v0/vmware_fake/identity/projects/' @@ -199,6 +203,12 @@ urlpatterns = [ url(r'api/multicloud-vio/v0/vmware_fake/heat/' r'(?P[0-9a-z-A-Z\-\_]+)' r'/stacks/preview$', FakeHeatServicePreview.as_view()), + + url(r'api/multicloud-vio/v0/vmware_fake/heat/' + r'(?P[0-9a-z-A-Z\-\_]+)' + r'/stacks/(?P[0-9a-z-A-Z\-\_]+)', + FakeHeatService.as_view()), + url(r'api/multicloud-vio/v0/vmware_fake/heat/' r'(?P[0-9a-z-A-Z\-\_]+)' r'/stacks/(?P[0-9a-z-A-Z\-\_]+)' @@ -213,6 +223,8 @@ urlpatterns = [ # proxy url(r'^api/multicloud-vio/v0/(?P[0-9a-z-A-Z\-\_]+)/identity/v3', TokenView.as_view()), + url(r'api/multicloud-vio/v0/(?P[0-9a-z-A-Z\-\_]+)/identity/v2.0', + TokenV2View.as_view()), url(r'^api/multicloud-vio/v0/(?P[0-9a-z-A-Z\-\_]+)/identity$', IdentityServer.as_view()), diff --git a/vio/vio/swagger/views/fakeplugin/fakeData/fakeResponse.py b/vio/vio/swagger/views/fakeplugin/fakeData/fakeResponse.py index 1508e3f..c0ca1dc 100644 --- a/vio/vio/swagger/views/fakeplugin/fakeData/fakeResponse.py +++ b/vio/vio/swagger/views/fakeplugin/fakeData/fakeResponse.py @@ -67,6 +67,39 @@ def keystone_version(): return data +def keystone_version2(): + + data = { + "version": { + "status": "deprecated", + "updated": "2016-08-04T00:00:00Z", + "media-types": [ + { + "base": "application/json", + "type": "application/" + "vnd.openstack.identity-v2.0+json" + } + ], + "id": "v2.0", + "links": [ + { + "href": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/identity/v2.0", + "rel": "self" + }, + { + "href": "https://docs.openstack.org/", + "type": "text/html", + "rel": "describedby" + } + ] + } + } + + return data + + def keystone_token(teanatid=None): data = { @@ -335,6 +368,294 @@ def keystone_token(teanatid=None): return data +def keystone_tokenV2(): + + data = \ + { + "access": { + "token": { + "issued_at": "2017-10-24T06:47:51.000000Z", + "expires": "2017-10-24T08:47:51.000000Z", + "id": Token, + "tenant": { + "enabled": true, + "description": "Bootstrap " + "project for " + "initializing the cloud.", + "name": "admin", + "id": Tenantid + }, + "audit_ids": [ + "_KKMw5S3RUCl8SNKwmiDcA" + ] + }, + "serviceCatalog": [ + { + "endpoints_links": [], + "endpoints": [ + { + "adminURL": + "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/nova/" + Tenantid, + "region": "nova", + "publicURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/nova/" + + Tenantid, + "internalURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/nova/" + + Tenantid, + "id": "10fd2ceacc994090a96ab3b8541e066e" + } + ], + "type": "compute", + "name": "nova" + }, + { + "endpoints_links": [], + "endpoints": [ + { + "adminURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/neutron", + "region": "nova", + "publicURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/neutron", + "internalURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/neutron", + "id": "1bf876c18fd64e4f89cfa3c8a9624864" + } + ], + "type": "network", + "name": "neutron" + }, + { + "endpoints_links": [], + "endpoints": [ + { + "adminURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/cinderv2/" + + Tenantid, + "region": "nova", + "publicURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/cinderv2/" + + Tenantid, + "internalURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/cinderv2/" + + Tenantid, + "id": "70ed007f3aae44288e1851d5ade542ef" + } + ], + "type": "volumev2", + "name": "cinderv2" + }, + { + "endpoints_links": [], + "endpoints": [ + { + "adminURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/cinderv3/" + + Tenantid, + "region": "nova", + "publicURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/cinderv3/" + + Tenantid, + "internalURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/cinderv3/" + + Tenantid, + "id": "2090cf622a904c1bbc0f500c2f1b1c78" + } + ], + "type": "volumev3", + "name": "cinderv3" + }, + { + "endpoints_links": [], + "endpoints": [ + { + "adminURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/glance", + "region": "nova", + "publicURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmare_fake/glance", + "internalURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/glance", + "id": "25404699d5fc4e1989f421243c0006d1" + } + ], + "type": "image", + "name": "glance" + }, + { + "endpoints_links": [], + "endpoints": [ + { + "adminURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/nova_legacy/" + + Tenantid, + "region": "nova", + "publicURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/nova_legacy/" + + Tenantid, + "internalURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/" + "nova_legacy/" + + Tenantid, + "id": "303b4193e0784d0391a2bc318ff27229" + } + ], + "type": "compute_legacy", + "name": "nova_legacy" + }, + { + "endpoints_links": [], + "endpoints": [ + { + "adminURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/heat-cfn", + "region": "nova", + "publicURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/heat-cfn", + "internalURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/heat-cfn", + "id": "1152aa50dd1a4a99be272aa84f910ef6" + } + ], + "type": "cloudformation", + "name": "heat-cfn" + }, + { + "endpoints_links": [], + "endpoints": [ + { + "adminURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/cinder/" + + Tenantid, + "region": "nova", + "publicURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/cinder/" + + Tenantid, + "internalURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/cinder/" + + Tenantid, + "id": "1cdfe5803856412f9daa3bed79f6e9ac" + } + ], + "type": "volume", + "name": "cinder" + }, + { + "endpoints_links": [], + "endpoints": [ + { + "adminURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/heat/" + + Tenantid, + "region": "nova", + "publicURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/heat/" + + Tenantid, + "internalURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/heat/" + + Tenantid, + "id": "7eb9b5633c8f431da405192665782392" + } + ], + "type": "orchestration", + "name": "heat" + }, + { + "endpoints_links": [], + "endpoints": [ + { + "adminURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/placement/" + + Tenantid, + "region": "nova", + "publicURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/placement/" + + Tenantid, + "internalURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/placement/" + + Tenantid, + "id": "9b509d9d5db54f51bbd27d9991586250" + } + ], + "type": "placement", + "name": "placement" + }, + { + "endpoints_links": [], + "endpoints": [ + { + "adminURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/identity", + "region": "nova", + "publicURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/identity", + "internalURL": "http://" + MSB_SERVER + + "/api/multicloud-vio/" + "v0/vmware_fake/identity", + "id": "62a158d5b28d4fdbb485e8cf6ae5cc92" + } + ], + "type": "identity", + "name": "keystone" + } + ], + "user": { + "username": "admin", + "roles_links": [], + "id": "08a03743532f4c64b5e283b15646fd10", + "roles": [ + { + "name": "admin" + } + ], + "name": "admin" + }, + "metadata": { + "is_admin": 0, + "roles": [ + "cd1ffa75112d47f9ac64a758fa75d688" + ] + } + } + } + + return data + + def list_projects(token=None): if token != Token: @@ -2086,9 +2407,6 @@ def showStack(stack_id, token): if token != Token: return {"error": {"message": "unauthorization", "code": 401}} - if stack_id != STACK_ID: - return {"error": {"message": "stack not found", "code": 404}} - data = \ { "stack": { diff --git a/vio/vio/swagger/views/fakeplugin/heat/views.py b/vio/vio/swagger/views/fakeplugin/heat/views.py index c520ef4..243a33d 100644 --- a/vio/vio/swagger/views/fakeplugin/heat/views.py +++ b/vio/vio/swagger/views/fakeplugin/heat/views.py @@ -56,7 +56,7 @@ class FakeHeatService(APIView): data = "" if stackName is None and stackID is None: data = getAllStacks(token=token) - elif stackName and stackID: + elif stackName or stackID: data = showStack(stack_id=stackID, token=token) if 'error' in data: diff --git a/vio/vio/swagger/views/fakeplugin/identity/views.py b/vio/vio/swagger/views/fakeplugin/identity/views.py index d291b2e..0ef35d7 100644 --- a/vio/vio/swagger/views/fakeplugin/identity/views.py +++ b/vio/vio/swagger/views/fakeplugin/identity/views.py @@ -4,8 +4,14 @@ from rest_framework import status from rest_framework.views import APIView from rest_framework.response import Response -from vio.swagger.views.fakeplugin.fakeData.fakeResponse import keystone_token -from vio.swagger.views.fakeplugin.fakeData.fakeResponse import keystone_version +from vio.swagger.views.fakeplugin.fakeData.fakeResponse import \ + keystone_token +from vio.swagger.views.fakeplugin.fakeData.fakeResponse import \ + keystone_tokenV2 +from vio.swagger.views.fakeplugin.fakeData.fakeResponse import \ + keystone_version +from vio.swagger.views.fakeplugin.fakeData.fakeResponse import \ + keystone_version2 from vio.swagger.views.fakeplugin.fakeData.fakeResponse import list_projects from vio.swagger.views.fakeplugin.fakeData.fakeResponse import show_project @@ -42,7 +48,7 @@ class FakeToken(APIView): except Exception as e: return Response( data={'error': 'Invalidate request body %s.' % e}, - status=status.HTTP_500_INTERNAL_SERVER_ERROR) + status=status.HTTP_400_BAD_REQUEST) url_path = request.get_full_path() @@ -55,3 +61,30 @@ class FakeToken(APIView): res = Response(data=tokeninfo, status=status.HTTP_201_CREATED) res['X-Subject-Token'] = tokeninfo['token']['value'] return res + + +class FakeTokenV2(APIView): + + def get(self, request): + + return Response(data=keystone_version2(), + status=status.HTTP_200_OK) + + def post(self, request): + + try: + json.loads(request.body) + except Exception as e: + return Response( + data={'error': 'Invalidate request body %s.' % e}, + status=status.HTTP_400_BAD_REQUEST) + + url_path = request.get_full_path() + + 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) + + tokeninfo = keystone_tokenV2() + return Response(data=tokeninfo, status=status.HTTP_200_OK) diff --git a/vio/vio/swagger/views/proxyplugin/identity/views.py b/vio/vio/swagger/views/proxyplugin/identity/views.py index fe4a5d3..1791c71 100644 --- a/vio/vio/swagger/views/proxyplugin/identity/views.py +++ b/vio/vio/swagger/views/proxyplugin/identity/views.py @@ -319,3 +319,144 @@ class TokenView(BaseClient): catalog.storeEndpoint(vimid=vimid, endpoints=vimEndpoints) Res = Response(data=tokenInfo, status=status.HTTP_200_OK) return Res + + +class TokenV2View(BaseClient): + + serverType = "identity" + + def get(self, request, vimid): + + url_path = request.get_full_path() + if url_path[url_path.rfind("identity"):] != "identity/v2.0": + 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'] + # replace to v2.0 + url = keystoneURL.split('/') + url[-1] = 'v2.0' + url = "/".join(url) + + logger.info("vimid(%(vimid)s) get keystoneV2 url %(url)s ", + {"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]: + return Response(data={"error": res.content}, + status=res.status_code) + res = res.json() + res['version']['links'][0]['href'] = \ + "http://" + MSB_ADDRESS + "/multicloud-vio/v0/" \ + + vimid + "/identity/v2.0" + + 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 post(self, request, vimid): + + 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) + + 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 = vim_info['url'].split('/') + url[-1] = 'v2.0' + url = "/".join(url) + 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('/') + 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']: + 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 -- cgit 1.2.3-korg