summaryrefslogtreecommitdiffstats
path: root/vio
diff options
context:
space:
mode:
authorliangke <lokyse@163.com>2017-10-13 13:42:03 +0800
committerliangke <lokyse@163.com>2017-10-17 10:46:40 +0800
commit41e35ae741d930a192f58adea85b8276e35932f0 (patch)
tree6189b6cad5cd12ef0a28526993d8b72aafc9987a /vio
parent985fca36a2c0b87849b9668c6f1229200309d8a5 (diff)
Support keystoneV2 in VIO plugin
Change-Id: If8fadc0f8ae718b6428feed30bfcd18579b2cd91 issue-Id: MULTICLOUD-114 Signed-off-by: liangke <lokyse@163.com>
Diffstat (limited to 'vio')
-rw-r--r--vio/vio/pub/utils/syscomm.py42
-rw-r--r--vio/vio/swagger/views/proxyplugin/identity/views.py119
2 files changed, 152 insertions, 9 deletions
diff --git a/vio/vio/pub/utils/syscomm.py b/vio/vio/pub/utils/syscomm.py
index d98e3e4..451548d 100644
--- a/vio/vio/pub/utils/syscomm.py
+++ b/vio/vio/pub/utils/syscomm.py
@@ -14,6 +14,17 @@ import inspect
import json
from collections import defaultdict
+keystoneV2Json = \
+ {
+ "auth": {
+ "tenantName": "",
+ "passwordCredentials": {
+ "username": "",
+ "password": ""
+ }
+ }
+ }
+
def fun_name():
return inspect.stack()[1][3]
@@ -44,4 +55,35 @@ class Catalogs(object):
return vim.get(serverType).get(interface, "") if vim else ""
+def verifyKeystoneV2(param):
+
+ return _walk_json(param, keystoneV2Json)
+
+
+# comapare two json by key
+def _walk_json(data, data2):
+ if isinstance(data, dict) and isinstance(data2, dict):
+ if set(data.keys()) != set(data2.keys()):
+ return False
+ else:
+ v1 = data.values()
+ v2 = data2.values()
+ v1.sort()
+ v2.sort()
+ if len(v1) != len(v2):
+ return False
+ for (i, j) in zip(v1, v2):
+ # continue compare key
+ if isinstance(i, dict) and isinstance(j, dict):
+ if not _walk_json(i, j):
+ return False
+ # ignore value
+ else:
+ continue
+
+ return True
+
+ return False
+
+
catalog = Catalogs()
diff --git a/vio/vio/swagger/views/proxyplugin/identity/views.py b/vio/vio/swagger/views/proxyplugin/identity/views.py
index 56ac864..fe4a5d3 100644
--- a/vio/vio/swagger/views/proxyplugin/identity/views.py
+++ b/vio/vio/swagger/views/proxyplugin/identity/views.py
@@ -17,6 +17,7 @@ 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.utils.syscomm import verifyKeystoneV2
from vio.pub.config.config import MSB_SERVICE_PORT, MSB_SERVICE_IP
import json
import requests
@@ -113,7 +114,9 @@ class TokenView(BaseClient):
{"vimid": vimid, "url": keystoneURL})
try:
res = requests.get(url=keystoneURL, verify=False)
- if res.status_code != status.HTTP_200_OK:
+ 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()
@@ -140,11 +143,6 @@ class TokenView(BaseClient):
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:
@@ -152,6 +150,12 @@ class TokenView(BaseClient):
data={'error': 'Fail to decode request body %s.' % e},
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ url_path = request.get_full_path()
+
+ if verifyKeystoneV2(create_req):
+ return self._keystoneV2Token(url_path, vimid,
+ create_req=create_req)
+
try:
vim_info = extsys.get_vim_by_id(vimid)
except VimDriverVioException as e:
@@ -161,17 +165,30 @@ class TokenView(BaseClient):
return Response(data={"error": str(e)},
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
- url = vim_info['url'] + "/auth/tokens"
+ 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)
+
+ url = vim_info['url']
+ # keystone version must be v3
+ if url.split('/')[-1] != "v3":
+ return Response(data={"error": "The keystone server is not v3"},
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+
+ url += "/auth/tokens"
headers = {"Content-Type": "application/json"}
- logger.info("vimid(%(vimid)s) request token url %(url)s ",
+ logger.info("vimid(%(vimid)s) request V3 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 != status.HTTP_201_CREATED:
+ 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()
resHeader = dict(res.headers)
except Exception as e:
@@ -218,3 +235,87 @@ class TokenView(BaseClient):
Res = Response(data=tokenInfo, status=status.HTTP_200_OK)
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 = 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