diff options
author | Huang Haibin <haibin.huang@intel.com> | 2018-03-08 22:05:26 +0800 |
---|---|---|
committer | Huang Haibin <haibin.huang@intel.com> | 2018-03-10 00:38:17 +0800 |
commit | 51fde27c2a12f525e94ecd3a83238a46215d9392 (patch) | |
tree | 4b9b72d4048209d410c0f9bc8a25a9561f3fcfa0 /newton/newton/proxy | |
parent | c701ab185721e50cca3d432220361aaa723358cc (diff) |
newton use share library
Change-Id: I0ed8ced042862edf8afa87fec3b457d019e811b4
Issue-ID: MULTICLOUD-138
Signed-off-by: Huang Haibin <haibin.huang@intel.com>
Diffstat (limited to 'newton/newton/proxy')
-rw-r--r-- | newton/newton/proxy/tests/test_identity_proxy.py | 6 | ||||
-rw-r--r-- | newton/newton/proxy/tests/test_service_proxy.py | 6 | ||||
-rw-r--r-- | newton/newton/proxy/urls.py | 2 | ||||
-rw-r--r-- | newton/newton/proxy/views/dnsaasdelegate.py | 196 | ||||
-rw-r--r-- | newton/newton/proxy/views/identityV3.py | 215 | ||||
-rw-r--r-- | newton/newton/proxy/views/proxy_utils.py | 196 | ||||
-rw-r--r-- | newton/newton/proxy/views/services.py | 242 |
7 files changed, 20 insertions, 843 deletions
diff --git a/newton/newton/proxy/tests/test_identity_proxy.py b/newton/newton/proxy/tests/test_identity_proxy.py index 5d7616c5..f61ba699 100644 --- a/newton/newton/proxy/tests/test_identity_proxy.py +++ b/newton/newton/proxy/tests/test_identity_proxy.py @@ -19,9 +19,9 @@ import mock from rest_framework import status import unittest -from newton.requests.tests import test_base -from newton.requests.views.util import VimDriverUtils -from newton.requests.tests import mock_info +from newton_base.tests import test_base +from newton_base.util import VimDriverUtils +from newton_base.tests import mock_info mock_catalog_response = { diff --git a/newton/newton/proxy/tests/test_service_proxy.py b/newton/newton/proxy/tests/test_service_proxy.py index 39cc3dd9..d11ccb06 100644 --- a/newton/newton/proxy/tests/test_service_proxy.py +++ b/newton/newton/proxy/tests/test_service_proxy.py @@ -20,9 +20,9 @@ import mock from rest_framework import status import unittest -from newton.requests.tests import mock_info -from newton.requests.tests import test_base -from newton.requests.views.util import VimDriverUtils +from newton_base.tests import mock_info +from newton_base.tests import test_base +from newton_base.util import VimDriverUtils MOCK_GET_SERVERS_RESPONSE = { "servers": [ diff --git a/newton/newton/proxy/urls.py b/newton/newton/proxy/urls.py index d5d67800..0322e79c 100644 --- a/newton/newton/proxy/urls.py +++ b/newton/newton/proxy/urls.py @@ -17,7 +17,7 @@ from rest_framework.urlpatterns import format_suffix_patterns from newton.proxy.views import identityV3 from newton.proxy.views import services -from newton.proxy.views import dnsaasdelegate +from newton_base.proxy import dnsaasdelegate urlpatterns = [ # url(r'^identity/v2)$', diff --git a/newton/newton/proxy/views/dnsaasdelegate.py b/newton/newton/proxy/views/dnsaasdelegate.py deleted file mode 100644 index e2c657d9..00000000 --- a/newton/newton/proxy/views/dnsaasdelegate.py +++ /dev/null @@ -1,196 +0,0 @@ -# Copyright (c) 2017-2018 Wind River Systems, 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. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging -import json -import traceback - -from keystoneauth1.exceptions import HttpError -import re -from rest_framework.permissions import BasePermission -from rest_framework.response import Response -from rest_framework import status -from rest_framework.views import APIView - -from newton.proxy.views.services import Services - -from newton.proxy.views.proxy_utils import ProxyUtils -from newton.pub.exceptions import VimDriverNewtonException -from newton.pub.msapi import extsys -from newton.requests.views.util import VimDriverUtils - - -logger = logging.getLogger(__name__) - -DEBUG=True - -class DnsaasDelegate(Services): - ''' - DNSaaS delegate service - ''' - - def __init__(self): - self._logger = logger - - - def _do_action(self, action, request, vim_id, servicetype, requri): - tmp_auth_token = self._get_token(request) - try: - # fetch the auth_state out of cache - auth_state_str, metadata_catalog_str = VimDriverUtils.get_token_cache(tmp_auth_token) - - if not auth_state_str: - #invalid token - return Response(data={'error': "request token %s is not valid" % (tmp_auth_token)}, - status=status.HTTP_404_NOT_FOUND) - - # get project name from auth_state - auth_state = json.loads(auth_state_str) - if not auth_state: - # invalid token - return Response(data={'error': "request token %s is broken" % (tmp_auth_token)}, - status=status.HTTP_404_NOT_FOUND) - - tenant_name = auth_state['body']['token']['project']['name'] - #tenant_id = auth_state['body']['token']['project']['id'] - - #find out the delegated DNSaaS provider - viminfo = VimDriverUtils.get_vim_info(vim_id) - if not viminfo: - return Response(data={'error': "vimid %s is not found" % (vim_id)}, - status=status.HTTP_404_NOT_FOUND) - - cloud_dns_delegate_info = None - cloud_extra_info_str = viminfo.get('cloud_extra_info') - if cloud_extra_info_str: - cloud_extra_info = json.loads(cloud_extra_info_str) - cloud_dns_delegate_info = cloud_extra_info.get("dns-delegate") - - if not cloud_dns_delegate_info \ - or not cloud_dns_delegate_info.get("cloud-owner") \ - or not cloud_dns_delegate_info.get("cloud-region-id"): - return Response(data={'error': "dns-delegate for vimid %s is not configured" - % (vim_id)}, - status=status.HTTP_404_NOT_FOUND) - - vimid_delegate = cloud_dns_delegate_info.get("cloud-owner") \ - + "_" \ - + cloud_dns_delegate_info.get("cloud-region-id") - - - #now forward request to delegated DNS service endpoint - vim = VimDriverUtils.get_vim_info(vimid_delegate) - if not vim: - return Response(data={'error': "vimid %s is not found" % (vimid_delegate)}, - status=status.HTTP_404_NOT_FOUND) - - sess = VimDriverUtils.get_session(vim, tenant_name=tenant_name) - - cloud_owner, regionid = extsys.decode_vim_id(vimid_delegate) - interface = 'public' - service = { - 'service_type': servicetype, - 'interface': interface, - 'region_id': regionid - } - - req_resource = requri - querystr = VimDriverUtils.get_query_part(request) - if querystr: - req_resource += "?" + querystr - - self._logger.debug("service " + action + " request uri %s" % (req_resource)) - if(action == "get"): - resp = sess.get(req_resource, endpoint_filter=service, - headers={"Content-Type": "application/json", - "Accept": "application/json"}) - elif(action == "post"): - resp = sess.post(req_resource, data=json.JSONEncoder().encode(request.data), - endpoint_filter=service, - headers={"Content-Type": "application/json", - "Accept": "application/json"}) - elif(action == "put"): - resp = sess.put(req_resource, data=json.JSONEncoder().encode(request.data), - endpoint_filter=service, - headers={"Content-Type": "application/json", - "Accept": "application/json"}) - elif(action == "patch"): - resp = sess.patch(req_resource, data=json.JSONEncoder().encode(request.data), - endpoint_filter=service, - headers={"Content-Type": "application/json", - "Accept": "application/json"}) - elif (action == "delete"): - resp = sess.delete(req_resource, endpoint_filter=service, - headers={"Content-Type": "application/json", - "Accept": "application/json"}) - content = resp.json() if resp.content else None - self._logger.debug("service " + action + " response: %s, %s" % (resp.status_code, content)) - - if (action == "delete"): - return Response(headers={'X-Subject-Token': tmp_auth_token}, status=resp.status_code) - else: - #content = ProxyUtils.update_dnsaas_project_id(content, tenant_id) - return Response(headers={'X-Subject-Token': tmp_auth_token}, data=content, status=resp.status_code) - - except VimDriverNewtonException as e: - return Response(data={'error': e.content}, status=e.status_code) - except HttpError as e: - self._logger.error("HttpError: status:%s, response:%s" % (e.http_status, e.response.json())) - return Response(data=e.response.json(), status=e.http_status) - except Exception as e: - self._logger.error(traceback.format_exc()) - return Response(data={'error': str(e)}, - status=status.HTTP_500_INTERNAL_SERVER_ERROR) - - def get(self, request, vimid="", servicetype="dns-delegate", requri=""): - self._logger.debug("DnsaasDelegate--get::META> %s" % request.META) - self._logger.debug("DnsaasDelegate--get::data> %s" % request.data) - self._logger.debug("DnsaasDelegate--get::vimid, servicetype, requri> %s,%s,%s" - % (vimid, servicetype, requri)) - return self._do_action("get", request, vimid, "dns", requri) - - def head(self, request, vimid="", servicetype="dns-delegate", requri=""): - self._logger.debug("DnsaasDelegate--get::META> %s" % request.META) - self._logger.debug("DnsaasDelegate--get::data> %s" % request.data) - self._logger.debug("DnsaasDelegate--get::vimid, servicetype, requri> %s,%s,%s" - % (vimid, servicetype, requri)) - return self._do_action("head", request, vimid, "dns", requri) - - def post(self, request, vimid="", servicetype="dns-delegate", requri=""): - self._logger.debug("DnsaasDelegate--get::META> %s" % request.META) - self._logger.debug("DnsaasDelegate--get::data> %s" % request.data) - self._logger.debug("DnsaasDelegate--get::vimid, servicetype, requri> %s,%s,%s" - % (vimid, servicetype, requri)) - return self._do_action("post", request, vimid, "dns", requri) - - def put(self, request, vimid="", servicetype="dns-delegate", requri=""): - self._logger.debug("DnsaasDelegate--get::META> %s" % request.META) - self._logger.debug("DnsaasDelegate--get::data> %s" % request.data) - self._logger.debug("DnsaasDelegate--get::vimid, servicetype, requri> %s,%s,%s" - % (vimid, servicetype, requri)) - return self._do_action("put", request, vimid, "dns", requri) - - def patch(self, request, vimid="", servicetype="dns-delegate", requri=""): - self._logger.debug("DnsaasDelegate--get::META> %s" % request.META) - self._logger.debug("DnsaasDelegate--get::data> %s" % request.data) - self._logger.debug("DnsaasDelegate--get::vimid, servicetype, requri> %s,%s,%s" - % (vimid, servicetype, requri)) - return self._do_action("patch", request, vimid, "dns", requri) - - def delete(self, request, vimid="", servicetype="dns-delegate", requri=""): - self._logger.debug("DnsaasDelegate--get::META> %s" % request.META) - self._logger.debug("DnsaasDelegate--get::data> %s" % request.data) - self._logger.debug("DnsaasDelegate--get::vimid, servicetype, requri> %s,%s,%s" - % (vimid, servicetype, requri)) - return self._do_action("delete", request, vimid, "dns", requri) diff --git a/newton/newton/proxy/views/identityV3.py b/newton/newton/proxy/views/identityV3.py index 9707726c..dd280314 100644 --- a/newton/newton/proxy/views/identityV3.py +++ b/newton/newton/proxy/views/identityV3.py @@ -13,225 +13,22 @@ # limitations under the License. import logging -import json -import traceback -from django.core.cache import cache - -from keystoneauth1 import access -from keystoneauth1.access import service_catalog -from keystoneauth1.exceptions import HttpError -from rest_framework import status -from rest_framework.response import Response -from rest_framework.views import APIView - -from newton.pub.config import config -from newton.pub.exceptions import VimDriverNewtonException -from newton.requests.views.util import VimDriverUtils -from newton.proxy.views.proxy_utils import ProxyUtils +from django.conf import settings +from newton_base.proxy import identityV3 as newton_identityV3 logger = logging.getLogger(__name__) DEBUG=True -v3_version_detail = { - "version": { - "status": "stable", - "updated": "2014-04-17T00:00:00Z", - "media-types": [ - { - "base": "application/json", - "type": "application/vnd.openstack.identity-v3+json" - } - ], - "id": "v3", - "links": [ - ] - } -} - -class Tokens(APIView): - service = {'service_type': 'identity', - 'interface': 'public'} +class Tokens(newton_identityV3.Tokens): def __init__(self): - self.proxy_prefix = config.MULTICLOUD_PREFIX + self.proxy_prefix = settings.MULTICLOUD_PREFIX self._logger = logger - def get(self, request, vimid=""): - self._logger.debug("identityV3--get::META> %s" % request.META) - - return Response(data=v3_version_detail, status=status.HTTP_200_OK) - - def post(self, request, vimid=""): - self._logger.debug("identityV3--post::META> %s" % request.META) - self._logger.debug("identityV3--post::data> %s" % request.data) - self._logger.debug("identityV3--post::vimid> %s" % (vimid)) - sess = None - resp = None - resp_body = None - try: - tenant_name = request.data.get("tenant_name") - tenant_id = request.data.get("tenant_id") - - #backward support for keystone v2.0 API - if not tenant_name and request.data.get("auth"): - tenant_name = request.data["auth"].get("tenantName") - tenant_id = request.data["auth"].get("tenantId") - - #keystone v3 API - if not tenant_name and request.data.get("auth") \ - and request.data["auth"].get("scope")\ - and request.data["auth"]["scope"].get("project"): - if request.data["auth"]["scope"]["project"].get("name"): - tenant_name = request.data["auth"]["scope"]["project"].get("name") - else: - tenant_id = request.data["auth"]["scope"]["project"].get("id") - - - - # prepare request resource to vim instance - vim = VimDriverUtils.get_vim_info(vimid) - sess = VimDriverUtils.get_session( - vim, tenant_name=tenant_name, tenant_id=tenant_id) - - tmp_auth_state = VimDriverUtils.get_auth_state(sess) - tmp_auth_info = json.loads(tmp_auth_state) - tmp_auth_token = tmp_auth_info['auth_token'] - tmp_auth_data = tmp_auth_info['body'] - - #store the auth_state, redis/memcached - #set expiring in 1 hour - - #update the catalog - tmp_auth_data['token']['catalog'], tmp_metadata_catalog = ProxyUtils.update_catalog( - vimid, tmp_auth_data['token']['catalog'], self.proxy_prefix) - - VimDriverUtils.update_token_cache( - tmp_auth_token, tmp_auth_state, - json.dumps(tmp_metadata_catalog)) - - tmp_auth_data['token']['catalog'] = ProxyUtils.update_catalog_dnsaas( - vimid,tmp_auth_data['token']['catalog'], self.proxy_prefix, vim) - - resp = Response(headers={'X-Subject-Token': tmp_auth_token}, - data=tmp_auth_data, status=status.HTTP_201_CREATED) - return resp - except VimDriverNewtonException as e: - - return Response(data={'error': e.content}, status=e.status_code) - except HttpError as e: - self._logger.error("HttpError: status:%s, response:%s" % (e.http_status, e.response.json())) - return Response(data=e.response.json(), status=e.http_status) - except Exception as e: - self._logger.error(traceback.format_exc()) - - return Response(data={'error': str(e)}, - status=status.HTTP_500_INTERNAL_SERVER_ERROR) - -v2_version_detail = { - "version": { - "status": "stable", - "updated": "2014-04-17T00:00:00Z", - "media-types": [ - { - "base": "application/json", - "type": "application/vnd.openstack.identity-v2.0+json" - } - ], - "id": "v2.0", - "links": [ - ] - } -} - -class TokensV2(Tokens): - ''' - Backward compatible API for /v2.0/tokens - ''' +class TokensV2(newton_identityV3.TokensV2): def __init__(self): - self.proxy_prefix = config.MULTICLOUD_PREFIX + self.proxy_prefix = settings.MULTICLOUD_PREFIX self._logger = logger - - def get(self, request, vimid=""): - self._logger.debug("TokensV2--get::META> %s" % request.META) - - return Response(data=v2_version_detail, status=status.HTTP_200_OK) - - def post(self, request, vimid=""): - self._logger.debug("TokensV2--post::META> %s" % request.META) - self._logger.debug("TokensV2--post::data> %s" % request.data) - self._logger.debug("TokensV2--post::vimid > %s" % (vimid)) - - try: - resp = super(TokensV2,self).post(request, vimid) - self._logger.debug("TokensV2--resp:: headers:%s, data:%s" % (resp._headers, resp.data)) - if resp.status_code == status.HTTP_201_CREATED: - v3_content = resp.data - v3_token = v3_content['token'] - - #convert catalog - v2_catalog = [] - for v3_catalog in v3_token['catalog']: - v2_catalog1 = { - "type": v3_catalog["type"], - "name": v3_catalog["name"], - "endpoints": [] - } - - #convert endpoints - v2_catalog1_endpoints = None - for v3_endpoint in v3_catalog['endpoints']: - v2_catalog1_endpoints = { - "id": v3_endpoint['id'], - "region":v3_endpoint['region'], - "region_id": v3_endpoint['region_id'], - 'interface':v3_endpoint['interface'] - } - if v3_endpoint['interface'] == 'public': - v2_catalog1_endpoints['publicURL'] = v3_endpoint['url'] - elif v3_endpoint['interface'] == 'admin': - v2_catalog1_endpoints['adminURL'] = v3_endpoint['url'] - elif v3_endpoint['interface'] == 'internal': - v2_catalog1_endpoints['internalURL'] = v3_endpoint['url'] - - if v2_catalog1_endpoints: - v2_catalog1['endpoints'].append(v2_catalog1_endpoints) - - v2_catalog.append(v2_catalog1) - - - #conversion between v3 tokens response and v2.0 tokens response - v3_token["project"]['enabled'] = 'true' - v2_content = { - "access": { - "token": { - "id" : resp.get('X-Subject-Token', None), - "issued_at": v3_token["issued_at"], - "expires" : v3_token["expires_at"], - "tenant" : v3_token["project"], - }, - "serviceCatalog": v2_catalog, - "user": v3_token["user"], - } - } - - return Response(data=v2_content, - status=status.HTTP_200_OK \ - if resp.status_code==status.HTTP_201_CREATED \ - else resp.status_code) - - else: - return resp - except VimDriverNewtonException as e: - - return Response(data={'error': e.content}, status=e.status_code) - except HttpError as e: - self._logger.error("HttpError: status:%s, response:%s" % (e.http_status, e.response.json())) - return Response(data=e.response.json(), status=e.http_status) - except Exception as e: - self._logger.error(traceback.format_exc()) - - return Response(data={'error': str(e)}, - status=status.HTTP_500_INTERNAL_SERVER_ERROR) diff --git a/newton/newton/proxy/views/proxy_utils.py b/newton/newton/proxy/views/proxy_utils.py deleted file mode 100644 index 9928c773..00000000 --- a/newton/newton/proxy/views/proxy_utils.py +++ /dev/null @@ -1,196 +0,0 @@ -# Copyright (c) 2017-2018 Wind River Systems, 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. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging -import json -import traceback -import re -import uuid - -from rest_framework import status - -from newton.pub.exceptions import VimDriverNewtonException - -logger = logging.getLogger(__name__) - -DEBUG=True -#MULTICLOUD_PREFIX = "http://%s:%s/api/multicloud-newton/v0" %(config.MSB_SERVICE_IP, config.MSB_SERVICE_PORT) - -class ProxyUtils(object): - - @staticmethod - def update_prefix(metadata_catalog, content): - '''match the longgest prefix and replace it''' - - if not content: - return content - - for (servicetype, service_metadata) in metadata_catalog.items(): - real_prefix = service_metadata['prefix'] - proxy_prefix = service_metadata['proxy_prefix'] - - if content: - # filter the resp content and replace all endpoint prefix - tmp_content = json.dumps(content) - tmp_pattern = re.compile(real_prefix+r'([^:])') - tmp_content = tmp_pattern.sub(proxy_prefix+r'\1', tmp_content) - content = json.loads(tmp_content) - - return content - - @staticmethod - def update_catalog(vimid, catalog, multicould_namespace): - ''' - replace the orignal endpoints with multicloud's - return the catalog with updated endpoints, and also another catalog with prefix and suffix of each endpoint - :param vimid: - :param catalog: service catalog to be updated - :param multicould_namespace: multicloud namespace prefix to replace the real one in catalog endpoints url - :return:updated catalog, and metadata_catalog looks like: - { - 'compute': { - 'prefix': 'http://ip:port', - 'proxy_prefix': 'http://another_ip: another_port', - 'suffix': 'v2.1/53a4ab9015c84ee892e46d294f3b8b2d', - }, - 'network': { - 'prefix': 'http://ip:port', - 'proxy_prefix': 'http://another_ip: another_port', - 'suffix': '', - }, - } - ''' - - metadata_catalog = {} - if catalog: - # filter and replace endpoints of catalogs - for item in catalog: - one_catalog = {} - metadata_catalog[item['type']] = one_catalog - - endpoints = item['endpoints'] - item['endpoints']=[] - for endpoint in endpoints: - interface = endpoint.get('interface', None) - if interface != 'public': - continue - # elif item["type"] == "identity": - # endpoint["url"] = multicould_namespace + "/%s/identity/v3" % vimid - else: - # replace the endpoint with MultiCloud's proxy - import re - endpoint_url = endpoint["url"] - real_prefix = None - real_suffix = None - m = re.search(r'^(http[s]?://[0-9.]+:[0-9]+)(/([0-9a-zA-Z/._-]+)$)?', endpoint_url) - if not m: - m = re.search(r'^(http[s]?://[0-9.]+)(/([0-9a-zA-Z/._-]+)$)?', endpoint_url) - if m: - real_prefix = m.group(1) - real_suffix = m.group(3) - - if real_prefix: - # populate metadata_catalog - one_catalog['prefix'] = real_prefix - one_catalog['suffix'] = real_suffix if real_suffix else '' - one_catalog['proxy_prefix'] = multicould_namespace + "/%s" % vimid - - endpoint_url = multicould_namespace + "/%s" % vimid - - tmp_pattern = re.compile(item["type"]) - if not real_suffix or not re.match(tmp_pattern, real_suffix): - one_catalog['proxy_prefix'] += "/" + item["type"] - endpoint_url += '/' + item["type"] - - if real_suffix: - endpoint_url += "/" + real_suffix - - if item["type"] == "identity": - endpoint_url = multicould_namespace + "/%s/identity/v3" % vimid - - else: - #something wrong - pass - - endpoint["url"] = endpoint_url - item['endpoints'].append( endpoint ) - - return catalog, metadata_catalog - else: - return None - - - @staticmethod - def update_catalog_dnsaas(vimid, catalog, multicould_namespace, viminfo): - ''' - append DNSaaS delegate endpoints to catalog - :param vimid: - :param catalog: service catalog to be updated - :param multicould_namespace: multicloud namespace prefix to replace the real one in catalog endpoints url - :param viminfo: vim information - :return:updated catalog - ''' - - try: - cloud_dns_delegate_info = None - cloud_extra_info_str = viminfo.get('cloud_extra_info') - if cloud_extra_info_str: - cloud_extra_info = json.loads(cloud_extra_info_str) - cloud_dns_delegate_info = cloud_extra_info.get("dns-delegate") - - if not cloud_dns_delegate_info\ - or not cloud_dns_delegate_info.get("cloud-owner") \ - or not cloud_dns_delegate_info.get("cloud-region-id"): - #DNSaaS deleget was not configured yet - return catalog - - dns_catalog = { - "name":"dns-delegate", - "type":"dns", - "id": str(uuid.uuid1()), - "endpoints": [{ - "interface": "public", - "region": cloud_dns_delegate_info.get("cloud-region-id"), - "region_id": cloud_dns_delegate_info.get("cloud-region-id"), - "id": str(uuid.uuid1()), - "url": multicould_namespace + "/%s/dns-delegate" % vimid, - }] - } - catalog.append(dns_catalog) - - return catalog - - except Exception as e: - logger.error(traceback.format_exc()) - return catalog - - -# @staticmethod -# def update_dnsaas_project_id(content, new_project_id): -# ''' -# update project id in DNSaaS delegate content -# ''' -# try: -# if content: -# # filter the resp content and replace all endpoint prefix -# tmp_content = json.dumps(content) -# tmp_pattern = re.compile(r'(^.*)"project_id"\s*:\s*"' + r'[\w-]+'+r'"(.*$)') -# part1 = tmp_pattern.sub(r'\1', tmp_content) -# part2 = tmp_pattern.sub(r'"project_id":"'+new_project_id +r'"\2', tmp_content) -# #logger.debug("jsonstr:%s,part1:%s,part2:%s"%(tmp_content,part1,part2)) -# content = json.loads(part1+part2) -# return content -# except Exception as e: -# logger.error(traceback.format_exc()) -# return content diff --git a/newton/newton/proxy/views/services.py b/newton/newton/proxy/views/services.py index 38354bbb..4bfecdbc 100644 --- a/newton/newton/proxy/views/services.py +++ b/newton/newton/proxy/views/services.py @@ -13,228 +13,23 @@ # limitations under the License. import logging -import json -import traceback -from keystoneauth1.exceptions import HttpError -import re -from rest_framework.permissions import BasePermission -from rest_framework.response import Response from rest_framework import status -from rest_framework.views import APIView -from newton.proxy.views.proxy_utils import ProxyUtils -from newton.pub.exceptions import VimDriverNewtonException -from newton.pub.msapi import extsys -from newton.requests.views.util import VimDriverUtils +from django.conf import settings +from newton_base.proxy import services as newton_services logger = logging.getLogger(__name__) DEBUG=True - -class HasValidToken(BasePermission): - - def has_permission(self, request, view): - logger.debug("HasValidToken--has_permission::META> %s" % request.META) - token = request.META.get('HTTP_X_AUTH_TOKEN', None) - if token: - state, metadata = VimDriverUtils.get_token_cache(token) - if state: - return True - return False - - -class Services(APIView): - permission_classes = (HasValidToken,) +class Services(newton_services.Services): def __init__(self): self._logger = logger - def _get_token(self, request): - return request.META.get('HTTP_X_AUTH_TOKEN', None) - - def _get_resource_and_metadata(self, servicetype, metadata_catalog, requri): - real_prefix = None - proxy_prefix = None - suffix = None - if servicetype and metadata_catalog: - metadata_catalog = json.loads(metadata_catalog) - service_metadata = metadata_catalog.get(servicetype, None) - if service_metadata: - real_prefix = service_metadata['prefix'] - proxy_prefix = service_metadata['proxy_prefix'] - suffix = service_metadata['suffix'] - - if not real_prefix or not proxy_prefix: - raise VimDriverNewtonException(message="internal state error", - content="invalid cached metadata", - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR) - - if requri == suffix: - requri = None - - if suffix and requri: - # remove the suffix from the requri to avoid duplicated suffix in real request uri later - tmp_pattern = re.compile(suffix) - requri = tmp_pattern.sub('', requri) - - req_resource = '' - if requri and requri != '': - req_resource = "/" if re.match(r'//', requri) else '' + requri - return req_resource, metadata_catalog - - def _do_action(self, action, request, vim_id, servicetype, requri): - tmp_auth_token = self._get_token(request) - try: - #special handling of compute/v2 request from APPC, temp solution for A release - if servicetype == 'compute': - tmp_pattern = re.compile(r'^v2/(.+)') - requri = tmp_pattern.sub(r'v2.1/' + r'\1', requri) - - - vim = VimDriverUtils.get_vim_info(vim_id) - # fetch the auth_state out of cache - auth_state, metadata_catalog = VimDriverUtils.get_token_cache(tmp_auth_token) - req_resource, metadata_catalog = self._get_resource_and_metadata(servicetype, metadata_catalog, requri) - sess = VimDriverUtils.get_session(vim, auth_state=auth_state) - - cloud_owner, regionid = extsys.decode_vim_id(vim_id) - interface = 'public' - service = { - 'service_type': servicetype, - 'interface': interface, - 'region_id': regionid - } - - querystr = VimDriverUtils.get_query_part(request) - if querystr: - req_resource += "?" + querystr - - self._logger.debug("service " + action + " request uri %s" % (req_resource)) - if(action == "get"): - resp = sess.get(req_resource, endpoint_filter=service, - headers={"Content-Type": "application/json", - "Accept": "application/json"}) - elif(action == "post"): - resp = sess.post(req_resource, data=json.JSONEncoder().encode(request.data), - endpoint_filter=service, - headers={"Content-Type": "application/json", - "Accept": "application/json"}) - elif(action == "put"): - resp = sess.put(req_resource, data=json.JSONEncoder().encode(request.data), - endpoint_filter=service, - headers={"Content-Type": "application/json", - "Accept": "application/json"}) - elif(action == "patch"): - resp = sess.patch(req_resource, data=json.JSONEncoder().encode(request.data), - endpoint_filter=service, - headers={"Content-Type": "application/json", - "Accept": "application/json"}) - elif (action == "delete"): - resp = sess.delete(req_resource, endpoint_filter=service, - headers={"Content-Type": "application/json", - "Accept": "application/json"}) - content = resp.json() if resp.content else None - self._logger.debug("service " + action + " response: %s, %s" % (resp.status_code, content)) - - if (action == "delete"): - return Response(headers={'X-Subject-Token': tmp_auth_token}, status=resp.status_code) - else: - content = ProxyUtils.update_prefix(metadata_catalog, content) - if (action == "get"): - if requri == '/v3/auth/catalog' and content and content.get("catalog"): - content['catalog'] = ProxyUtils.update_catalog_dnsaas( - vim_id, content['catalog'], self.proxy_prefix, vim) - return Response(headers={'X-Subject-Token': tmp_auth_token}, data=content, status=resp.status_code) - - except VimDriverNewtonException as e: - return Response(data={'error': e.content}, status=e.status_code) - except HttpError as e: - self._logger.error("HttpError: status:%s, response:%s" % (e.http_status, e.response.json())) - return Response(data=e.response.json(), status=e.http_status) - except Exception as e: - self._logger.error(traceback.format_exc()) - return Response(data={'error': str(e)}, - status=status.HTTP_500_INTERNAL_SERVER_ERROR) - - def head(self, request, vimid="", servicetype="", requri=""): - #self._logger.debug("Services--head::META> %s" % request.META) - self._logger.debug("Services--head::data> %s" % request.data) - self._logger.debug("Services--head::vimid, servicetype, requri> %s,%s,%s" - % (vimid, servicetype, requri)) - - token = self._get_token(request) - try: - vim = VimDriverUtils.get_vim_info(vimid) - auth_state, metadata_catalog = VimDriverUtils.get_token_cache(token) - sess = VimDriverUtils.get_session(vim, auth_state=auth_state) - - req_resource = '' - if requri and requri != '': - req_resource = "/" if re.match(r'//', requri) else ''+ requri - - cloud_owner, regionid = extsys.decode_vim_id(vimid) - interface = 'public' - service = {'service_type': servicetype, - 'interface': interface, - 'region_id': regionid} - self._logger.debug("service head request uri %s" % (req_resource)) - - resp = sess.head(req_resource, endpoint_filter=service) - content = resp.json() if resp.content else None - self._logger.debug("service head response: %s, %s" % (resp.status_code, content)) - - return Response(headers={'X-Subject-Token': token}, data=content, status=resp.status_code) - except VimDriverNewtonException as e: - return Response(data={'error': e.content}, status=e.status_code) - except HttpError as e: - self._logger.error("HttpError: status:%s, response:%s" % (e.http_status, e.response.json())) - return Response(data=e.response.json(), status=e.http_status) - except Exception as e: - self._logger.error(traceback.format_exc()) - return Response(data={'error': str(e)}, - status=status.HTTP_500_INTERNAL_SERVER_ERROR) - - def get(self, request, vimid="", servicetype="", requri=""): - #self._logger.debug("Services--get::META> %s" % request.META) - self._logger.debug("Services--get::data> %s" % request.data) - self._logger.debug("Services--get::vimid, servicetype, requri> %s,%s,%s" - % (vimid, servicetype, requri)) - return self._do_action("get", request, vimid, servicetype, requri) - - def post(self, request, vimid="", servicetype="", requri=""): - #self._logger.debug("Services--post::META> %s" % request.META) - self._logger.debug("Services--post::data> %s" % request.data) - self._logger.debug("Services--post::vimid, servicetype, requri> %s,%s,%s" - % (vimid, servicetype, requri)) - - return self._do_action("post", request, vimid, servicetype, requri) - - def put(self, request, vimid="", servicetype="", requri=""): - #self._logger.debug("Services--put::META> %s" % request.META) - self._logger.debug("Services--put::data> %s" % request.data) - self._logger.debug("Services--put::vimid, servicetype, requri> %s,%s,%s" - % (vimid, servicetype, requri)) - return self._do_action("put", request, vimid, servicetype, requri) - - def patch(self, request, vimid="", servicetype="", requri=""): - #self._logger.debug("Services--patch::META> %s" % request.META) - self._logger.debug("Services--patch::data> %s" % request.data) - self._logger.debug("Services--patch::vimid, servicetype, requri> %s,%s,%s" - % (vimid, servicetype, requri)) - return self._do_action("patch", request, vimid, servicetype, requri) - - def delete(self, request, vimid="", servicetype="", requri=""): - #self._logger.debug("Services--delete::META> %s" % request.META) - self._logger.debug("Services--delete::data> %s" % request.data) - self._logger.debug("Services--delete::vimid, servicetype, requri> %s,%s,%s" - % (vimid, servicetype, requri)) - return self._do_action("delete", request, vimid, servicetype, requri) - - -class GetTenants(Services): +class GetTenants(newton_services.GetTenants): ''' Backward compatible API for /v2.0/tenants ''' @@ -242,33 +37,10 @@ class GetTenants(Services): def __init__(self): self._logger = logger - def get(self, request, vimid="", servicetype="identity", requri='projects'): - #self._logger.debug("GetTenants--get::META> %s" % request.META) + def get(self, request, vimid="", servicetype="identity", requri='v3/projects'): + self._logger.debug("GetTenants--get::META> %s" % request.META) self._logger.debug("GetTenants--get::data> %s" % request.data) self._logger.debug("GetTenants--get::vimid, servicetype, requri> %s,%s,%s" % (vimid, servicetype, requri)) - tmp_auth_token = request.META.get('HTTP_X_AUTH_TOKEN', None) - - resp = super(GetTenants,self).get(request, vimid, servicetype, requri) - if resp.status_code == status.HTTP_200_OK: - content = resp.data - return Response(headers={'X-Subject-Token': tmp_auth_token}, data={'tenants': content['projects'],'tenants_links':[]}, - status=resp.status_code) - else: - return resp - - def head(self, request, vimid="", servicetype="", requri=""): - return Response(data={'error': 'unsupported operation'}, status=status.HTTP_400_BAD_REQUEST) - - def post(self, request, vimid="", servicetype="", requri=""): - return Response(data={'error': 'unsupported operation'}, status=status.HTTP_400_BAD_REQUEST) - - def put(self, request, vimid="", servicetype="", requri=""): - return Response(data={'error': 'unsupported operation'}, status=status.HTTP_400_BAD_REQUEST) - - def patch(self, request, vimid="", servicetype="", requri=""): - return Response(data={'error': 'unsupported operation'}, status=status.HTTP_400_BAD_REQUEST) - - def delete(self, request, vimid="", servicetype="", requri=""): - return Response(data={'error': 'unsupported operation'}, status=status.HTTP_400_BAD_REQUEST) + return super(GetTenants,self).get(request, vimid, servicetype, requri) |