From d4d563eea97f94742800531fe702597c3545b9c4 Mon Sep 17 00:00:00 2001 From: Victor Morales Date: Mon, 18 Sep 2017 09:55:52 -0700 Subject: Refactor Service UTs The Unit tests that covers the get function of Service resource was generic, this change pretends to translate it to use cases. Change-Id: Iaec6d0751b5501612aebb240423da750bd56abff Signed-off-by: Victor Morales Issue-Id: MULTICLOUD-83 --- .gitignore | 3 +- newton/newton/proxy/tests/test_service_proxy.py | 177 ++++----- newton/newton/proxy/views/services.py | 475 ++++++------------------ newton/newton/requests/tests/test_reqeust.py | 20 - newton/newton/requests/tests/test_request.py | 20 + newton/newton/requests/views/util.py | 6 +- newton/newton/settings.py | 7 + 7 files changed, 227 insertions(+), 481 deletions(-) delete mode 100644 newton/newton/requests/tests/test_reqeust.py create mode 100644 newton/newton/requests/tests/test_request.py diff --git a/.gitignore b/.gitignore index e86d02b0..7d298bc4 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ logs/*.log .tox .coverage htmlcov/ - +.idea/ +mydatabase diff --git a/newton/newton/proxy/tests/test_service_proxy.py b/newton/newton/proxy/tests/test_service_proxy.py index 2dd558d5..adac3002 100644 --- a/newton/newton/proxy/tests/test_service_proxy.py +++ b/newton/newton/proxy/tests/test_service_proxy.py @@ -11,19 +11,17 @@ # 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 json -import mock -import unittest +import copy +import json from django.test import Client +import mock from rest_framework import status +import unittest -from keystoneauth1 import session -from keystoneauth1.exceptions import HttpError from newton.requests.views.util import VimDriverUtils -from newton.proxy.views.services import Services, GetTenants MOCK_VIM_INFO = { "createTime": "2017-04-01 02:22:27", @@ -696,7 +694,7 @@ MOCK_PATCH_IMAGE_RESPONSE = { } -class mock_get_servers_response_specs(object): +class MockResponse(object): status_code = 200 content = '' @@ -707,68 +705,75 @@ class mock_get_servers_response_specs(object): class TestServiceProxy(unittest.TestCase): def setUp(self): self.client = Client() - pass - def tearDown(self): - pass - - - @mock.patch.object(VimDriverUtils, 'get_vim_info') @mock.patch.object(VimDriverUtils, 'get_session') - @mock.patch.object(VimDriverUtils, 'get_auth_state') - @mock.patch.object(VimDriverUtils, 'update_token_cache') @mock.patch.object(VimDriverUtils, 'get_token_cache') - def test_get(self, mock_get_token_cache, mock_update_token_cache, mock_get_auth_state, mock_get_session, mock_get_vim_info): - ''' - Test service proxy API: GET - - :param mock_get_token_cache: - :param mock_update_token_cache: - :param mock_get_auth_state: - :param mock_get_session: - :param mock_get_vim_info: - :return: - ''' - - #mock VimDriverUtils APIs - mock_session_specs = ["get"] - + @mock.patch.object(VimDriverUtils, 'get_vim_info') + def test_get_token(self, mock_get_vim_info, mock_get_token_cache, mock_get_session): + mock_session_specs = ["head"] mock_session = mock.Mock(name='mock_session', spec=mock_session_specs) - mock_get_servers_response_obj = mock.Mock(spec=mock_get_servers_response_specs) + mock_get_servers_response_obj = mock.Mock(spec=MockResponse) mock_get_servers_response_obj.status_code=200 mock_get_servers_response_obj.content = MOCK_GET_SERVERS_RESPONSE mock_get_servers_response_obj.json.return_value=MOCK_GET_SERVERS_RESPONSE - mock_session.get.return_value = mock_get_servers_response_obj + mock_session.head.return_value = mock_get_servers_response_obj mock_get_vim_info.return_value = MOCK_VIM_INFO mock_get_session.return_value = mock_session - mock_get_auth_state.return_value = json.dumps(MOCK_AUTH_STATE) - mock_update_token_cache.return_value = MOCK_TOKEN_ID mock_get_token_cache.return_value = (json.dumps(MOCK_AUTH_STATE),json.dumps(MOCK_INTERNAL_METADATA_CATALOG)) + response = self.client.head( + "/api/multicloud-newton/v0/windriver-hudson-dc_RegionOne/compute/v2.1/fcca3cc49d5e42caae15459e27103efc/servers", + {}, HTTP_X_AUTH_TOKEN=MOCK_TOKEN_ID) + self.assertEquals(status.HTTP_200_OK, response.status_code) - #simulate client to make the request + def test_unauthorized_access(self): response = self.client.get( - "/api/multicloud-newton/v0/windriver-hudson-dc_RegionOne/compute/v2.1/fcca3cc49d5e42caae15459e27103efc/servers", - {}, HTTP_X_AUTH_TOKEN=MOCK_TOKEN_ID) + "/api/multicloud-newton/v0/windriver-hudson-dc_RegionOne/compute/v2.1/fcca3cc49d5e42caae15459e27103efc/servers") + self.assertEquals(status.HTTP_403_FORBIDDEN, response.status_code) - self.failUnlessEqual(status.HTTP_200_OK, response.status_code) - context = response.json() + @mock.patch.object(VimDriverUtils, 'get_vim_info') + def test_expired_auth_token(self, mock_get_vim_info): + mock_get_vim_info.return_value = MOCK_VIM_INFO + + response = self.client.get( + "/api/multicloud-newton/v0/windriver-hudson-dc_RegionOne/compute/v2.1/fcca3cc49d5e42caae15459e27103efc/servers", + {}, HTTP_X_AUTH_TOKEN=MOCK_TOKEN_ID) + self.assertEquals(status.HTTP_403_FORBIDDEN, response.status_code) + + @mock.patch.object(VimDriverUtils, 'get_token_cache') + @mock.patch.object(VimDriverUtils, 'get_vim_info') + def test_request_without_servicetype(self, mock_get_vim_info, mock_get_token_cache): + mock_get_vim_info.return_value = MOCK_VIM_INFO + mock_get_token_cache.return_value = (json.dumps(MOCK_AUTH_STATE), {}) + servicetype = "compute" + url = ("/api/multicloud-newton/v0/windriver-hudson-dc_RegionOne/" + servicetype + + "/v2.1/fcca3cc49d5e42caae15459e27103efc/servers") + response = self.client.get(url, {}, HTTP_X_AUTH_TOKEN=MOCK_TOKEN_ID) + self.assertEquals(status.HTTP_500_INTERNAL_SERVER_ERROR, response.status_code) - self.assertTrue(response['X-Subject-Token'] == MOCK_TOKEN_ID) - self.assertTrue(context['servers'] != None) + metadata_catalog = copy.deepcopy(MOCK_INTERNAL_METADATA_CATALOG) + metadata_catalog[servicetype] = None + mock_get_token_cache.return_value = (json.dumps(MOCK_AUTH_STATE), json.dumps(metadata_catalog)) - pass + response = self.client.get(url, {}, HTTP_X_AUTH_TOKEN=MOCK_TOKEN_ID) + self.assertEquals(status.HTTP_500_INTERNAL_SERVER_ERROR, response.status_code) + metadata_catalog = copy.deepcopy(MOCK_INTERNAL_METADATA_CATALOG) + metadata_catalog[servicetype]['prefix'] = None + metadata_catalog[servicetype]['proxy_prefix'] = None + mock_get_token_cache.return_value = (json.dumps(MOCK_AUTH_STATE), json.dumps(metadata_catalog)) + response = self.client.get(url, {}, HTTP_X_AUTH_TOKEN=MOCK_TOKEN_ID) + self.assertEquals(status.HTTP_500_INTERNAL_SERVER_ERROR, response.status_code) @mock.patch.object(VimDriverUtils, 'get_vim_info') @mock.patch.object(VimDriverUtils, 'get_session') @mock.patch.object(VimDriverUtils, 'get_auth_state') @mock.patch.object(VimDriverUtils, 'update_token_cache') @mock.patch.object(VimDriverUtils, 'get_token_cache') - def test_post(self, mock_get_token_cache, mock_update_token_cache, mock_get_auth_state, mock_get_session, mock_get_vim_info): + def test_crud_resources(self, mock_get_token_cache, mock_update_token_cache, mock_get_auth_state, mock_get_session, mock_get_vim_info): ''' - Test service proxy API: POST + Test service proxy API: GET :param mock_get_token_cache: :param mock_update_token_cache: @@ -779,14 +784,31 @@ class TestServiceProxy(unittest.TestCase): ''' #mock VimDriverUtils APIs - mock_session_specs = ["post"] + mock_session_specs = ["get", "post", "put", "patch", "delete"] - mock_session = mock.Mock(name='mock_session', spec=mock_session_specs) - mock_post_server_response_obj = mock.Mock(spec=mock_get_servers_response_specs) + mock_get_servers_response_obj = mock.Mock(spec=MockResponse) + mock_get_servers_response_obj.status_code=200 + mock_get_servers_response_obj.content = MOCK_GET_SERVERS_RESPONSE + mock_get_servers_response_obj.json.return_value=MOCK_GET_SERVERS_RESPONSE + + mock_post_server_response_obj = mock.Mock(spec=MockResponse) mock_post_server_response_obj.status_code=202 mock_post_server_response_obj.content = MOCK_POST_SERVER_RESPONSE mock_post_server_response_obj.json.return_value=MOCK_POST_SERVER_RESPONSE + + mock_patch_server_response_obj = mock.Mock(spec=MockResponse) + mock_patch_server_response_obj.status_code=202 + mock_patch_server_response_obj.content = MOCK_PATCH_IMAGE_REQUEST + mock_patch_server_response_obj.json.return_value=MOCK_PATCH_IMAGE_REQUEST + + mock_delete_server_response_obj = mock.Mock(spec=MockResponse) + mock_delete_server_response_obj.status_code=204 + + mock_session = mock.Mock(name='mock_session', spec=mock_session_specs) + mock_session.get.return_value = mock_get_servers_response_obj mock_session.post.return_value = mock_post_server_response_obj + mock_session.patch.return_value = mock_patch_server_response_obj + mock_session.delete.return_value = mock_delete_server_response_obj mock_get_vim_info.return_value = MOCK_VIM_INFO mock_get_session.return_value = mock_session @@ -794,57 +816,40 @@ class TestServiceProxy(unittest.TestCase): mock_update_token_cache.return_value = MOCK_TOKEN_ID mock_get_token_cache.return_value = (json.dumps(MOCK_AUTH_STATE),json.dumps(MOCK_INTERNAL_METADATA_CATALOG)) - #simulate client to make the request + # Create resource response = self.client.post( "/api/multicloud-newton/v0/windriver-hudson-dc_RegionOne/compute/v2.1/fcca3cc49d5e42caae15459e27103efc/servers", MOCK_POST_SERVER_REQUEST, HTTP_X_AUTH_TOKEN=MOCK_TOKEN_ID) - self.failUnlessEqual(status.HTTP_202_ACCEPTED, response.status_code) + self.assertEquals(status.HTTP_202_ACCEPTED, response.status_code) context = response.json() + self.assertEquals(MOCK_TOKEN_ID, response['X-Subject-Token']) + self.assertIsNotNone(context['server']) - self.assertTrue(response['X-Subject-Token'] == MOCK_TOKEN_ID) - self.assertTrue(context['server'] != None) - - pass - - - @mock.patch.object(VimDriverUtils, 'get_vim_info') - @mock.patch.object(VimDriverUtils, 'get_session') - @mock.patch.object(VimDriverUtils, 'get_auth_state') - @mock.patch.object(VimDriverUtils, 'update_token_cache') - @mock.patch.object(VimDriverUtils, 'get_token_cache') - def test_delete(self, mock_get_token_cache, mock_update_token_cache, mock_get_auth_state, mock_get_session, mock_get_vim_info): - ''' - Test service proxy API: DELETE - - :param mock_get_token_cache: - :param mock_update_token_cache: - :param mock_get_auth_state: - :param mock_get_session: - :param mock_get_vim_info: - :return: - ''' + # Retrieve resource + response = self.client.get( + "/api/multicloud-newton/v0/windriver-hudson-dc_RegionOne/compute/v2.1/fcca3cc49d5e42caae15459e27103efc/servers", + {}, HTTP_X_AUTH_TOKEN=MOCK_TOKEN_ID) + self.assertEquals(status.HTTP_200_OK, response.status_code) + context = response.json() - #mock VimDriverUtils APIs - mock_session_specs = ["delete"] + self.assertEquals(MOCK_TOKEN_ID, response['X-Subject-Token']) + self.assertIsNotNone(context['servers']) - mock_session = mock.Mock(name='mock_session', spec=mock_session_specs) - mock_post_server_response_obj = mock.Mock(spec=mock_get_servers_response_specs) - mock_post_server_response_obj.status_code=204 - mock_session.delete.return_value = mock_post_server_response_obj + # Update resource + response = self.client.get( + "/api/multicloud-newton/v0/windriver-hudson-dc_RegionOne/compute/v2.1/fcca3cc49d5e42caae15459e27103efc/servers", + {}, HTTP_X_AUTH_TOKEN=MOCK_TOKEN_ID) + self.assertEquals(status.HTTP_200_OK, response.status_code) + context = response.json() - mock_get_vim_info.return_value = MOCK_VIM_INFO - mock_get_session.return_value = mock_session - mock_get_auth_state.return_value = json.dumps(MOCK_AUTH_STATE) - mock_update_token_cache.return_value = MOCK_TOKEN_ID - mock_get_token_cache.return_value = (json.dumps(MOCK_AUTH_STATE),json.dumps(MOCK_INTERNAL_METADATA_CATALOG)) + self.assertEquals(MOCK_TOKEN_ID, response['X-Subject-Token']) + self.assertIsNotNone(context['servers']) #simulate client to make the request response = self.client.delete( "/api/multicloud-newton/v0/windriver-hudson-dc_RegionOne/compute/v2.1/fcca3cc49d5e42caae15459e27103efc/servers/324dfb7d-f4a9-419a-9a19-237df04b443b", HTTP_X_AUTH_TOKEN=MOCK_TOKEN_ID) - self.failUnlessEqual(status.HTTP_204_NO_CONTENT, response.status_code) - self.assertTrue(response['X-Subject-Token'] == MOCK_TOKEN_ID) - - pass + self.assertEquals(status.HTTP_204_NO_CONTENT, response.status_code) + self.assertEquals(MOCK_TOKEN_ID, response['X-Subject-Token']) diff --git a/newton/newton/proxy/views/services.py b/newton/newton/proxy/views/services.py index 6e166f95..b6e1be0c 100644 --- a/newton/newton/proxy/views/services.py +++ b/newton/newton/proxy/views/services.py @@ -15,51 +15,130 @@ import logging import json import traceback -import re -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 +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.requests.views.util import VimDriverUtils from newton.pub.msapi import extsys -from newton.proxy.views.proxy_utils import ProxyUtils +from newton.requests.views.util import VimDriverUtils logger = logging.getLogger(__name__) DEBUG=True + +class HasValidToken(BasePermission): + + def has_permission(self, request, view): + 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: + 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, tenantid=None, auth_state=auth_state) + + cloud_owner, regionid = extsys.decode_vim_id(vim_id) + interface = 'public' + service = { + 'service_type': servicetype, + 'interface': interface, + 'region_id': regionid + } + + self._logger.debug("service " + action + " request uri %s" % (req_resource)) + if(action == "get"): + resp = sess.get(req_resource, endpoint_filter=service) + elif(action == "post"): + resp = sess.post(req_resource, data=json.JSONEncoder().encode(request.data), endpoint_filter=service) + elif(action == "put"): + resp = sess.put(req_resource, data=json.JSONEncoder().encode(request.data), endpoint_filter=service) + elif(action == "patch"): + resp = sess.patch(req_resource, data=json.JSONEncoder().encode(request.data), endpoint_filter=service) + elif (action == "delete"): + resp = sess.delete(req_resource, endpoint_filter=service) + content = resp.json() if resp.content else None + self._logger.debug("service " + action + " response: %s, %s" % (resp.status_code, content)) + + if (action != "delete"): + content = ProxyUtils.update_prefix(metadata_catalog, content) + return Response(headers={'X-Subject-Token': tmp_auth_token}, data=content, status=resp.status_code) + return Response(headers={'X-Subject-Token': tmp_auth_token}, 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: - # prepare request resource to vim instance - #get token: - tmp_auth_token = request.META.get('HTTP_X_AUTH_TOKEN', None) - if not tmp_auth_token: - return Response(data={'error': "No X-Auth-Token found in headers"}, status=status.HTTP_401_UNAUTHORIZED) - vim = VimDriverUtils.get_vim_info(vimid) - #fetch the auth_state out of cache - tmp_auth_state, metadata_catalog = VimDriverUtils.get_token_cache(vim,tmp_auth_token) - if not tmp_auth_state: - return Response(data={'error': "Expired X-Auth-Token found in headers"}, status=status.HTTP_401_UNAUTHORIZED) - + auth_state, metadata_catalog = VimDriverUtils.get_token_cache(token) + sess = VimDriverUtils.get_session(vim, auth_state=auth_state) - sess = VimDriverUtils.get_session(vim, tenantid=None, auth_state=tmp_auth_state) req_resource = '' if requri and requri != '': req_resource = "/" if re.match(r'//', requri) else ''+ requri @@ -73,13 +152,10 @@ class Services(APIView): self._logger.debug("service head request uri %s" % (req_resource)) resp = sess.head(req_resource, endpoint_filter=service) - #update token cache in case the token was required during the requests - #tmp_auth_token = VimDriverUtils.update_token_cache(vim, sess, tmp_auth_token, tmp_auth_state) 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': tmp_auth_token}, data=content, status=resp.status_code) - #return resp + 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: @@ -95,377 +171,36 @@ class Services(APIView): self._logger.debug("Services--get::data> %s" % request.data) self._logger.debug("Services--get::vimid, servicetype, requri> %s,%s,%s" % (vimid, servicetype, requri)) - try: - # prepare request resource to vim instance - #get token: - tmp_auth_token = request.META.get('HTTP_X_AUTH_TOKEN', None) - if not tmp_auth_token: - return Response(data={'error': "No X-Auth-Token found in headers"}, status=status.HTTP_401_UNAUTHORIZED) - - vim = VimDriverUtils.get_vim_info(vimid) - # fetch the auth_state out of cache - tmp_auth_state, metadata_catalog = VimDriverUtils.get_token_cache(vim, tmp_auth_token) - if not tmp_auth_state: - return Response(data={'error': "Expired X-Auth-Token found in headers"}, status=status.HTTP_401_UNAUTHORIZED) - - real_prefix = None - proxy_prefix = None - suffix = None - if servicetype and metadata_catalog: -# self._logger.error("metadata_catalog:%s" % 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) - - sess = VimDriverUtils.get_session(vim, tenantid=None, auth_state=tmp_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 get request uri %s" % (req_resource)) - - resp = sess.get(req_resource, endpoint_filter=service) - #update token cache in case the token was required during the requests - #tmp_auth_token = VimDriverUtils.update_token_cache(vim, sess, tmp_auth_token, tmp_auth_state) - content = resp.json() if resp.content else None - self._logger.debug("service get response: %s, %s" % (resp.status_code, content)) - - content = ProxyUtils.update_prefix(metadata_catalog, content) - return Response(headers={'X-Subject-Token': tmp_auth_token}, data=content, status=resp.status_code) - #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) + 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)) - try: - # prepare request resource to vim instance - # get token: - tmp_auth_token = request.META.get('HTTP_X_AUTH_TOKEN', None) - if not tmp_auth_token: - return Response(data={'error': "No X-Auth-Token found in headers"}, status=status.HTTP_401_UNAUTHORIZED) - vim = VimDriverUtils.get_vim_info(vimid) - # fetch the auth_state out of cache - tmp_auth_state, metadata_catalog = VimDriverUtils.get_token_cache(vim, tmp_auth_token) - if not tmp_auth_state: - return Response(data={'error': "Expired X-Auth-Token found in headers"}, - status=status.HTTP_401_UNAUTHORIZED) - - real_prefix = None - proxy_prefix = None - suffix = None - if servicetype and metadata_catalog: -# self._logger.error("metadata_catalog:%s" % 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) - - sess = VimDriverUtils.get_session(vim, tenantid=None, auth_state=tmp_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 post request uri %s" % (req_resource)) - - resp = sess.post(req_resource, data=json.JSONEncoder().encode(request.data),endpoint_filter=service) - # update token cache in case the token was required during the requests - #tmp_auth_token = VimDriverUtils.update_token_cache(vim, sess, tmp_auth_token, tmp_auth_state) - content = resp.json() if resp.content else None - self._logger.debug("service post response: %s, %s" % (resp.status_code, content)) - - content = ProxyUtils.update_prefix(metadata_catalog, content) - 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) + 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)) - try: - # prepare request resource to vim instance - # get token: - tmp_auth_token = request.META.get('HTTP_X_AUTH_TOKEN', None) - if not tmp_auth_token: - return Response(data={'error': "No X-Auth-Token found in headers"}, status=status.HTTP_401_UNAUTHORIZED) - - vim = VimDriverUtils.get_vim_info(vimid) - # fetch the auth_state out of cache - tmp_auth_state, metadata_catalog = VimDriverUtils.get_token_cache(vim, tmp_auth_token) - if not tmp_auth_state: - return Response(data={'error': "Expired X-Auth-Token found in headers"}, - status=status.HTTP_401_UNAUTHORIZED) - - real_prefix = None - proxy_prefix = None - suffix = None - if servicetype and metadata_catalog: -# self._logger.error("metadata_catalog:%s" % 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) - - sess = VimDriverUtils.get_session(vim, tenantid=None, auth_state=tmp_auth_state) - req_resource = "" - if requri and requri != "": - req_resource = "/" + requri - - cloud_owner, regionid = extsys.decode_vim_id(vimid) - interface = 'public' - service = {'service_type': servicetype, - 'interface': interface, - 'region_id': regionid} - - self._logger.debug("service put request uri %s" % (req_resource)) - - resp = sess.put(req_resource, data=json.JSONEncoder().encode(request.data),endpoint_filter=service) - # update token cache in case the token was required during the requests - #tmp_auth_token = VimDriverUtils.update_token_cache(vim, sess, tmp_auth_token, tmp_auth_state) - content = resp.json() if resp.content else None - self._logger.debug("service put response: %s, %s" % (resp.status_code, content)) - - content = ProxyUtils.update_prefix(metadata_catalog, content) - 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) - + 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)) - try: - # prepare request resource to vim instance - # get token: - tmp_auth_token = request.META.get('HTTP_X_AUTH_TOKEN', None) - if not tmp_auth_token: - return Response(data={'error': "No X-Auth-Token found in headers"}, status=status.HTTP_401_UNAUTHORIZED) - - vim = VimDriverUtils.get_vim_info(vimid) - # fetch the auth_state out of cache - tmp_auth_state, metadata_catalog = VimDriverUtils.get_token_cache(vim, tmp_auth_token) - if not tmp_auth_state: - return Response(data={'error': "Expired X-Auth-Token found in headers"}, - status=status.HTTP_401_UNAUTHORIZED) - - real_prefix = None - proxy_prefix = None - suffix = None - if servicetype and metadata_catalog: -# self._logger.error("metadata_catalog:%s" % 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) - - sess = VimDriverUtils.get_session(vim, tenantid=None, auth_state=tmp_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 patch request uri %s" % (req_resource)) - - resp = sess.patch(req_resource, data=json.JSONEncoder().encode(request.data),endpoint_filter=service) - # update token cache in case the token was required during the requests - #tmp_auth_token = VimDriverUtils.update_token_cache(vim, sess, tmp_auth_token, tmp_auth_state) - content = resp.json() if resp.content else None - self._logger.debug("service patch response: %s, %s" % (resp.status_code, content)) - - content = ProxyUtils.update_prefix(metadata_catalog, content) - 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) + 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)) - try: - # prepare request resource to vim instance - # get token: - tmp_auth_token = request.META.get('HTTP_X_AUTH_TOKEN', None) - if not tmp_auth_token: - return Response(data={'error': "No X-Auth-Token found in headers"}, status=status.HTTP_401_UNAUTHORIZED) - - vim = VimDriverUtils.get_vim_info(vimid) - # fetch the auth_state out of cache - tmp_auth_state, metadata_catalog = VimDriverUtils.get_token_cache(vim, tmp_auth_token) - if not tmp_auth_state: - return Response(data={'error': "Expired X-Auth-Token found in headers"}, - status=status.HTTP_401_UNAUTHORIZED) - - real_prefix = None - proxy_prefix = None - suffix = None - if servicetype and metadata_catalog: -# self._logger.error("metadata_catalog:%s" % 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) - - sess = VimDriverUtils.get_session(vim, tenantid=None, auth_state=tmp_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 delete request uri %s" % (req_resource)) - - resp = sess.delete(req_resource, endpoint_filter=service) - # update token cache in case the token was required during the requests - #tmp_auth_token = VimDriverUtils.update_token_cache(vim, sess, tmp_auth_token, tmp_auth_state) - - return Response(headers={'X-Subject-Token': tmp_auth_token}, 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) + return self._do_action("delete", request, vimid, servicetype, requri) class GetTenants(Services): diff --git a/newton/newton/requests/tests/test_reqeust.py b/newton/newton/requests/tests/test_reqeust.py deleted file mode 100644 index d094314d..00000000 --- a/newton/newton/requests/tests/test_reqeust.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) 2017 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. - -from django.test import TestCase - - -class TestNetworksRequest(TestCase): - def assert_true_result(self): - self.assertTrue(1) diff --git a/newton/newton/requests/tests/test_request.py b/newton/newton/requests/tests/test_request.py new file mode 100644 index 00000000..d094314d --- /dev/null +++ b/newton/newton/requests/tests/test_request.py @@ -0,0 +1,20 @@ +# Copyright (c) 2017 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. + +from django.test import TestCase + + +class TestNetworksRequest(TestCase): + def assert_true_result(self): + self.assertTrue(1) diff --git a/newton/newton/requests/views/util.py b/newton/newton/requests/views/util.py index c5046387..f2c62896 100644 --- a/newton/newton/requests/views/util.py +++ b/newton/newton/requests/views/util.py @@ -124,15 +124,13 @@ class VimDriverUtils(object): # return auth.get_auth_ref(session) @staticmethod - def get_token_cache(vim, token): + def get_token_cache(token): ''' get auth_state and metadata fromm cache - :param vim: :param token: :return: ''' - metadata_key = "meta_%s" % token - return cache.get(token), cache.get(metadata_key) + return cache.get(token), cache.get("meta_%s" % token) @staticmethod diff --git a/newton/newton/settings.py b/newton/newton/settings.py index b62a584f..d460758c 100644 --- a/newton/newton/settings.py +++ b/newton/newton/settings.py @@ -12,6 +12,13 @@ import os import sys +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': 'mydatabase', + } +} + # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -- cgit 1.2.3-korg