Fix bug in identity v2.0 proxy 91/17591/2
authorBin Yang <bin.yang@windriver.com>
Mon, 9 Oct 2017 09:42:08 +0000 (17:42 +0800)
committerBin Yang <bin.yang@windriver.com>
Mon, 9 Oct 2017 09:42:08 +0000 (17:42 +0800)
Change-Id: I9e25a1b6438f602e38c13cc1282daa9b10118388
Issue-Id: MULTICLOUD-109
Signed-off-by: Bin Yang <bin.yang@windriver.com>
newton/newton/proxy/urls.py
newton/newton/proxy/views/identityV3.py
newton/newton/pub/msapi/extsys.py
newton/newton/pub/tests/test_extsys.py
newton/newton/pub/tests/test_restcall.py
newton/newton/pub/utils/restcall.py
ocata/ocata/proxy/urls.py
ocata/run.sh
windriver/run.sh
windriver/titanium_cloud/proxy/urls.py

index ee2da59..556cc4e 100644 (file)
@@ -23,9 +23,11 @@ urlpatterns = [
     #        identityV2.Tokens.as_view()),
     url(r'^identity/v3/auth/tokens$',
         identityV3.Tokens.as_view()),
-    url(r'^identity/v2.0/tokens$',
+    url(r'^identity/v2.0/?$',
         identityV3.TokensV2.as_view()),
-    url(r'^identity/v2.0/tenants$',
+    url(r'^identity/v2.0/tokens/?$',
+        identityV3.TokensV2.as_view()),
+    url(r'^identity/v2.0/tenants/?$',
         services.GetTenants.as_view()),
     url(r'^(?P<servicetype>[0-9a-zA-Z_-]{,18})/(?P<requri>[0-9a-zA-Z./_-]*)$',
         services.Services.as_view()),
index bf63ad6..3fa124c 100644 (file)
@@ -50,14 +50,26 @@ class Tokens(APIView):
         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("tenant_name")
+                tenant_name = request.data["auth"].get("tenantName")
+
+            #keystone v3 API
+            if not tenant_name and request.data.get("auth") \
+                    and request.data["auth"].get("scope")\
+                    and request["auth"]["scope"].get("project"):
+                if request["auth"]["scope"]["project"].get("name"):
+                    tenant_name = request["auth"]["scope"]["project"].get("name")
+                else:
+                    tenant_id = request["auth"]["scope"]["project"].get("id")
+
+
 
             # prepare request resource to vim instance
             vim = VimDriverUtils.get_vim_info(vimid)
-            sess = VimDriverUtils.get_session(vim, tenantname = tenant_name)
+            sess = VimDriverUtils.get_session(vim, tenantname = tenant_name, tenantid=tenant_id)
 
             tmp_auth_state = VimDriverUtils.get_auth_state(vim, sess)
             tmp_auth_info = json.loads(tmp_auth_state)
@@ -85,6 +97,21 @@ class Tokens(APIView):
             return Response(data={'error': str(e)},
                             status=status.HTTP_500_INTERNAL_SERVER_ERROR)
 
+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):
     '''
@@ -95,6 +122,11 @@ class TokensV2(Tokens):
         self.proxy_prefix = config.MULTICLOUD_PREFIX
         self._logger = logger
 
+    def get(self, request, vimid=""):
+        self._logger.debug("TokensV2--get::META> %s" % request.META)
+
+        return Response(data=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)
@@ -142,11 +174,14 @@ class TokensV2(Tokens):
                             "tenant" : v3_token["project"],
                         },
                         "serviceCatalog": v2_catalog,
-    #                    "user": v3_token["user"],
+                        "user": v3_token["user"],
                     }
                 }
 
-                return Response(data=v2_content, status=resp.status_code)
+                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
index aa6a159..0f08adb 100644 (file)
@@ -25,7 +25,7 @@ def get_vim_by_id(vim_id):
 
     if cloud_owner and cloud_region_id:
         retcode, content, status_code = \
-            restcall.req_to_aai("/cloud-infrastructure/cloud-regions/cloud-region/%s/%s"
+            restcall.req_to_aai("/cloud-infrastructure/cloud-regions/cloud-region/%s/%s?depth=1"
                        % (cloud_owner,cloud_region_id),"GET")
         if retcode != 0:
             logger.error("Status code is %s, detail is %s.", status_code, content)
@@ -35,16 +35,17 @@ def get_vim_by_id(vim_id):
         tmp_viminfo = json.JSONDecoder().decode(content)
 
         #assume esr-system-info-id is composed by {cloud-owner} _ {cloud-region-id}
-        retcode2,content2,status_code2 = \
-            restcall.req_to_aai(("/cloud-infrastructure/cloud-regions/cloud-region/%(owner)s/%(region)s"
-                                 "/esr-system-info-list/esr-system-info/%(owner)s_%(region)s" % {
-                "owner": cloud_owner, "region": cloud_region_id}), "GET")
-        if retcode2 != 0:
-            logger.error("Status code is %s, detail is %s.", status_code, content)
-            raise VimDriverNewtonException(
-                "Failed to query ESR system with id (%s:%s,%s)." % (vim_id,cloud_owner,cloud_region_id),
-                status_code, content)
-        tmp_authinfo = json.JSONDecoder().decode(content2)
+#        retcode2,content2,status_code2 = \
+#            restcall.req_to_aai(("/cloud-infrastructure/cloud-regions/cloud-region/%(owner)s/%(region)s"
+#                                 "/esr-system-info-list/esr-system-info/%(owner)s_%(region)s" % {
+#                "owner": cloud_owner, "region": cloud_region_id}), "GET")
+#        if retcode2 != 0:
+#            logger.error("Status code is %s, detail is %s.", status_code, content)
+#            raise VimDriverNewtonException(
+#                "Failed to query ESR system with id (%s:%s,%s)." % (vim_id,cloud_owner,cloud_region_id),
+#                status_code2, content2)
+#        tmp_authinfo = json.JSONDecoder().decode(content2)
+        tmp_authinfo = tmp_viminfo['esr-system-info-list']['esr-system-info'][0] if tmp_viminfo else None
 
         #convert vim information
         if tmp_viminfo and tmp_authinfo:
@@ -52,19 +53,19 @@ def get_vim_by_id(vim_id):
             viminfo['vimId'] = vim_id
             viminfo['cloud_owner'] = cloud_owner
             viminfo['cloud_region_id'] = cloud_region_id
-            viminfo['type'] = tmp_viminfo['cloud-type']
-            viminfo['name'] = tmp_viminfo['complex-name']
-            viminfo['version'] = tmp_viminfo['cloud-region-version']
-            viminfo['cloud_extra_info'] = tmp_viminfo['cloud-extra-info']
-            viminfo['cloud_epa_caps'] = tmp_viminfo['cloud-epa-caps']
+            viminfo['type'] = tmp_viminfo.get('cloud-type')
+            viminfo['name'] = tmp_viminfo.get('complex-name')
+            viminfo['version'] = tmp_viminfo.get('cloud-region-version')
+            viminfo['cloud_extra_info'] = tmp_viminfo.get('cloud-extra-info')
+            viminfo['cloud_epa_caps'] = tmp_viminfo.get('cloud-epa-caps')
 
             viminfo['userName'] = tmp_authinfo['user-name']
             viminfo['password'] = tmp_authinfo['password']
-            viminfo['domain'] = tmp_authinfo['cloud-domain']
-            viminfo['url'] = tmp_authinfo['service-url']
-            viminfo['tenant'] = tmp_authinfo['default-tenant']
-            viminfo['cacert'] = tmp_authinfo['ssl-cacert']
-            viminfo['insecure'] = tmp_authinfo['ssl-insecure']
+            viminfo['domain'] = tmp_authinfo.get('cloud-domain')
+            viminfo['url'] = tmp_authinfo.get('service-url')
+            viminfo['tenant'] = tmp_authinfo.get('default-tenant')
+            viminfo['cacert'] = tmp_authinfo.get('ssl-cacert')
+            viminfo['insecure'] = tmp_authinfo.get('ssl-insecure')
 
             return viminfo
     return None
index 239ebe0..533910f 100644 (file)
@@ -23,24 +23,31 @@ from newton.pub.exceptions import VimDriverNewtonException
 from newton.pub.msapi import extsys
 from newton.pub.utils import restcall
 
-MOCK_VIM_INFO = {
-    "cloud-type": "openstack",
-    "complex-name": "complex",
-    "cloud-region-version": "Regionv1",
-    "cloud-extra-info": "type",
-    "cloud-epa-caps": "epa"
-}
 
 MOCK_ESR_SYSTEM_INFO = {
     "user-name": "test",
     "password": "secret",
-    "cloud-domain": "default",
+    "cloud-domain": "Default",
     "service-url": "http://localhost",
     "default-tenant": "demo",
     "ssl-cacert": None,
     "ssl-insecure": None
 }
 
+MOCK_VIM_INFO = {
+    "cloud-type": "openstack",
+    "complex-name": "complex",
+    "cloud-region-version": "Regionv1",
+    "cloud-extra-info": "type",
+    "cloud-epa-caps": "epa",
+    "esr-system-info-list" :
+        {
+            "esr-system-info": [
+                MOCK_ESR_SYSTEM_INFO
+            ]
+        }
+}
+
 
 def returnList(items):
     def func():
@@ -82,7 +89,7 @@ class TestEpaCaps(unittest.TestCase):
         self.assertRaises(VimDriverNewtonException, extsys.get_vim_by_id, self.vim_id)
         restcall.req_to_aai.assert_called_once()
 
-        self.assertRaises(VimDriverNewtonException, extsys.get_vim_by_id, self.vim_id)
+        #self.assertRaises(VimDriverNewtonException, extsys.get_vim_by_id, self.vim_id)
 
         viminfo = extsys.get_vim_by_id(self.vim_id)
         self.assertIsNotNone(viminfo)
index 28def73..063beb3 100644 (file)
@@ -19,6 +19,7 @@ import unittest
 
 from newton.pub.utils import restcall
 
+rest_no_auth, rest_oneway_auth, rest_bothway_auth = 0, 1, 2
 
 class TestRestCall(unittest.TestCase):
     base_url = "http://localhost"
@@ -29,7 +30,7 @@ class TestRestCall(unittest.TestCase):
         mock_http.raiseError.side_effect = mock.Mock(
             side_effect=Exception('Test'))
         args = [
-            self.base_url, "user", "password", "auth_type",
+            self.base_url, None, None, rest_no_auth,
             self.resource, "get", {"extra": "test"}
         ]
 
@@ -41,7 +42,7 @@ class TestRestCall(unittest.TestCase):
     @mock.patch.object(Http, 'request')
     def test_invalid_output_call_req(self, mock_http):
         args = [
-            self.base_url, "user", "password", "auth_type",
+            self.base_url, None, None, rest_no_auth,
             self.resource, "get", {"extra": "test"}
         ]
 
@@ -56,7 +57,7 @@ class TestRestCall(unittest.TestCase):
     @mock.patch.object(Http, 'request')
     def test_req_by_msb(self, mock_http):
         resp_body = "test_body"
-        resp_status=status.HTTP_200_OK
+        resp_status='200' #status.HTTP_200_OK
         mock_http.return_value = (
             {'status': resp_status},
             str.encode(resp_body, 'utf-8'))
@@ -70,7 +71,7 @@ class TestRestCall(unittest.TestCase):
     @mock.patch.object(Http, 'request')
     def test_req_to_vim(self, mock_http):
         resp_body = "test_body"
-        resp_status=status.HTTP_200_OK
+        resp_status='200' #status.HTTP_200_OK
         mock_http.return_value = (
             {'status': resp_status},
             str.encode(resp_body, 'utf-8'))
@@ -83,7 +84,7 @@ class TestRestCall(unittest.TestCase):
     @mock.patch.object(Http, 'request')
     def test_req_to_aai(self, mock_http):
         resp_body = "test_body"
-        resp_status=status.HTTP_200_OK
+        resp_status='200' #status.HTTP_200_OK
         mock_http.return_value = (
             {'status': resp_status},
             str.encode(resp_body, 'utf-8'))
index 6444014..f0c1993 100644 (file)
@@ -9,6 +9,9 @@
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
+import six
+import base64
+
 import codecs
 import json
 import traceback
@@ -23,9 +26,12 @@ from rest_framework import status
 from newton.pub.config import config
 
 rest_no_auth, rest_oneway_auth, rest_bothway_auth = 0, 1, 2
-
-status_ok_list \
-    = [status.HTTP_200_OK, status.HTTP_201_CREATED, status.HTTP_204_NO_CONTENT, status.HTTP_202_ACCEPTED]
+HTTP_200_OK, HTTP_201_CREATED = '200', '201'
+HTTP_204_NO_CONTENT, HTTP_202_ACCEPTED = '204', '202'
+status_ok_list = [HTTP_200_OK, HTTP_201_CREATED,
+                  HTTP_204_NO_CONTENT, HTTP_202_ACCEPTED]
+HTTP_404_NOTFOUND, HTTP_403_FORBIDDEN = '404', '403'
+HTTP_401_UNAUTHORIZED, HTTP_400_BADREQUEST = '401', '400'
 
 MAX_RETRY_TIME = 3
 
@@ -46,9 +52,16 @@ def _call_req(base_url, user, passwd, auth_type,
 
         if extra_headers:
             headers.update(extra_headers)
+#        if user:
+#            headers['Authorization'] = \
+#                'Basic ' + str(codecs.encode('%s:%s' % (user, passwd), "ascii"))
+
         if user:
-            headers['Authorization'] = \
-                'Basic ' + str(codecs.encode('%s:%s' % (user, passwd), "ascii"))
+            tmpauthsource = '%s:%s' % (user, passwd)
+            if six.PY3:
+                tmpauthsource = tmpauthsource.encode('utf-8')
+            headers['Authorization'] = 'Basic ' + \
+                base64.b64encode(tmpauthsource).decode('utf-8')
 
         ca_certs = None
         for retry_times in range(MAX_RETRY_TIME):
@@ -102,7 +115,7 @@ def req_to_vim(base_url, resource, method, extra_headers='', content=''):
 
 
 def req_to_aai(resource, method, content='', appid=config.MULTICLOUD_APP_ID):
-    tmp_trasaction_id = str(uuid.uuid1())
+    tmp_trasaction_id = '9003' #str(uuid.uuid1())
     headers = {
         'X-FromAppId': appid,
         'X-TransactionId': tmp_trasaction_id,
@@ -110,7 +123,8 @@ def req_to_aai(resource, method, content='', appid=config.MULTICLOUD_APP_ID):
         'accept': 'application/json'
     }
 
-    logger.debug("req_to_aai--%s::> %s, %s" % (tmp_trasaction_id, method, resource))
+    logger.debug("req_to_aai--%s::> %s, %s" %
+                 (tmp_trasaction_id, method, _combine_url(config.AAI_BASE_URL,resource)))
     return _call_req(config.AAI_BASE_URL, config.AAI_USERNAME, config.AAI_PASSWORD, rest_no_auth,
                     resource, method, content=json.dumps(content), extra_headers=headers)
 
index 12777bf..e59b2e0 100644 (file)
@@ -21,11 +21,13 @@ from ocata.proxy.views import services
 urlpatterns = [
     #    url(r'^identity/v2)$',
     #        identityV2.Tokens.as_view()),
-    url(r'^identity/v3/auth/tokens$',
+    url(r'^identity/v3/auth/tokens/?$',
         identityV3.Tokens.as_view()),
-    url(r'^identity/v2.0/tokens$',
+    url(r'^identity/v2.0/?',
         identityV3.TokensV2.as_view()),
-    url(r'^identity/v2.0/tenants$',
+    url(r'^identity/v2.0/tokens/?$',
+        identityV3.TokensV2.as_view()),
+    url(r'^identity/v2.0/tenants/?$',
         services.GetTenants.as_view()),
     url(r'^(?P<servicetype>[0-9a-zA-Z_-]{,18})/(?P<requri>[0-9a-zA-Z./_-]*)$',
         services.Services.as_view()),
index 446172b..cfb52b7 100644 (file)
@@ -20,6 +20,14 @@ sed -i "s/AAI_SCHEMA_VERSION =.*/AAI_SCHEMA_VERSION = \"${AAI_SCHEMA_VERSION}\"/
 sed -i "s/AAI_USERNAME =.*/AAI_USERNAME = \"${AAI_USERNAME}\"/g" ocata/pub/config/config.py
 sed -i "s/AAI_PASSWORD =.*/AAI_PASSWORD = \"${AAI_PASSWORD}\"/g" ocata/pub/config/config.py
 
+sed -i "s/MSB_SERVICE_ADDR =.*/MSB_SERVICE_ADDR = \"${MSB_ADDR}\"/g" lib/newton/newton/pub/config/config.py
+sed -i "s/MSB_SERVICE_PORT =.*/MSB_SERVICE_PORT = \"${MSB_PORT}\"/g" lib/newton/newton/pub/config/config.py
+sed -i "s/AAI_ADDR =.*/AAI_ADDR = \"${AAI_ADDR}\"/g" lib/newton/newton/pub/config/config.py
+sed -i "s/AAI_PORT =.*/AAI_PORT = \"${AAI_PORT}\"/g" lib/newton/newton/pub/config/config.py
+sed -i "s/AAI_SCHEMA_VERSION =.*/AAI_SCHEMA_VERSION = \"${AAI_SCHEMA_VERSION}\"/g" lib/newton/newton/pub/config/config.py
+sed -i "s/AAI_USERNAME =.*/AAI_USERNAME = \"${AAI_USERNAME}\"/g" lib/newton/newton/pub/config/config.py
+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
 nohup python manage.py runserver 0.0.0.0:9006 2>&1 &
index 031719b..ddf92da 100644 (file)
@@ -20,6 +20,14 @@ sed -i "s/AAI_SCHEMA_VERSION =.*/AAI_SCHEMA_VERSION = \"${AAI_SCHEMA_VERSION}\"/
 sed -i "s/AAI_USERNAME =.*/AAI_USERNAME = \"${AAI_USERNAME}\"/g" titanium_cloud/pub/config/config.py
 sed -i "s/AAI_PASSWORD =.*/AAI_PASSWORD = \"${AAI_PASSWORD}\"/g" titanium_cloud/pub/config/config.py
 
+sed -i "s/MSB_SERVICE_ADDR =.*/MSB_SERVICE_ADDR = \"${MSB_ADDR}\"/g" lib/newton/newton/pub/config/config.py
+sed -i "s/MSB_SERVICE_PORT =.*/MSB_SERVICE_PORT = \"${MSB_PORT}\"/g" lib/newton/newton/pub/config/config.py
+sed -i "s/AAI_ADDR =.*/AAI_ADDR = \"${AAI_ADDR}\"/g" lib/newton/newton/pub/config/config.py
+sed -i "s/AAI_PORT =.*/AAI_PORT = \"${AAI_PORT}\"/g" lib/newton/newton/pub/config/config.py
+sed -i "s/AAI_SCHEMA_VERSION =.*/AAI_SCHEMA_VERSION = \"${AAI_SCHEMA_VERSION}\"/g" lib/newton/newton/pub/config/config.py
+sed -i "s/AAI_USERNAME =.*/AAI_USERNAME = \"${AAI_USERNAME}\"/g" lib/newton/newton/pub/config/config.py
+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
 nohup python manage.py runserver 0.0.0.0:9005 2>&1 &
index 31a3c8f..73cd428 100644 (file)
@@ -23,6 +23,8 @@ urlpatterns = [
     #        identityV2.Tokens.as_view()),
     url(r'^identity/v3/auth/tokens/?$',
         identityV3.Tokens.as_view()),
+    url(r'^identity/v2.0/?$',
+        identityV3.TokensV2.as_view()),
     url(r'^identity/v2.0/tokens/?$',
         identityV3.TokensV2.as_view()),
     url(r'^identity/v2.0/tenants/?$',