summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuang Haibin <haibin.huang@intel.com>2018-01-17 06:06:27 +0800
committerHuang Haibin <haibin.huang@intel.com>2018-01-18 01:01:15 +0800
commit9e7c5a6bfd338dd5352d9d6afdae0cea23856acf (patch)
treebffbbdc32f615bb2e8c44441572a942c75ce66b1
parent79c711a95de34531e62927ea19fe16753513063b (diff)
Add newton base directory
newton base directory is mainly placed openstack public files, we will move mainly from the original newton folder.this patch create newton base framework and move one file to here. Issue-ID: MULTICLOUD-138 Change-Id: Ie901795a5cf3383217c3585eb6602a4baba6dcd8 Signed-off-by: Huang Haibin <haibin.huang@intel.com>
-rw-r--r--ocata/assembly.xml14
-rw-r--r--ocata/ocata/proxy/views/services.py4
-rw-r--r--ocata/ocata/settings.py5
-rw-r--r--ocata/run.sh4
-rw-r--r--ocata/tox.ini2
-rw-r--r--share/newton_base/__init__.py10
-rw-r--r--share/newton_base/proxy/__init__.py10
-rw-r--r--share/newton_base/proxy/services.py273
8 files changed, 315 insertions, 7 deletions
diff --git a/ocata/assembly.xml b/ocata/assembly.xml
index 7ae321af..e60dd7fd 100644
--- a/ocata/assembly.xml
+++ b/ocata/assembly.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (c) 2017 Wind River Systems, Inc.
+ 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.
@@ -31,6 +31,18 @@
</includes>
</fileSet>
<fileSet>
+ <directory>../share</directory>
+ <outputDirectory>/lib/share</outputDirectory>
+ <includes>
+ <include>**/*.py</include>
+ <include>**/*.json</include>
+ <include>**/*.xml</include>
+ <include>**/*.wsdl</include>
+ <include>**/*.xsd</include>
+ <include>**/*.bpel</include>
+ </includes>
+ </fileSet>
+ <fileSet>
<directory>logs</directory>
<outputDirectory>/logs</outputDirectory>
<includes>
diff --git a/ocata/ocata/proxy/views/services.py b/ocata/ocata/proxy/views/services.py
index 7eb6bd25..d65da20a 100644
--- a/ocata/ocata/proxy/views/services.py
+++ b/ocata/ocata/proxy/views/services.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2017 Wind River Systems, Inc.
+# 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.
@@ -16,7 +16,7 @@ import logging
from rest_framework import status
from ocata.pub.config import config
-from newton.proxy.views import services as newton_services
+from newton_base.proxy import services as newton_services
logger = logging.getLogger(__name__)
diff --git a/ocata/ocata/settings.py b/ocata/ocata/settings.py
index 3cc4caa9..6021aa78 100644
--- a/ocata/ocata/settings.py
+++ b/ocata/ocata/settings.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2017 Wind River Systems, Inc.
+# 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.
@@ -114,6 +114,9 @@ CACHES = {
}
}
+OPENSTACK_VERSION = "ocata"
+MULTIVIM_VERSION = "multicloud-" + OPENSTACK_VERSION
+
if 'test' in sys.argv:
from ocata.pub.config import config
diff --git a/ocata/run.sh b/ocata/run.sh
index cfb52b74..680290a2 100644
--- a/ocata/run.sh
+++ b/ocata/run.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright (c) 2017 Wind River Systems, Inc.
+# 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.
@@ -29,7 +29,7 @@ sed -i "s/AAI_USERNAME =.*/AAI_USERNAME = \"${AAI_USERNAME}\"/g" lib/newton/newt
sed -i "s/AAI_PASSWORD =.*/AAI_PASSWORD = \"${AAI_PASSWORD}\"/g" lib/newton/newton/pub/config/config.py
memcached -d -m 2048 -u root -c 1024 -p 11211 -P /tmp/memcached1.pid
-export PYTHONPATH=lib/newton
+export PYTHONPATH=lib/newton:lib/share
nohup python manage.py runserver 0.0.0.0:9006 2>&1 &
while [ ! -f logs/runtime_ocata.log ]; do
diff --git a/ocata/tox.ini b/ocata/tox.ini
index dcd7033e..391f3b71 100644
--- a/ocata/tox.ini
+++ b/ocata/tox.ini
@@ -7,7 +7,7 @@ downloadcache = ~/cache/pip
[testenv]
setenv =
- PYTHONPATH = {toxinidir}/../newton
+ PYTHONPATH = {toxinidir}/../newton:{toxinidir}/../share
deps = -r{toxinidir}/requirements.txt
commands =
coverage run --branch manage.py test
diff --git a/share/newton_base/__init__.py b/share/newton_base/__init__.py
new file mode 100644
index 00000000..387c54c2
--- /dev/null
+++ b/share/newton_base/__init__.py
@@ -0,0 +1,10 @@
+# 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.
diff --git a/share/newton_base/proxy/__init__.py b/share/newton_base/proxy/__init__.py
new file mode 100644
index 00000000..387c54c2
--- /dev/null
+++ b/share/newton_base/proxy/__init__.py
@@ -0,0 +1,10 @@
+# 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.
diff --git a/share/newton_base/proxy/services.py b/share/newton_base/proxy/services.py
new file mode 100644
index 00000000..3c543bf9
--- /dev/null
+++ b/share/newton_base/proxy/services.py
@@ -0,0 +1,273 @@
+# Copyright (c) 2017-2018 Wind River System 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.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 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,)
+
+ 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("hhb 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):
+ '''
+ Backward compatible API for /v2.0/tenants
+ '''
+
+ def __init__(self):
+ self._logger = logger
+
+ def get(self, request, vimid="", servicetype="identity", requri='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)