diff options
-rw-r--r-- | pom.xml | 2 | ||||
-rw-r--r-- | version.properties | 2 | ||||
-rw-r--r-- | vio/docker/Dockerfile | 2 | ||||
-rw-r--r-- | vio/pom.xml | 11 | ||||
-rw-r--r-- | vio/version.properties | 2 | ||||
-rw-r--r-- | vio/vio/pub/utils/syscomm.py | 42 | ||||
-rw-r--r-- | vio/vio/swagger/views/proxyplugin/identity/views.py | 119 |
7 files changed, 161 insertions, 19 deletions
@@ -18,7 +18,7 @@ <parent> <groupId>org.onap.oparent</groupId> <artifactId>oparent</artifactId> - <version>1.0.0-SNAPSHOT</version> + <version>0.1.1</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>org.onap.multicloud.openstack.vmware</groupId> diff --git a/version.properties b/version.properties index 639c1f7..0b19cfa 100644 --- a/version.properties +++ b/version.properties @@ -18,7 +18,7 @@ # because they are used in Jenkins, whose plug-in doesn't support major=1 -minor=1 +minor=0 patch=0 base_version=${major}.${minor}.${patch} diff --git a/vio/docker/Dockerfile b/vio/docker/Dockerfile index 7d2e84f..80fa427 100644 --- a/vio/docker/Dockerfile +++ b/vio/docker/Dockerfile @@ -17,7 +17,7 @@ RUN apt-get update && \ RUN cd /opt/ && \ - wget -q -O multicloud-vio.zip 'https://nexus.onap.org/service/local/artifact/maven/redirect?r=snapshots&g=org.onap.multicloud.openstack.vmware&a=multicloud-vio&v=LATEST&e=zip' && \ + wget -q -O multicloud-vio.zip 'https://nexus.onap.org/service/local/artifact/maven/redirect?r=snapshots&g=org.onap.multicloud.openstack.vmware.vio&a=multicloud-vio-plugin&v=LATEST&e=zip' && \ unzip multicloud-vio.zip && \ rm -rf multicloud-vio.zip && \ pip install -r vio/requirements.txt diff --git a/vio/pom.xml b/vio/pom.xml index 428832b..06ab660 100644 --- a/vio/pom.xml +++ b/vio/pom.xml @@ -16,17 +16,16 @@ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> - <groupId>org.onap.oparent</groupId> - <artifactId>oparent</artifactId> + <groupId>org.onap.multicloud.openstack.vmware</groupId> + <artifactId>multicloud-vio</artifactId> <version>1.0.0-SNAPSHOT</version> - <relativePath>../oparent</relativePath> </parent> <modelVersion>4.0.0</modelVersion> - <groupId>org.onap.multicloud.openstack.vmware</groupId> - <artifactId>multicloud-vio</artifactId> + <groupId>org.onap.multicloud.openstack.vmware.vio</groupId> + <artifactId>multicloud-vio-plugin</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> - <name>multicloud-opentack-vmware</name> + <name>multicloud-opentack-vmware-vio</name> <description>multicloud vio</description> <properties> <encoding>UTF-8</encoding> diff --git a/vio/version.properties b/vio/version.properties index 7f86aa1..5128787 100644 --- a/vio/version.properties +++ b/vio/version.properties @@ -3,7 +3,7 @@ # because they are used in Jenkins, whose plug-in doesn't support major=1 -minor=1 +minor=0 patch=0 base_version=${major}.${minor}.${patch} 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 |