summaryrefslogtreecommitdiffstats
path: root/starlingx
diff options
context:
space:
mode:
Diffstat (limited to 'starlingx')
-rw-r--r--starlingx/starlingx/proxy/__init__.py13
-rw-r--r--starlingx/starlingx/proxy/tests/__init__.py13
-rw-r--r--starlingx/starlingx/proxy/tests/test_identity_proxy.py739
-rw-r--r--starlingx/starlingx/proxy/tests/test_service_proxy.py852
-rw-r--r--starlingx/starlingx/proxy/urls.py41
-rw-r--r--starlingx/starlingx/proxy/urlsV1.py39
-rw-r--r--starlingx/starlingx/proxy/views/__init__.py13
-rw-r--r--starlingx/starlingx/proxy/views/identityV3.py84
-rw-r--r--starlingx/starlingx/proxy/views/services.py146
-rw-r--r--starlingx/starlingx/registration/__init__.py13
-rw-r--r--starlingx/starlingx/registration/tests/__init__.py13
-rw-r--r--starlingx/starlingx/registration/tests/test_registration.py485
-rw-r--r--starlingx/starlingx/registration/tests/test_registration2.py107
-rw-r--r--starlingx/starlingx/requests/__init__.py13
-rw-r--r--starlingx/starlingx/requests/urls.py49
-rw-r--r--starlingx/starlingx/requests/urlsV1.py49
-rw-r--r--starlingx/starlingx/requests/views/__init__.py13
-rw-r--r--starlingx/starlingx/resource/__init__.py13
-rw-r--r--starlingx/starlingx/resource/tests/__init__.py13
-rw-r--r--starlingx/starlingx/resource/tests/test_capacity.py277
-rw-r--r--starlingx/starlingx/resource/tests/tests_infra_workload.py280
-rw-r--r--starlingx/starlingx/urls.py34
22 files changed, 3299 insertions, 0 deletions
diff --git a/starlingx/starlingx/proxy/__init__.py b/starlingx/starlingx/proxy/__init__.py
new file mode 100644
index 00000000..81362a2b
--- /dev/null
+++ b/starlingx/starlingx/proxy/__init__.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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.
diff --git a/starlingx/starlingx/proxy/tests/__init__.py b/starlingx/starlingx/proxy/tests/__init__.py
new file mode 100644
index 00000000..81362a2b
--- /dev/null
+++ b/starlingx/starlingx/proxy/tests/__init__.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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.
diff --git a/starlingx/starlingx/proxy/tests/test_identity_proxy.py b/starlingx/starlingx/proxy/tests/test_identity_proxy.py
new file mode 100644
index 00000000..36bbb370
--- /dev/null
+++ b/starlingx/starlingx/proxy/tests/test_identity_proxy.py
@@ -0,0 +1,739 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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 json
+
+import mock
+import unittest
+
+from django.test import Client
+from rest_framework import status
+
+from newton_base.util import VimDriverUtils
+from newton_base.tests import mock_info
+
+mock_viminfo = {
+ "createTime": "2017-04-01 02:22:27",
+ "domain": "Default",
+ "name": "TiS_R4",
+ "password": "admin",
+ "tenant": "admin",
+ "type": "openstack",
+ "url": "http://128.224.180.14:5000/v3",
+ "userName": "admin",
+ "vendor": "Starlingx",
+ "version": "starlingx",
+ "vimId": "starlingx_RegionOne",
+ 'cloud_owner': 'starlingx',
+ 'cloud_region_id': ' RegionOne',
+ 'cloud_extra_info': '',
+ 'insecure': 'True',
+}
+
+mock_token_id = "1a62b3971d774404a504c5d9a3e506e3"
+
+mock_catalog_response = {
+ "catalog": [
+ {
+ "id": "99aefcc82a9246f98f8c281e61ffc754",
+ "endpoints": [
+ {
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:9696",
+ "id": "39583c1508ad4b71b380570a745ee10a",
+ "interface": "public",
+ "region_id": "RegionOne"
+ },
+ {
+ "url": "http://192.168.204.2:9696",
+ "region": "RegionOne",
+ "id": "37e8d07ba24e4b8f93490c9daaba06e2",
+ "interface": "internal",
+ "region_id": "RegionOne"
+ },
+ {
+ "interface": "admin",
+ "id": "7eee4ca98d444b1abb00a50d4b89373f",
+ "region_id": "RegionOne",
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:9696"
+ }
+ ],
+ "name": "neutron",
+ "type": "network"
+ },
+ {
+ "endpoints": [
+ {
+ "interface": "public",
+ "id": "10496738fa374295a4a88a63b81a1589",
+ "region_id": "RegionOne",
+ "url": "http://128.224.180.14:8777",
+ "region": "RegionOne"
+ },
+ {
+ "id": "02dcb8c0bd464c4489fa0a0c9f28571f",
+ "region_id": "RegionOne",
+ "interface": "internal",
+ "url": "http://192.168.204.2:8777",
+ "region": "RegionOne"
+ },
+ {
+ "region_id": "RegionOne",
+ "id": "8a73b0d3743b4e78b87614690f6e97fe",
+ "interface": "admin",
+ "url": "http://192.168.204.2:8777",
+ "region": "RegionOne"
+ }
+ ],
+ "id": "d131054da83f4c93833799747a0f4709",
+ "name": "ceilometer",
+ "type": "metering"
+ },
+ {
+ "type": "volumev2",
+ "name": "cinderv2",
+ "endpoints": [
+ {
+ "id": "35a67ad36f0447d19c9662babf7cf609",
+ "interface": "public",
+ "region_id": "RegionOne",
+ "url": "http://128.224.180.14:8776/v2/fcca3cc49d5e42caae15459e27103efc",
+ "region": "RegionOne"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8776/v2/fcca3cc49d5e42caae15459e27103efc",
+ "id": "c6ea42052268420fa2c8d351ee68c922",
+ "interface": "internal",
+ "region_id": "RegionOne"
+ },
+ {
+ "region_id": "RegionOne",
+ "id": "91cb24853dc3450d847b0c286a2e44ea",
+ "interface": "admin",
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8776/v2/fcca3cc49d5e42caae15459e27103efc"
+ }
+ ],
+ "id": "40440057102440739c30be10a66bc5d1"
+ },
+ {
+ "name": "heat",
+ "type": "orchestration",
+ "id": "35300cce88db4bd4bb5a72ffe3b88b00",
+ "endpoints": [
+ {
+ "id": "58999d7b4a94439089ecfb2aca2d7f6c",
+ "region_id": "RegionOne",
+ "interface": "public",
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:8004/v1/fcca3cc49d5e42caae15459e27103efc"
+ },
+ {
+ "url": "http://192.168.204.2:8004/v1/fcca3cc49d5e42caae15459e27103efc",
+ "region": "RegionOne",
+ "interface": "internal",
+ "id": "1e0ee1a2aef84802b921d422372a567e",
+ "region_id": "RegionOne"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8004/v1/fcca3cc49d5e42caae15459e27103efc",
+ "id": "17661bf4859741b8a43a461dedad1871",
+ "region_id": "RegionOne",
+ "interface": "admin"
+ }
+ ]
+ },
+ {
+ "id": "08dc6912aea64c01925012c8a6df250a",
+ "endpoints": [
+ {
+ "id": "02792c4eed77486083f9b2e52d7b94b0",
+ "region_id": "RegionOne",
+ "interface": "public",
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:5000/v3"
+ },
+ {
+ "id": "b6d5cad394b94309ae40d8de88059c5f",
+ "region_id": "RegionOne",
+ "interface": "internal",
+ "url": "http://192.168.204.2:5000/v3",
+ "region": "RegionOne"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:35357/v3",
+ "region_id": "RegionOne",
+ "id": "1f18e2b7c6a34493b86853b65917888e",
+ "interface": "admin"
+ }
+ ],
+ "type": "identity",
+ "name": "keystone"
+ },
+ {
+ "name": "vim",
+ "type": "nfv",
+ "endpoints": [
+ {
+ "url": "http://128.224.180.14:4545",
+ "region": "RegionOne",
+ "id": "b33e317345e4480ab0786e4960995ec9",
+ "interface": "public",
+ "region_id": "RegionOne"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:4545",
+ "interface": "internal",
+ "id": "03c85828d5bf432ab04831aa65ac9c52",
+ "region_id": "RegionOne"
+ },
+ {
+ "id": "067983abb061476cb53a9e23a740d98f",
+ "region_id": "RegionOne",
+ "interface": "admin",
+ "url": "http://192.168.204.2:4545",
+ "region": "RegionOne"
+ }
+ ],
+ "id": "01636c856fc84988b38b9117eb4a8021"
+ },
+ {
+ "name": "aodh",
+ "type": "alarming",
+ "id": "eb269151d0e44744a5b5449657bdc61c",
+ "endpoints": [
+ {
+ "id": "5bfc6c056e0244c493642eb82f6aaa11",
+ "region_id": "RegionOne",
+ "interface": "public",
+ "url": "http://128.224.180.14:8042",
+ "region": "RegionOne"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8042",
+ "region_id": "RegionOne",
+ "id": "ad69c7f76dce4089a195b9221ddbfb44",
+ "interface": "internal"
+ },
+ {
+ "interface": "admin",
+ "id": "3e8fcdfa7bcb40b0ae33c282adfcc9ff",
+ "region_id": "RegionOne",
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8042"
+ }
+ ]
+ },
+ {
+ "name": "sysinv",
+ "type": "platform",
+ "endpoints": [
+ {
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:6385/v1",
+ "interface": "public",
+ "id": "ba4ba8104590421b84672306c7e0e1f1",
+ "region_id": "RegionOne"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:6385/v1",
+ "interface": "internal",
+ "id": "a1cba34b163f496ab1acd6e9b51e39a2",
+ "region_id": "RegionOne"
+ },
+ {
+ "url": "http://192.168.204.2:6385/v1",
+ "region": "RegionOne",
+ "id": "7c171210a2c841a6a52a5713e316d6fc",
+ "interface": "admin",
+ "region_id": "RegionOne"
+ }
+ ],
+ "id": "256bbad671f946fea543e6bd71f98875"
+ },
+ {
+ "id": "e84665dcce814c05b4c5084964547534",
+ "endpoints": [
+ {
+ "url": "http://128.224.180.14:8000/v1/fcca3cc49d5e42caae15459e27103efc",
+ "region": "RegionOne",
+ "region_id": "RegionOne",
+ "id": "b2ed1a23dc6944bea129c20861e0286a",
+ "interface": "public"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8000/v1/fcca3cc49d5e42caae15459e27103efc",
+ "interface": "internal",
+ "id": "c4df7c6bc15646848eff35caf6ffea8e",
+ "region_id": "RegionOne"
+ },
+ {
+ "region_id": "RegionOne",
+ "id": "61b3dabb761443a89ab549f437c05ab0",
+ "interface": "admin",
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8000/v1/fcca3cc49d5e42caae15459e27103efc"
+ }
+ ],
+ "name": "heat-cfn",
+ "type": "cloudformation"
+ },
+ {
+ "id": "823024424a014981a3721229491c0b1a",
+ "endpoints": [
+ {
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:8776/v1/fcca3cc49d5e42caae15459e27103efc",
+ "region_id": "RegionOne",
+ "id": "4a52e4e54ff440789f9a797919c4a0f2",
+ "interface": "public"
+ },
+ {
+ "url": "http://192.168.204.2:8776/v1/fcca3cc49d5e42caae15459e27103efc",
+ "region": "RegionOne",
+ "id": "d4f9a84476524a39844f0fce63f1022e",
+ "region_id": "RegionOne",
+ "interface": "internal"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8776/v1/fcca3cc49d5e42caae15459e27103efc",
+ "interface": "admin",
+ "id": "81bf3810a8cc4697b68c6e93b5b8fe1f",
+ "region_id": "RegionOne"
+ }
+ ],
+ "type": "volume",
+ "name": "cinder"
+ },
+ {
+ "name": "glance",
+ "type": "image",
+ "endpoints": [
+ {
+ "id": "bd930aba961946cfb1401bada56d55e3",
+ "region_id": "RegionOne",
+ "interface": "public",
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:9292"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:9292",
+ "id": "c11da585f0b141b99d1e18bb9a607beb",
+ "region_id": "RegionOne",
+ "interface": "internal"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:9292",
+ "id": "31b26c625a6a4fc7910dc5935155996e",
+ "interface": "admin",
+ "region_id": "RegionOne"
+ }
+ ],
+ "id": "3b78cf039bc54d1bbb99ab3a4be15ef1"
+ },
+ {
+ "id": "b8701374bf254de1beee8a2c9ecc6b33",
+ "endpoints": [
+ {
+ "region_id": "RegionOne",
+ "id": "f7407f330c8b4577b1d377d3fab9c2f8",
+ "interface": "public",
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:15491"
+ },
+ {
+ "url": "http://192.168.204.2:5491",
+ "region": "RegionOne",
+ "interface": "internal",
+ "id": "0b37ce31a32f4b6fa5e1aa0d6c20680f",
+ "region_id": "RegionOne"
+ },
+ {
+ "region_id": "RegionOne",
+ "id": "7b87ea72adf245e1991e9e0df29b7ea9",
+ "interface": "admin",
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:5491"
+ }
+ ],
+ "type": "patching",
+ "name": "patching"
+ },
+ {
+ "id": "0ec0923a58f04ffeb6fced3bbc5c0947",
+ "endpoints": [
+ {
+ "url": "http://128.224.180.14:8774/v2.1/fcca3cc49d5e42caae15459e27103efc",
+ "region": "RegionOne",
+ "id": "13168b12da17451fb39630de67db168f",
+ "region_id": "RegionOne",
+ "interface": "public"
+ },
+ {
+ "id": "22dd6a44209f42d986b82e3aa6535f82",
+ "interface": "internal",
+ "region_id": "RegionOne",
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8774/v2.1/fcca3cc49d5e42caae15459e27103efc"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8774/v2.1/fcca3cc49d5e42caae15459e27103efc",
+ "id": "552a991ae501492f841c1b6e2ff38fc5",
+ "region_id": "RegionOne",
+ "interface": "admin"
+ }
+ ],
+ "type": "compute",
+ "name": "nova"
+ },
+ {
+ "id": "50b219650f1049b097b3f14e8c70cdf8",
+ "endpoints": [
+ {
+ "interface": "public",
+ "id": "5a4276cd6e4d43e883cf8640d4e13f7d",
+ "region_id": "RegionOne",
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:8776/v3/fcca3cc49d5e42caae15459e27103efc"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8776/v3/fcca3cc49d5e42caae15459e27103efc",
+ "region_id": "RegionOne",
+ "id": "c796df3ca5a84fc18db5b43a55283953",
+ "interface": "internal"
+ },
+ {
+ "region_id": "RegionOne",
+ "id": "cf55c2b34d0049ba835a2e48b9ad0e2e",
+ "interface": "admin",
+ "url": "http://192.168.204.2:8776/v3/fcca3cc49d5e42caae15459e27103efc",
+ "region": "RegionOne"
+ }
+ ],
+ "type": "volumev3",
+ "name": "cinderv3"
+ }
+ ],
+}
+
+mock_auth_state = {
+ "body": {
+ "token": {
+ "is_domain": "false",
+ "expires_at": "2017-08-27T14:19:15.000000Z",
+ "issued_at": "2017-08-27T13:19:15.000000Z",
+ "roles": [
+ {
+ "id": "9fe2ff9ee4384b1894a90878d3e92bab",
+ "name": "_member_"
+ },
+ {
+ "id": "b86a7e02935844b899d3d326f83c1b1f",
+ "name": "admin"
+ },
+ {
+ "name": "heat_stack_owner",
+ "id": "7de502236e954c8282de32e773fc052e"
+ }
+ ],
+ "methods": [
+ "password"
+ ],
+ "catalog": mock_catalog_response['catalog'],
+ "project": {
+ "name": "admin",
+ "id": "fcca3cc49d5e42caae15459e27103efc",
+ "domain": {
+ "id": "default",
+ "name": "Default"
+ }
+ },
+ "user": {
+ "name": "admin",
+ "id": "9efb043c7629497a8028d7325ca1afb0",
+ "domain": {
+ "id": "default",
+ "name": "Default"
+ }
+ },
+ "audit_ids": [
+ "_ZWT10DtSZKRXIvIcxun7w"
+ ]
+ }
+ },
+ "auth_token": mock_token_id
+}
+
+
+class TestIdentityService(unittest.TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ @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')
+ def test_token(self, mock_update_token_cache, mock_get_auth_state,
+ mock_get_session, mock_get_vim_info):
+ '''
+ test API: get token
+ :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_session_get_response = {'status': 200}
+ mock_session = mock.Mock(name='mock_session', spec=mock_session_specs)
+ mock_session.get.return_value = mock_session_get_response
+
+ mock_get_vim_info.return_value = mock_viminfo
+ 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
+
+ # simulate client to make the request
+ data = {}
+ response = self.client.post(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/identity/v3/auth/tokens", data=data,
+ format='json')
+ self.failUnlessEqual(status.HTTP_201_CREATED, response.status_code)
+ context = response.json()
+
+ self.assertTrue(response['X-Subject-Token'] == mock_token_id)
+ self.assertTrue(context['token']['catalog'] is not None)
+
+ @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')
+ def test_tokensV2(self, mock_update_token_cache, mock_get_auth_state,
+ mock_get_session, mock_get_vim_info):
+ '''
+ test API: get token
+ :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_session_get_response = {'status': 200}
+ mock_session = mock.Mock(name='mock_session',
+ spec=mock_session_specs)
+ mock_session.get.return_value = mock_session_get_response
+
+ mock_get_vim_info.return_value = mock_info.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_info.MOCK_TOKEN_ID
+
+ # simulate client to make the request
+ data = {}
+ response = self.client.post(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/identity/v2.0/tokens",
+ data=data, format='json')
+ self.failUnlessEqual(status.HTTP_200_OK,
+ response.status_code)
+ context = response.json()
+
+ self.assertIsNotNone(context['access']['token'])
+ self.assertEqual(mock_info.MOCK_TOKEN_ID,
+ context['access']['token']["id"])
+ self.assertIsNotNone(context['access']['serviceCatalog'])
+
+ @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')
+ def test_token_with_tenantname(self, mock_update_token_cache, mock_get_auth_state,
+ mock_get_session, mock_get_vim_info):
+ '''
+ test API: get token
+ :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_session_get_response = {'status': 200}
+ mock_session = mock.Mock(name='mock_session',
+ spec=mock_session_specs)
+ mock_session.get.return_value = mock_session_get_response
+
+ mock_get_vim_info.return_value = mock_info.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_info.MOCK_TOKEN_ID
+
+ # simulate client to make the request
+ token_data = {
+ "auth": {
+ "identity": {
+ "methods": ["password"],
+ "password": {
+ "user": {
+ "name": "demo",
+ "domain": {"name": "Default"},
+ "password": "demo"
+ }
+ }
+ },
+ "scope": {
+ "project": {
+ "domain": {"name": "Default"},
+ "name": "Integration"
+ }
+ }
+ }
+ }
+
+ response = self.client.post(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/identity/v3/auth/tokens",
+ data=json.dumps(token_data), content_type='application/json')
+ self.failUnlessEqual(status.HTTP_201_CREATED,
+ response.status_code)
+ context = response.json()
+
+ self.assertEqual(mock_info.MOCK_TOKEN_ID,
+ response['X-Subject-Token'])
+ self.assertIsNotNone(context['token']['catalog'])
+
+ @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')
+ def test_tokensV2_with_tenantname(self, mock_update_token_cache, mock_get_auth_state,
+ mock_get_session, mock_get_vim_info):
+ '''
+ test API: get token
+ :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_session_get_response = {'status': 200}
+ mock_session = mock.Mock(name='mock_session',
+ spec=mock_session_specs)
+ mock_session.get.return_value = mock_session_get_response
+
+ mock_get_vim_info.return_value = mock_info.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_info.MOCK_TOKEN_ID
+
+ # simulate client to make the request
+ token_data = {
+ "auth": {
+ "tenantName": "Integration",
+ "passwordCredentials": {
+ "username": "demo",
+ "password": "demo"
+ }
+ }
+ }
+
+ response = self.client.post(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/identity/v2.0/tokens",
+ data=json.dumps(token_data), content_type='application/json')
+ self.failUnlessEqual(status.HTTP_200_OK,
+ response.status_code)
+ context = response.json()
+
+ self.assertIsNotNone(context['access']['token'])
+ self.assertEqual(mock_info.MOCK_TOKEN_ID,
+ context['access']['token']["id"])
+ self.assertIsNotNone(context['access']['serviceCatalog'])
+
+ @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')
+ def test_token_with_projectid(self, mock_update_token_cache, mock_get_auth_state,
+ mock_get_session, mock_get_vim_info):
+ '''
+ test API: get token
+ :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_session_get_response = {'status': 200}
+ mock_session = mock.Mock(name='mock_session',
+ spec=mock_session_specs)
+ mock_session.get.return_value = mock_session_get_response
+
+ mock_get_vim_info.return_value = mock_info.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_info.MOCK_TOKEN_ID
+
+ # simulate client to make the request
+ token_data = {
+ "auth": {
+ "identity": {
+ "methods": ["password"],
+ "password": {
+ "user": {
+ "name": "demo",
+ "password": "demo"
+ }
+ }
+ },
+ "scope": {
+ "project": {"id": "dd327af0542e47d7853e0470fe9ad625"}
+ }
+ }
+ }
+
+ response = self.client.post(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/identity/v3/auth/tokens",
+ data=json.dumps(token_data), content_type='application/json')
+ self.failUnlessEqual(status.HTTP_201_CREATED,
+ response.status_code)
+ context = response.json()
+
+ self.assertEqual(mock_info.MOCK_TOKEN_ID,
+ response['X-Subject-Token'])
+
+ self.assertIsNotNone(context['token']['catalog'])
diff --git a/starlingx/starlingx/proxy/tests/test_service_proxy.py b/starlingx/starlingx/proxy/tests/test_service_proxy.py
new file mode 100644
index 00000000..858fbeec
--- /dev/null
+++ b/starlingx/starlingx/proxy/tests/test_service_proxy.py
@@ -0,0 +1,852 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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 copy
+import json
+
+from django.test import Client
+import mock
+from rest_framework import status
+import unittest
+
+from newton_base.util import VimDriverUtils
+
+MOCK_VIM_INFO = {
+ "createTime": "2017-04-01 02:22:27",
+ "domain": "Default",
+ "name": "TiS_R4",
+ "password": "admin",
+ "tenant": "admin",
+ "type": "openstack",
+ "url": "http://128.224.180.14:5000/v3",
+ "userName": "admin",
+ "vendor": "Starlingx",
+ "version": "starlingx",
+ "vimId": "starlingx_RegionOne",
+ 'cloud_owner': 'starlingx',
+ 'cloud_region_id': 'RegionOne',
+ 'cloud_extra_info': '',
+ 'insecure': 'True',
+}
+
+MOCK_TOKEN_ID = "1a62b3971d774404a504c5d9a3e506e3"
+
+MOCK_CATALOG_RESPONSE = {
+ "catalog": [
+ {
+ "id": "99aefcc82a9246f98f8c281e61ffc754",
+ "endpoints": [
+ {
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:9696",
+ "id": "39583c1508ad4b71b380570a745ee10a",
+ "interface": "public",
+ "region_id": "RegionOne"
+ },
+ {
+ "url": "http://192.168.204.2:9696",
+ "region": "RegionOne",
+ "id": "37e8d07ba24e4b8f93490c9daaba06e2",
+ "interface": "internal",
+ "region_id": "RegionOne"
+ },
+ {
+ "interface": "admin",
+ "id": "7eee4ca98d444b1abb00a50d4b89373f",
+ "region_id": "RegionOne",
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:9696"
+ }
+ ],
+ "name": "neutron",
+ "type": "network"
+ },
+ {
+ "endpoints": [
+ {
+ "interface": "public",
+ "id": "10496738fa374295a4a88a63b81a1589",
+ "region_id": "RegionOne",
+ "url": "http://128.224.180.14:8777",
+ "region": "RegionOne"
+ },
+ {
+ "id": "02dcb8c0bd464c4489fa0a0c9f28571f",
+ "region_id": "RegionOne",
+ "interface": "internal",
+ "url": "http://192.168.204.2:8777",
+ "region": "RegionOne"
+ },
+ {
+ "region_id": "RegionOne",
+ "id": "8a73b0d3743b4e78b87614690f6e97fe",
+ "interface": "admin",
+ "url": "http://192.168.204.2:8777",
+ "region": "RegionOne"
+ }
+ ],
+ "id": "d131054da83f4c93833799747a0f4709",
+ "name": "ceilometer",
+ "type": "metering"
+ },
+ {
+ "type": "volumev2",
+ "name": "cinderv2",
+ "endpoints": [
+ {
+ "id": "35a67ad36f0447d19c9662babf7cf609",
+ "interface": "public",
+ "region_id": "RegionOne",
+ "url": "http://128.224.180.14:8776/v2/fcca3cc49d5e42caae15459e27103efc",
+ "region": "RegionOne"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8776/v2/fcca3cc49d5e42caae15459e27103efc",
+ "id": "c6ea42052268420fa2c8d351ee68c922",
+ "interface": "internal",
+ "region_id": "RegionOne"
+ },
+ {
+ "region_id": "RegionOne",
+ "id": "91cb24853dc3450d847b0c286a2e44ea",
+ "interface": "admin",
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8776/v2/fcca3cc49d5e42caae15459e27103efc"
+ }
+ ],
+ "id": "40440057102440739c30be10a66bc5d1"
+ },
+ {
+ "name": "heat",
+ "type": "orchestration",
+ "id": "35300cce88db4bd4bb5a72ffe3b88b00",
+ "endpoints": [
+ {
+ "id": "58999d7b4a94439089ecfb2aca2d7f6c",
+ "region_id": "RegionOne",
+ "interface": "public",
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:8004/v1/fcca3cc49d5e42caae15459e27103efc"
+ },
+ {
+ "url": "http://192.168.204.2:8004/v1/fcca3cc49d5e42caae15459e27103efc",
+ "region": "RegionOne",
+ "interface": "internal",
+ "id": "1e0ee1a2aef84802b921d422372a567e",
+ "region_id": "RegionOne"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8004/v1/fcca3cc49d5e42caae15459e27103efc",
+ "id": "17661bf4859741b8a43a461dedad1871",
+ "region_id": "RegionOne",
+ "interface": "admin"
+ }
+ ]
+ },
+ {
+ "id": "08dc6912aea64c01925012c8a6df250a",
+ "endpoints": [
+ {
+ "id": "02792c4eed77486083f9b2e52d7b94b0",
+ "region_id": "RegionOne",
+ "interface": "public",
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:5000/v3"
+ },
+ {
+ "id": "b6d5cad394b94309ae40d8de88059c5f",
+ "region_id": "RegionOne",
+ "interface": "internal",
+ "url": "http://192.168.204.2:5000/v3",
+ "region": "RegionOne"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:35357/v3",
+ "region_id": "RegionOne",
+ "id": "1f18e2b7c6a34493b86853b65917888e",
+ "interface": "admin"
+ }
+ ],
+ "type": "identity",
+ "name": "keystone"
+ },
+ {
+ "name": "vim",
+ "type": "nfv",
+ "endpoints": [
+ {
+ "url": "http://128.224.180.14:4545",
+ "region": "RegionOne",
+ "id": "b33e317345e4480ab0786e4960995ec9",
+ "interface": "public",
+ "region_id": "RegionOne"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:4545",
+ "interface": "internal",
+ "id": "03c85828d5bf432ab04831aa65ac9c52",
+ "region_id": "RegionOne"
+ },
+ {
+ "id": "067983abb061476cb53a9e23a740d98f",
+ "region_id": "RegionOne",
+ "interface": "admin",
+ "url": "http://192.168.204.2:4545",
+ "region": "RegionOne"
+ }
+ ],
+ "id": "01636c856fc84988b38b9117eb4a8021"
+ },
+ {
+ "name": "aodh",
+ "type": "alarming",
+ "id": "eb269151d0e44744a5b5449657bdc61c",
+ "endpoints": [
+ {
+ "id": "5bfc6c056e0244c493642eb82f6aaa11",
+ "region_id": "RegionOne",
+ "interface": "public",
+ "url": "http://128.224.180.14:8042",
+ "region": "RegionOne"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8042",
+ "region_id": "RegionOne",
+ "id": "ad69c7f76dce4089a195b9221ddbfb44",
+ "interface": "internal"
+ },
+ {
+ "interface": "admin",
+ "id": "3e8fcdfa7bcb40b0ae33c282adfcc9ff",
+ "region_id": "RegionOne",
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8042"
+ }
+ ]
+ },
+ {
+ "name": "sysinv",
+ "type": "platform",
+ "endpoints": [
+ {
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:6385/v1",
+ "interface": "public",
+ "id": "ba4ba8104590421b84672306c7e0e1f1",
+ "region_id": "RegionOne"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:6385/v1",
+ "interface": "internal",
+ "id": "a1cba34b163f496ab1acd6e9b51e39a2",
+ "region_id": "RegionOne"
+ },
+ {
+ "url": "http://192.168.204.2:6385/v1",
+ "region": "RegionOne",
+ "id": "7c171210a2c841a6a52a5713e316d6fc",
+ "interface": "admin",
+ "region_id": "RegionOne"
+ }
+ ],
+ "id": "256bbad671f946fea543e6bd71f98875"
+ },
+ {
+ "id": "e84665dcce814c05b4c5084964547534",
+ "endpoints": [
+ {
+ "url": "http://128.224.180.14:8000/v1/fcca3cc49d5e42caae15459e27103efc",
+ "region": "RegionOne",
+ "region_id": "RegionOne",
+ "id": "b2ed1a23dc6944bea129c20861e0286a",
+ "interface": "public"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8000/v1/fcca3cc49d5e42caae15459e27103efc",
+ "interface": "internal",
+ "id": "c4df7c6bc15646848eff35caf6ffea8e",
+ "region_id": "RegionOne"
+ },
+ {
+ "region_id": "RegionOne",
+ "id": "61b3dabb761443a89ab549f437c05ab0",
+ "interface": "admin",
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8000/v1/fcca3cc49d5e42caae15459e27103efc"
+ }
+ ],
+ "name": "heat-cfn",
+ "type": "cloudformation"
+ },
+ {
+ "id": "823024424a014981a3721229491c0b1a",
+ "endpoints": [
+ {
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:8776/v1/fcca3cc49d5e42caae15459e27103efc",
+ "region_id": "RegionOne",
+ "id": "4a52e4e54ff440789f9a797919c4a0f2",
+ "interface": "public"
+ },
+ {
+ "url": "http://192.168.204.2:8776/v1/fcca3cc49d5e42caae15459e27103efc",
+ "region": "RegionOne",
+ "id": "d4f9a84476524a39844f0fce63f1022e",
+ "region_id": "RegionOne",
+ "interface": "internal"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8776/v1/fcca3cc49d5e42caae15459e27103efc",
+ "interface": "admin",
+ "id": "81bf3810a8cc4697b68c6e93b5b8fe1f",
+ "region_id": "RegionOne"
+ }
+ ],
+ "type": "volume",
+ "name": "cinder"
+ },
+ {
+ "name": "glance",
+ "type": "image",
+ "endpoints": [
+ {
+ "id": "bd930aba961946cfb1401bada56d55e3",
+ "region_id": "RegionOne",
+ "interface": "public",
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:9292"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:9292",
+ "id": "c11da585f0b141b99d1e18bb9a607beb",
+ "region_id": "RegionOne",
+ "interface": "internal"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:9292",
+ "id": "31b26c625a6a4fc7910dc5935155996e",
+ "interface": "admin",
+ "region_id": "RegionOne"
+ }
+ ],
+ "id": "3b78cf039bc54d1bbb99ab3a4be15ef1"
+ },
+ {
+ "id": "b8701374bf254de1beee8a2c9ecc6b33",
+ "endpoints": [
+ {
+ "region_id": "RegionOne",
+ "id": "f7407f330c8b4577b1d377d3fab9c2f8",
+ "interface": "public",
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:15491"
+ },
+ {
+ "url": "http://192.168.204.2:5491",
+ "region": "RegionOne",
+ "interface": "internal",
+ "id": "0b37ce31a32f4b6fa5e1aa0d6c20680f",
+ "region_id": "RegionOne"
+ },
+ {
+ "region_id": "RegionOne",
+ "id": "7b87ea72adf245e1991e9e0df29b7ea9",
+ "interface": "admin",
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:5491"
+ }
+ ],
+ "type": "patching",
+ "name": "patching"
+ },
+ {
+ "id": "0ec0923a58f04ffeb6fced3bbc5c0947",
+ "endpoints": [
+ {
+ "url": "http://128.224.180.14:8774/v2.1/fcca3cc49d5e42caae15459e27103efc",
+ "region": "RegionOne",
+ "id": "13168b12da17451fb39630de67db168f",
+ "region_id": "RegionOne",
+ "interface": "public"
+ },
+ {
+ "id": "22dd6a44209f42d986b82e3aa6535f82",
+ "interface": "internal",
+ "region_id": "RegionOne",
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8774/v2.1/fcca3cc49d5e42caae15459e27103efc"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8774/v2.1/fcca3cc49d5e42caae15459e27103efc",
+ "id": "552a991ae501492f841c1b6e2ff38fc5",
+ "region_id": "RegionOne",
+ "interface": "admin"
+ }
+ ],
+ "type": "compute",
+ "name": "nova"
+ },
+ {
+ "id": "50b219650f1049b097b3f14e8c70cdf8",
+ "endpoints": [
+ {
+ "interface": "public",
+ "id": "5a4276cd6e4d43e883cf8640d4e13f7d",
+ "region_id": "RegionOne",
+ "region": "RegionOne",
+ "url": "http://128.224.180.14:8776/v3/fcca3cc49d5e42caae15459e27103efc"
+ },
+ {
+ "region": "RegionOne",
+ "url": "http://192.168.204.2:8776/v3/fcca3cc49d5e42caae15459e27103efc",
+ "region_id": "RegionOne",
+ "id": "c796df3ca5a84fc18db5b43a55283953",
+ "interface": "internal"
+ },
+ {
+ "region_id": "RegionOne",
+ "id": "cf55c2b34d0049ba835a2e48b9ad0e2e",
+ "interface": "admin",
+ "url": "http://192.168.204.2:8776/v3/fcca3cc49d5e42caae15459e27103efc",
+ "region": "RegionOne"
+ }
+ ],
+ "type": "volumev3",
+ "name": "cinderv3"
+ }
+ ]
+}
+
+MOCK_AUTH_STATE = {
+ "body": {
+ "token": {
+ "is_domain": "false",
+ "expires_at": "2017-08-27T14:19:15.000000Z",
+ "issued_at": "2017-08-27T13:19:15.000000Z",
+ "roles": [
+ {
+ "id": "9fe2ff9ee4384b1894a90878d3e92bab",
+ "name": "_member_"
+ },
+ {
+ "id": "b86a7e02935844b899d3d326f83c1b1f",
+ "name": "admin"
+ },
+ {
+ "name": "heat_stack_owner",
+ "id": "7de502236e954c8282de32e773fc052e"
+ }
+ ],
+ "methods": [
+ "password"
+ ],
+ "catalog": MOCK_CATALOG_RESPONSE['catalog'],
+ "project": {
+ "name": "admin",
+ "id": "fcca3cc49d5e42caae15459e27103efc",
+ "domain": {
+ "id": "default",
+ "name": "Default"
+ }
+ },
+ "user": {
+ "name": "admin",
+ "id": "9efb043c7629497a8028d7325ca1afb0",
+ "domain": {
+ "id": "default",
+ "name": "Default"
+ }
+ },
+ "audit_ids": [
+ "_ZWT10DtSZKRXIvIcxun7w"
+ ]
+ }
+ },
+ "auth_token": MOCK_TOKEN_ID
+}
+
+MOCK_INTERNAL_METADATA_CATALOG = {
+ "identity": {
+ "proxy_prefix": "http://172.16.77.20:9003/api/multicloud-starlingx/v0/starlingx_RegionOne/identity",
+ "prefix": "http://128.224.180.14:5000",
+ "suffix": "v3"
+ },
+ "patching": {
+ "proxy_prefix": "http://172.16.77.20:9003/api/multicloud-starlingx/v0/starlingx_RegionOne/patching",
+ "suffix": "",
+ "prefix": "http://128.224.180.14:15491"
+ },
+ "orchestration": {
+ "suffix": "v1/fcca3cc49d5e42caae15459e27103efc",
+ "prefix": "http://128.224.180.14:8004",
+ "proxy_prefix": "http://172.16.77.20:9003/api/multicloud-starlingx/v0/starlingx_RegionOne/orchestration"
+ },
+ "volume": {
+ "prefix": "http://128.224.180.14:8776",
+ "suffix": "v1/fcca3cc49d5e42caae15459e27103efc",
+ "proxy_prefix": "http://172.16.77.20:9003/api/multicloud-starlingx/v0/starlingx_RegionOne/volume"
+ },
+ "metering": {
+ "suffix": "",
+ "prefix": "http://128.224.180.14:8777",
+ "proxy_prefix": "http://172.16.77.20:9003/api/multicloud-starlingx/v0/starlingx_RegionOne/metering"
+ },
+ "volumev3": {
+ "prefix": "http://128.224.180.14:8776",
+ "suffix": "v3/fcca3cc49d5e42caae15459e27103efc",
+ "proxy_prefix": "http://172.16.77.20:9003/api/multicloud-starlingx/v0/starlingx_RegionOne/volumev3"
+ },
+ "compute": {
+ "suffix": "v2.1/fcca3cc49d5e42caae15459e27103efc",
+ "prefix": "http://128.224.180.14:8774",
+ "proxy_prefix": "http://172.16.77.20:9003/api/multicloud-starlingx/v0/starlingx_RegionOne/compute"
+ },
+ "platform": {
+ "prefix": "http://128.224.180.14:6385",
+ "suffix": "v1",
+ "proxy_prefix": "http://172.16.77.20:9003/api/multicloud-starlingx/v0/starlingx_RegionOne/platform"
+ },
+ "nfv": {
+ "proxy_prefix": "http://172.16.77.20:9003/api/multicloud-starlingx/v0/starlingx_RegionOne/nfv",
+ "prefix": "http://128.224.180.14:4545",
+ "suffix": ""
+ },
+ "volumev2": {
+ "proxy_prefix": "http://172.16.77.20:9003/api/multicloud-starlingx/v0/starlingx_RegionOne/volumev2",
+ "suffix": "v2/fcca3cc49d5e42caae15459e27103efc",
+ "prefix": "http://128.224.180.14:8776"
+ },
+ "image": {
+ "suffix": "",
+ "prefix": "http://128.224.180.14:9292",
+ "proxy_prefix": "http://172.16.77.20:9003/api/multicloud-starlingx/v0/starlingx_RegionOne/image"
+ },
+ "network": {
+ "proxy_prefix": "http://172.16.77.20:9003/api/multicloud-starlingx/v0/starlingx_RegionOne/network",
+ "prefix": "http://128.224.180.14:9696",
+ "suffix": ""
+ },
+ "alarming": {
+ "suffix": "",
+ "prefix": "http://128.224.180.14:8042",
+ "proxy_prefix": "http://172.16.77.20:9003/api/multicloud-starlingx/v0/starlingx_RegionOne/alarming"
+ },
+ "cloudformation": {
+ "proxy_prefix": "http://172.16.77.20:9003/api/multicloud-starlingx/v0/starlingx_RegionOne/cloudformation",
+ "prefix": "http://128.224.180.14:8000",
+ "suffix": "v1/fcca3cc49d5e42caae15459e27103efc"
+ }
+}
+
+MOCK_GET_SERVERS_RESPONSE = {
+ "servers": [
+ {
+ "links": [
+ {
+ "href": "http://128.224.180.14:8774/v2.1/fcca3cc49d5e42caae15459e27103efc/servers/b2581b5c-7c56-4564-819d-fe7a2ce9c261",
+ "rel": "self"
+ },
+ {
+ "href": "http://128.224.180.14:8774/fcca3cc49d5e42caae15459e27103efc/servers/b2581b5c-7c56-4564-819d-fe7a2ce9c261",
+ "rel": "bookmark"
+ }
+ ],
+ "id": "b2581b5c-7c56-4564-819d-fe7a2ce9c261",
+ "name": "t1"
+ },
+ {
+ "id": "ff7b51ca-a272-45f4-b54c-e40b8099e67d",
+ "name": "t2",
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://128.224.180.14:8774/v2.1/fcca3cc49d5e42caae15459e27103efc/servers/ff7b51ca-a272-45f4-b54c-e40b8099e67d"
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://128.224.180.14:8774/fcca3cc49d5e42caae15459e27103efc/servers/ff7b51ca-a272-45f4-b54c-e40b8099e67d"
+ }
+ ]
+ }
+ ]
+}
+
+MOCK_POST_SERVER_REQUEST = {
+ "server": {
+ "accessIPv4": "1.2.3.4",
+ "accessIPv6": "80fe::",
+ "name": "new-server-test",
+ "imageRef": "70a599e0-31e7-49b7-b260-868f441e862b",
+ "flavorRef": "1",
+ "availability_zone": "nova",
+ "OS-DCF:diskConfig": "AUTO",
+ "metadata": {
+ "My Server Name": "Apache1"
+ },
+ "personality": [
+ {
+ "path": "/etc/banner.txt",
+ "contents": "ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBp dCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5k IGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVs c2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4g QnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRo ZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlv dSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vy c2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6 b25zLiINCg0KLVJpY2hhcmQgQmFjaA=="
+ }
+ ],
+ "security_groups": [
+ {
+ "name": "default"
+ }
+ ],
+ "user_data": "IyEvYmluL2Jhc2gKL2Jpbi9zdQplY2hvICJJIGFtIGluIHlvdSEiCg=="
+ },
+ "OS-SCH-HNT:scheduler_hints": {
+ "same_host": "48e6a9f6-30af-47e0-bc04-acaed113bb4e"
+ }
+}
+
+MOCK_POST_SERVER_RESPONSE = {
+ "server": {
+ "OS-DCF:diskConfig": "AUTO",
+ "adminPass": "6NpUwoz2QDRN",
+ "id": "f5dc173b-6804-445a-a6d8-c705dad5b5eb",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v2/6f70656e737461636b20342065766572/servers/f5dc173b-6804-445a-a6d8-c705dad5b5eb",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/f5dc173b-6804-445a-a6d8-c705dad5b5eb",
+ "rel": "bookmark"
+ }
+ ],
+ "security_groups": [
+ {
+ "name": "default"
+ }
+ ]
+ }
+}
+
+MOCK_PATCH_IMAGE_REQUEST = [
+ {
+ "op": "replace",
+ "path": "/name",
+ "value": "Fedora 17"
+ },
+ {
+ "op": "replace",
+ "path": "/tags",
+ "value": [
+ "fedora",
+ "beefy"
+ ]
+ }
+]
+
+MOCK_PATCH_IMAGE_RESPONSE = {
+ "checksum": "710544e7f0c828b42f51207342622d33",
+ "container_format": "ovf",
+ "created_at": "2016-06-29T16:13:07Z",
+ "disk_format": "vhd",
+ "file": "/v2/images/2b61ed2b-f800-4da0-99ff-396b742b8646/file",
+ "id": "2b61ed2b-f800-4da0-99ff-396b742b8646",
+ "min_disk": 20,
+ "min_ram": 512,
+ "name": "Fedora 17",
+ "owner": "02a7fb2dd4ef434c8a628c511dcbbeb6",
+ "protected": "false",
+ "schema": "/v2/schemas/image",
+ "self": "/v2/images/2b61ed2b-f800-4da0-99ff-396b742b8646",
+ "size": 21909,
+ "status": "active",
+ "tags": [
+ "beefy",
+ "fedora"
+ ],
+ "updated_at": "2016-07-25T14:48:18Z",
+ "virtual_size": "",
+ "visibility": "private"
+}
+
+
+class MockResponse(object):
+ status_code = 200
+ content = ''
+
+ def json(self):
+ pass
+
+
+class TestServiceProxy(unittest.TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_token_cache')
+ @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=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.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_token_cache.return_value = (json.dumps(MOCK_AUTH_STATE), json.dumps(MOCK_INTERNAL_METADATA_CATALOG))
+ response = self.client.head(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/compute/v2.1/fcca3cc49d5e42caae15459e27103efc/servers",
+ {}, HTTP_X_AUTH_TOKEN=MOCK_TOKEN_ID)
+ self.assertEquals(status.HTTP_200_OK, response.status_code)
+
+ def test_unauthorized_access(self):
+ response = self.client.get(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/compute/v2.1/fcca3cc49d5e42caae15459e27103efc/servers")
+ self.assertEquals(status.HTTP_403_FORBIDDEN, response.status_code)
+
+ @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-starlingx/v0/starlingx_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_part1 = "/api/multicloud-starlingx/v0/starlingx_RegionOne/"
+ url_part3 = "/v2.1/fcca3cc49d5e42caae15459e27103efc/servers"
+ url = (url_part1 + servicetype + url_part3)
+ 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] = 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)
+
+ 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_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: 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", "post", "put", "patch", "delete"]
+
+ 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
+ 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))
+
+ # Create resource
+ response = self.client.post(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/compute/v2.1/fcca3cc49d5e42caae15459e27103efc/servers",
+ MOCK_POST_SERVER_REQUEST, HTTP_X_AUTH_TOKEN=MOCK_TOKEN_ID)
+
+ 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'])
+
+ # Retrieve resource
+ response = self.client.get(
+ "/api/multicloud-starlingx/v0/starlingx_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()
+
+ self.assertEquals(MOCK_TOKEN_ID, response['X-Subject-Token'])
+ self.assertIsNotNone(context['servers'])
+
+ # Update resource
+ response = self.client.get(
+ "/api/multicloud-starlingx/v0/starlingx_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()
+
+ 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-starlingx/v0/starlingx_RegionOne/compute/v2.1/fcca3cc49d5e42caae15459e27103efc/servers/324dfb7d-f4a9-419a-9a19-237df04b443b",
+ HTTP_X_AUTH_TOKEN=MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_204_NO_CONTENT, response.status_code)
+ self.assertEquals(MOCK_TOKEN_ID, response['X-Subject-Token'])
diff --git a/starlingx/starlingx/proxy/urls.py b/starlingx/starlingx/proxy/urls.py
new file mode 100644
index 00000000..7fee0927
--- /dev/null
+++ b/starlingx/starlingx/proxy/urls.py
@@ -0,0 +1,41 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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.conf.urls import url
+from rest_framework.urlpatterns import format_suffix_patterns
+
+from starlingx.proxy.views import identityV3
+from starlingx.proxy.views import services
+from newton_base.proxy import dnsaasdelegate
+
+urlpatterns = [
+ # url(r'^identity/v2)$',
+ # identityV2.Tokens.as_view()),
+ url(r'^identity/v3/auth/tokens/?$',
+ identityV3.Tokens.as_view()),
+ url(r'^identity/v3/?$',
+ 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/?$',
+ services.GetTenants.as_view()),
+ url(r'dns-delegate/(?P<requri>[0-9a-zA-Z./_-]*)$',
+ dnsaasdelegate.DnsaasDelegate.as_view()),
+ url(r'^(?P<servicetype>[0-9a-zA-Z_-]{,18})/(?P<requri>[0-9a-zA-Z./_-]*)$',
+ services.Services.as_view()),
+]
+
+urlpatterns = format_suffix_patterns(urlpatterns)
diff --git a/starlingx/starlingx/proxy/urlsV1.py b/starlingx/starlingx/proxy/urlsV1.py
new file mode 100644
index 00000000..0009b7fb
--- /dev/null
+++ b/starlingx/starlingx/proxy/urlsV1.py
@@ -0,0 +1,39 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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.conf.urls import url
+from rest_framework.urlpatterns import format_suffix_patterns
+
+from starlingx.proxy.views import identityV3
+from starlingx.proxy.views import services
+from newton_base.proxy import dnsaasdelegate
+
+urlpatterns = [
+ url(r'^identity/v3/auth/tokens/?$',
+ identityV3.APIv1Tokens.as_view()),
+ url(r'^identity/v3/?$',
+ identityV3.APIv1Tokens.as_view()),
+ url(r'^identity/v2.0/?$',
+ identityV3.APIv1TokensV2.as_view()),
+ url(r'^identity/v2.0/tokens/?$',
+ identityV3.APIv1TokensV2.as_view()),
+ url(r'^identity/v2.0/tenants/?$',
+ services.APIv1GetTenants.as_view()),
+ url(r'dns-delegate/(?P<requri>[0-9a-zA-Z./_-]*)$',
+ dnsaasdelegate.APIv1DnsaasDelegate.as_view()),
+ url(r'^(?P<servicetype>[0-9a-zA-Z_-]{,18})/(?P<requri>[0-9a-zA-Z./_-]*)$',
+ services.APIv1Services.as_view()),
+]
+
+urlpatterns = format_suffix_patterns(urlpatterns)
diff --git a/starlingx/starlingx/proxy/views/__init__.py b/starlingx/starlingx/proxy/views/__init__.py
new file mode 100644
index 00000000..81362a2b
--- /dev/null
+++ b/starlingx/starlingx/proxy/views/__init__.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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.
diff --git a/starlingx/starlingx/proxy/views/identityV3.py b/starlingx/starlingx/proxy/views/identityV3.py
new file mode 100644
index 00000000..397a00c1
--- /dev/null
+++ b/starlingx/starlingx/proxy/views/identityV3.py
@@ -0,0 +1,84 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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
+
+from django.conf import settings
+from newton_base.proxy import identityV3 as newton_identityV3
+from common.msapi import extsys
+
+logger = logging.getLogger(__name__)
+
+
+# DEBUG=True
+
+
+class Tokens(newton_identityV3.Tokens):
+ def __init__(self):
+ super(Tokens, self).__init__()
+ self.proxy_prefix = settings.MULTICLOUD_PREFIX
+ # self._logger = logger
+
+
+class TokensV2(newton_identityV3.TokensV2):
+ def __init__(self):
+ super(TokensV2, self).__init__()
+ self.proxy_prefix = settings.MULTICLOUD_PREFIX
+ # self._logger = logger
+
+
+class APIv1Tokens(Tokens):
+ def __init__(self):
+ super(APIv1Tokens, self).__init__()
+ self.proxy_prefix = settings.MULTICLOUD_API_V1_PREFIX
+ # self._logger = logger
+
+ def get(self, request, cloud_owner="", cloud_region_id=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+ # self._logger.debug("META> %s" % request.META)
+ # self._logger.debug("data> %s" % request.data)
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1Tokens, self).get(request, vimid)
+
+ def post(self, request, cloud_owner="", cloud_region_id=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+ # self._logger.debug("META> %s" % request.META)
+ # self._logger.debug("data> %s" % request.data)
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1Tokens, self).post(request, vimid)
+
+
+class APIv1TokensV2(TokensV2):
+ def __init__(self):
+ super(APIv1TokensV2, self).__init__()
+ self.proxy_prefix = settings.MULTICLOUD_API_V1_PREFIX
+ # self._logger = logger
+
+ def get(self, request, cloud_owner="", cloud_region_id=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+ # self._logger.debug("META> %s" % request.META)
+ # self._logger.debug("data> %s" % request.data)
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1TokensV2, self).get(request, vimid)
+
+ def post(self, request, cloud_owner="", cloud_region_id=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+ # self._logger.debug("META> %s" % request.META)
+ # self._logger.debug("data> %s" % request.data)
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1TokensV2, self).post(request, vimid)
diff --git a/starlingx/starlingx/proxy/views/services.py b/starlingx/starlingx/proxy/views/services.py
new file mode 100644
index 00000000..d5bfd527
--- /dev/null
+++ b/starlingx/starlingx/proxy/views/services.py
@@ -0,0 +1,146 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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
+
+# from rest_framework import status
+
+# from django.conf import settings
+from newton_base.proxy import services as newton_services
+from common.msapi import extsys
+
+logger = logging.getLogger(__name__)
+
+# DEBUG=True
+
+
+class Services(newton_services.Services):
+
+ def __init__(self):
+ super(Services, self).__init__()
+ # self._logger = logger
+
+
+class GetTenants(newton_services.GetTenants):
+ '''
+ Backward compatible API for /v2.0/tenants
+ '''
+
+ def __init__(self):
+ super(GetTenants, self).__init__()
+ # self._logger = logger
+
+ def get(self, request, vimid="", servicetype="identity", requri='v3/projects'):
+ self._logger.info("vimid: %s" % (vimid))
+ self._logger.debug("with servicetype, requri> %s,%s" % (servicetype, requri))
+
+ return super(GetTenants, self).get(request, vimid, servicetype, requri)
+
+
+class APIv1Services(Services):
+
+ def __init__(self):
+ super(APIv1Services, self).__init__()
+ # self._logger = logger
+
+ def head(self, request, cloud_owner="", cloud_region_id="", servicetype="", requri=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+ # self._logger.info("servicetype, requri> %s,%s" % (servicetype, requri))
+ # self._logger.debug("META, data> %s , %s" % (request.META, request.data))
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1Services, self).head(request, vimid, servicetype, requri)
+
+ def get(self, request, cloud_owner="", cloud_region_id="", servicetype="", requri=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1Services, self).get(request, vimid, servicetype, requri)
+
+ def post(self, request, cloud_owner="", cloud_region_id="", servicetype="", requri=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1Services, self).post(request, vimid, servicetype, requri)
+
+ def put(self, request, cloud_owner="", cloud_region_id="", servicetype="", requri=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1Services, self).put(request, vimid, servicetype, requri)
+
+ def patch(self, request, cloud_owner="", cloud_region_id="", servicetype="", requri=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1Services, self).patch(request, vimid, servicetype, requri)
+
+ def delete(self, request, cloud_owner="", cloud_region_id="", servicetype="", requri=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1Services, self).delete(request, vimid, servicetype, requri)
+
+
+class APIv1GetTenants(GetTenants):
+ '''
+ Backward compatible API for /v2.0/tenants
+ '''
+
+ def __init__(self):
+ super(APIv1GetTenants, self).__init__()
+ # self._logger = logger
+
+ def head(self, request, cloud_owner="", cloud_region_id="", servicetype="identity", requri=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+ # self._logger.info("servicetype, requri> %s,%s" % (servicetype, requri))
+ # self._logger.debug("META, data> %s , %s" % (request.META, request.data))
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1GetTenants, self).head(request, vimid, servicetype, requri)
+
+ def get(self, request, cloud_owner="", cloud_region_id="", servicetype="identity", requri='v3/projects'):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+ # self._logger.debug("with servicetype, requri> %s,%s" % (servicetype, requri))
+ # self._logger.debug("with META> %s" % request.META)
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1GetTenants, self).get(request, vimid, servicetype, requri)
+
+ def post(self, request, cloud_owner="", cloud_region_id="", servicetype="identity", requri=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+ # self._logger.debug("with servicetype, requri> %s,%s" % (servicetype, requri))
+ # self._logger.debug("with META> %s" % request.META)
+ # self._logger.debug("with data> %s" % request.data)
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1GetTenants, self).post(request, vimid, servicetype, requri)
+
+ def put(self, request, cloud_owner="", cloud_region_id="", servicetype="identity", requri=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1GetTenants, self).put(request, vimid, servicetype, requri)
+
+ def patch(self, request, cloud_owner="", cloud_region_id="", servicetype="identity", requri=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1GetTenants, self).patch(request, vimid, servicetype, requri)
+
+ def delete(self, request, cloud_owner="", cloud_region_id="", servicetype="identity", requri=""):
+ self._logger.info("cloud_owner,cloud_region_id: %s,%s" % (cloud_owner, cloud_region_id))
+
+ vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id)
+ return super(APIv1GetTenants, self).delete(request, vimid, servicetype, requri)
diff --git a/starlingx/starlingx/registration/__init__.py b/starlingx/starlingx/registration/__init__.py
new file mode 100644
index 00000000..81362a2b
--- /dev/null
+++ b/starlingx/starlingx/registration/__init__.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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.
diff --git a/starlingx/starlingx/registration/tests/__init__.py b/starlingx/starlingx/registration/tests/__init__.py
new file mode 100644
index 00000000..81362a2b
--- /dev/null
+++ b/starlingx/starlingx/registration/tests/__init__.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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.
diff --git a/starlingx/starlingx/registration/tests/test_registration.py b/starlingx/starlingx/registration/tests/test_registration.py
new file mode 100644
index 00000000..99f5ffc5
--- /dev/null
+++ b/starlingx/starlingx/registration/tests/test_registration.py
@@ -0,0 +1,485 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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 mock
+
+from rest_framework import status
+
+from common.utils import restcall
+from newton_base.tests import mock_info
+from newton_base.tests import test_base
+from newton_base.util import VimDriverUtils
+
+MOCK_GET_TENANT_RESPONSE = {
+ "projects": [
+ {"id": "1", "name": "project"},
+ {"id": "2", "name": "project2"},
+ ]
+}
+
+MOCK_GET_FLAVOR_RESPONSE = {
+ "flavors": [
+ {
+ "id": "1", "name": "micro", "vcpus": 1, "ram": "1MB",
+ "disk": "1G", "OS-FLV-EXT-DATA:ephemeral": False,
+ "swap": True, "os-flavor-access:is_public": True,
+ "OS-FLV-DISABLED:disabled": True, "link": [{"href": 1}]
+ },
+ {
+ "id": "2", "name": "mini", "vcpus": 2, "ram": "2MB",
+ "disk": "2G", "OS-FLV-EXT-DATA:ephemeral": True,
+ "swap": False, "os-flavor-access:is_public": True,
+ "OS-FLV-DISABLED:disabled": True
+ },
+ ]
+}
+
+MOCK_GET_IMAGE_RESPONSE = {
+ "images": [
+ {
+ "id": "1", "name": "cirros", "self": "test",
+ "os_distro": "CirrOS", "os_version": "0.3",
+ "application": "test", "application_vendor": "ONAP",
+ "application_version": 1, "architecture": "x86",
+ "schema": None
+ },
+ {
+ "id": "2", "name": "cirros", "self": "test",
+ "os_distro": "CirrOS", "os_version": "0.3",
+ "application": "test", "application_vendor": "ONAP",
+ "application_version": 1, "architecture": "x86",
+ "schema": "req_resource"
+ },
+ ]
+}
+
+MOCK_GET_AZ_RESPONSE = {
+ "availabilityZoneInfo": [
+ {
+ "zoneName": "production",
+ "zoneState": {"available": True},
+ "hosts": {"hypervisor": "kvm"}
+ },
+ {
+ "zoneName": "testing",
+ },
+ ]
+}
+
+MOCK_HYPERVISOR_RESPONSE = {
+ "hypervisors": [
+ {"hypervisor_type": "kvm"}
+ ]
+}
+
+MOCK_GET_SNAPSHOT_RESPONSE = {
+ "snapshots": [
+ {
+ "id": 1, "name": "test", "metadata":
+ {
+ "architecture": "x86", "os-distro": "clearlinux",
+ "os-version": "276", "vendor": "intel", "version": 3,
+ "selflink": "test", "prev-snapshot-id": "test-id"
+ }
+ },
+ {"id": 2, "name": "test2"}
+ ]
+}
+
+MOCK_GET_HYPERVISOR_RESPONSE = {
+ "hypervisors": [
+ {
+ "hypervisor_hostname": "testing", "state": "ACTIVE",
+ "id": 1, "local_gb": 256, "memory_mb": 1024,
+ "hypervisor_links": "link", "host_ip": "127.0.0.1",
+ "cpu_info": u'{"topology": {"cores": 8, "threads": 16, "sockets": 4}}'
+ },
+ {
+ "hypervisor_hostname": "testing2", "state": "XXX",
+ "id": 1, "local_gb": 256, "memory_mb": 1024,
+ "hypervisor_links": "link", "host_ip": "127.0.0.1",
+ }
+ ]
+}
+
+TEST_REGISTER_ENDPOINT_REQUEST = {
+ "defaultTenant": "project1"
+}
+
+# HPA UT1: CPU-PINNING
+MOCK_GET_HPA_FLAVOR_LIST1_RESPONSE = {
+ "flavors": [
+ {
+ "id": "1", "name": "micro", "vcpus": 1, "ram": "1024",
+ "disk": "1G", "OS-FLV-EXT-DATA:ephemeral": False,
+ "swap": True, "os-flavor-access:is_public": True,
+ "OS-FLV-DISABLED:disabled": True, "link": [{"href": 1}]
+ },
+ {
+ "id": "2", "name": "onap.mini", "vcpus": 2, "ram": "2048",
+ "disk": "2G", "OS-FLV-EXT-DATA:ephemeral": True,
+ "swap": False, "os-flavor-access:is_public": True,
+ "OS-FLV-DISABLED:disabled": True
+ },
+ ]
+}
+
+MOCK_GET_HPA_FLAVOR_onap_mini_EXTRA_SPECS_RESPONSE = {
+ "extra_specs": {
+ "aggregate_instance_extra_specs:storage": "local_image",
+ "capabilities:cpu_info:model": "Haswell",
+ "hw:cpu_policy": "dedicated",
+ "hw:cpu_thread_policy": "prefer"
+ }
+}
+
+# HPA UT2: CPU-Topology
+MOCK_GET_HPA_FLAVOR_onap_mini_EXTRA_SPECS2_RESPONSE = {
+ "extra_specs": {
+ "aggregate_instance_extra_specs:storage": "local_image",
+ "capabilities:cpu_info:model": "Haswell",
+ "hw:cpu_sockets": "2",
+ "hw:cpu_cores": "4",
+ "hw:cpu_threads": "16"
+ }
+}
+
+# HPA UT3: mem_page_size
+MOCK_GET_HPA_FLAVOR_onap_mini_EXTRA_SPECS3_RESPONSE = {
+ "extra_specs": {
+ "aggregate_instance_extra_specs:storage": "local_image",
+ "capabilities:cpu_info:model": "Haswell",
+ "hw:mem_page_size": "large"
+ }
+}
+
+# HPA UT4: numa_nodes
+MOCK_GET_HPA_FLAVOR_onap_mini_EXTRA_SPECS4_RESPONSE = {
+ "extra_specs": {
+ "aggregate_instance_extra_specs:storage": "local_image",
+ "capabilities:cpu_info:model": "Haswell",
+ "hw:numa_nodes": "2",
+ "hw:numa_cpus.0": "0,1",
+ "hw:numa_cpus.1": "2,3,4,5",
+ "hw:numa_mem.0": "2048",
+ "hw:numa_mem.1": "2048"
+ }
+}
+
+# HPA UT5: instruction set
+MOCK_GET_HPA_FLAVOR_onap_mini_EXTRA_SPECS5_RESPONSE = {
+ "extra_specs": {
+ "aggregate_instance_extra_specs:storage": "local_image",
+ "capabilities:cpu_info:model": "Haswell",
+ "hw:capabilities:cpu_info:features": "avx,acpi"
+ }
+}
+
+# HPA UT6: pci passthrough
+MOCK_GET_HPA_FLAVOR_onap_mini_EXTRA_SPECS6_RESPONSE = {
+ "extra_specs": {
+ "aggregate_instance_extra_specs:storage": "local_image",
+ "capabilities:cpu_info:model": "Haswell",
+ "pci_passthrough:alias": "sriov-vf-intel-8086-15b3:4"
+ }
+}
+
+# HPA UT7: sriov-nic
+MOCK_GET_HPA_FLAVOR_onap_mini_EXTRA_SPECS7_RESPONSE = {
+ "extra_specs": {
+ "aggregate_instance_extra_specs:sriov_nic": "sriov-nic-intel-8086-15b3-physnet-1:1",
+ "capabilities:cpu_info:model": "Haswell"
+ }
+}
+
+
+class TestRegistration(test_base.TestRequest):
+ def setUp(self):
+ super(TestRegistration, self).setUp()
+ self.req_to_aai_backup = restcall.req_to_aai
+
+ def tearDown(self):
+ super(TestRegistration, self).tearDown()
+ restcall.req_to_aai = self.req_to_aai_backup
+
+ def _get_mock_response(self, return_value=None):
+ mock_response = mock.Mock(spec=test_base.MockResponse)
+ mock_response.status_code = status.HTTP_200_OK
+ mock_response.json.return_value = return_value
+ return mock_response
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_register_endpoint_successfully(
+ self, mock_get_vim_info, mock_get_session):
+ restcall.req_to_aai = mock.Mock()
+ restcall.req_to_aai.return_value = (0, {}, status.HTTP_200_OK)
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_RESPONSE),
+ self._get_mock_response(MOCK_GET_FLAVOR_RESPONSE),
+ self._get_mock_response(MOCK_GET_IMAGE_RESPONSE),
+ self._get_mock_response(),
+ self._get_mock_response(MOCK_GET_AZ_RESPONSE),
+ self._get_mock_response(MOCK_HYPERVISOR_RESPONSE),
+ self._get_mock_response(MOCK_GET_SNAPSHOT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HYPERVISOR_RESPONSE)
+ ]
+ })
+
+ response = self.client.post((
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/"
+ "registry"), TEST_REGISTER_ENDPOINT_REQUEST,
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_202_ACCEPTED,
+ response.status_code)
+
+ # @mock.patch.object(VimDriverUtils, 'delete_vim_info')
+ # def test_unregister_endpoint_successfully(
+ # self, mock_delete_vim_info):
+ # mock_delete_vim_info.return_value = 0
+
+ # response = self.client.delete((
+ # "/api/multicloud-starlingx/v0/starlingx_RegionOne/"
+ # "registry"), "{}", content_type="application/json",
+ # HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ # self.assertEquals(status.HTTP_202_ACCEPTED,
+ # response.status_code)
+
+ @mock.patch.object(VimDriverUtils, 'delete_vim_info')
+ def test_fail_unregister_endpoint(
+ self, mock_delete_vim_info):
+ mock_delete_vim_info.return_value = 1
+
+ response = self.client.delete((
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/"
+ "registry"), "{}", content_type="application/json",
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_500_INTERNAL_SERVER_ERROR,
+ response.status_code)
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_register_hpa_cpupinning_successfully(
+ self, mock_get_vim_info, mock_get_session):
+ restcall.req_to_aai = mock.Mock()
+ restcall.req_to_aai.return_value = (0, {}, status.HTTP_200_OK)
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HPA_FLAVOR_LIST1_RESPONSE),
+ self._get_mock_response(MOCK_GET_HPA_FLAVOR_onap_mini_EXTRA_SPECS_RESPONSE),
+ self._get_mock_response(MOCK_GET_IMAGE_RESPONSE),
+ self._get_mock_response(),
+ self._get_mock_response(MOCK_GET_AZ_RESPONSE),
+ self._get_mock_response(MOCK_HYPERVISOR_RESPONSE),
+ self._get_mock_response(MOCK_GET_SNAPSHOT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HYPERVISOR_RESPONSE)
+ ]
+ })
+
+ response = self.client.post((
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/"
+ "registry"), TEST_REGISTER_ENDPOINT_REQUEST,
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_202_ACCEPTED,
+ response.status_code)
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_register_hpa_topo_successfully(
+ self, mock_get_vim_info, mock_get_session):
+ restcall.req_to_aai = mock.Mock()
+ restcall.req_to_aai.return_value = (0, {}, status.HTTP_200_OK)
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HPA_FLAVOR_LIST1_RESPONSE),
+ self._get_mock_response(MOCK_GET_HPA_FLAVOR_onap_mini_EXTRA_SPECS2_RESPONSE),
+ self._get_mock_response(MOCK_GET_IMAGE_RESPONSE),
+ self._get_mock_response(),
+ self._get_mock_response(MOCK_GET_AZ_RESPONSE),
+ self._get_mock_response(MOCK_HYPERVISOR_RESPONSE),
+ self._get_mock_response(MOCK_GET_SNAPSHOT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HYPERVISOR_RESPONSE)
+ ]
+ })
+
+ response = self.client.post((
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/"
+ "registry"), TEST_REGISTER_ENDPOINT_REQUEST,
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_202_ACCEPTED,
+ response.status_code)
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_register_hpa_hugepage_successfully(
+ self, mock_get_vim_info, mock_get_session):
+ restcall.req_to_aai = mock.Mock()
+ restcall.req_to_aai.return_value = (0, {}, status.HTTP_200_OK)
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HPA_FLAVOR_LIST1_RESPONSE),
+ self._get_mock_response(MOCK_GET_HPA_FLAVOR_onap_mini_EXTRA_SPECS3_RESPONSE),
+ self._get_mock_response(MOCK_GET_IMAGE_RESPONSE),
+ self._get_mock_response(),
+ self._get_mock_response(MOCK_GET_AZ_RESPONSE),
+ self._get_mock_response(MOCK_HYPERVISOR_RESPONSE),
+ self._get_mock_response(MOCK_GET_SNAPSHOT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HYPERVISOR_RESPONSE)
+ ]
+ })
+
+ response = self.client.post((
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/"
+ "registry"), TEST_REGISTER_ENDPOINT_REQUEST,
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_202_ACCEPTED,
+ response.status_code)
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_register_hpa_numa_successfully(
+ self, mock_get_vim_info, mock_get_session):
+ restcall.req_to_aai = mock.Mock()
+ restcall.req_to_aai.return_value = (0, {}, status.HTTP_200_OK)
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HPA_FLAVOR_LIST1_RESPONSE),
+ self._get_mock_response(MOCK_GET_HPA_FLAVOR_onap_mini_EXTRA_SPECS4_RESPONSE),
+ self._get_mock_response(MOCK_GET_IMAGE_RESPONSE),
+ self._get_mock_response(),
+ self._get_mock_response(MOCK_GET_AZ_RESPONSE),
+ self._get_mock_response(MOCK_HYPERVISOR_RESPONSE),
+ self._get_mock_response(MOCK_GET_SNAPSHOT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HYPERVISOR_RESPONSE)
+ ]
+ })
+
+ response = self.client.post((
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/"
+ "registry"), TEST_REGISTER_ENDPOINT_REQUEST,
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_202_ACCEPTED,
+ response.status_code)
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_register_hpa_instructionset_successfully(
+ self, mock_get_vim_info, mock_get_session):
+ restcall.req_to_aai = mock.Mock()
+ restcall.req_to_aai.return_value = (0, {}, status.HTTP_200_OK)
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HPA_FLAVOR_LIST1_RESPONSE),
+ self._get_mock_response(MOCK_GET_HPA_FLAVOR_onap_mini_EXTRA_SPECS5_RESPONSE),
+ self._get_mock_response(MOCK_GET_IMAGE_RESPONSE),
+ self._get_mock_response(),
+ self._get_mock_response(MOCK_GET_AZ_RESPONSE),
+ self._get_mock_response(MOCK_HYPERVISOR_RESPONSE),
+ self._get_mock_response(MOCK_GET_SNAPSHOT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HYPERVISOR_RESPONSE)
+ ]
+ })
+
+ response = self.client.post((
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/"
+ "registry"), TEST_REGISTER_ENDPOINT_REQUEST,
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_202_ACCEPTED,
+ response.status_code)
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_register_pcipassthrough_successfully(
+ self, mock_get_vim_info, mock_get_session):
+ restcall.req_to_aai = mock.Mock()
+ restcall.req_to_aai.return_value = (0, {}, status.HTTP_200_OK)
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HPA_FLAVOR_LIST1_RESPONSE),
+ self._get_mock_response(MOCK_GET_HPA_FLAVOR_onap_mini_EXTRA_SPECS6_RESPONSE),
+ self._get_mock_response(MOCK_GET_IMAGE_RESPONSE),
+ self._get_mock_response(),
+ self._get_mock_response(MOCK_GET_AZ_RESPONSE),
+ self._get_mock_response(MOCK_HYPERVISOR_RESPONSE),
+ self._get_mock_response(MOCK_GET_SNAPSHOT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HYPERVISOR_RESPONSE)
+ ]
+ })
+
+ response = self.client.post((
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/"
+ "registry"), TEST_REGISTER_ENDPOINT_REQUEST,
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_202_ACCEPTED,
+ response.status_code)
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_register_sriovnic_successfully(
+ self, mock_get_vim_info, mock_get_session):
+ restcall.req_to_aai = mock.Mock()
+ restcall.req_to_aai.return_value = (0, {}, status.HTTP_200_OK)
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HPA_FLAVOR_LIST1_RESPONSE),
+ self._get_mock_response(MOCK_GET_HPA_FLAVOR_onap_mini_EXTRA_SPECS7_RESPONSE),
+ self._get_mock_response(MOCK_GET_IMAGE_RESPONSE),
+ self._get_mock_response(),
+ self._get_mock_response(MOCK_GET_AZ_RESPONSE),
+ self._get_mock_response(MOCK_HYPERVISOR_RESPONSE),
+ self._get_mock_response(MOCK_GET_SNAPSHOT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HYPERVISOR_RESPONSE)
+ ]
+ })
+
+ response = self.client.post((
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/"
+ "registry"), TEST_REGISTER_ENDPOINT_REQUEST,
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_202_ACCEPTED,
+ response.status_code)
diff --git a/starlingx/starlingx/registration/tests/test_registration2.py b/starlingx/starlingx/registration/tests/test_registration2.py
new file mode 100644
index 00000000..62138540
--- /dev/null
+++ b/starlingx/starlingx/registration/tests/test_registration2.py
@@ -0,0 +1,107 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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 mock
+
+import unittest
+from django.test import Client
+from rest_framework import status
+from common.utils import restcall
+from starlingx_base.registration import registration
+from newton_base.tests import test_base
+
+MOCK_VIM_INFO = {
+ "createTime": "2017-04-01 02:22:27",
+ "domain": "Default",
+ "name": "TiS_R4",
+ "password": "admin",
+ "tenant": "admin",
+ "type": "openstack",
+ "url": "http://128.224.180.14:5000/v3",
+ "userName": "admin",
+ "vendor": "Starlingx",
+ "version": "newton",
+ "vimId": "starlingx_RegionOne",
+ 'cloud_owner': 'starlingx',
+ 'cloud_region_id': 'RegionOne',
+ 'cloud_extra_info': '',
+ 'insecure': 'True',
+}
+
+MOCK_GET_FLAVOR_RESPONSE = {
+ "flavors": [
+ {
+ "id": "1", "name": "micro", "vcpus": 1, "ram": "1MB",
+ "disk": "1G", "OS-FLV-EXT-DATA:ephemeral": False,
+ "swap": True, "os-flavor-access:is_public": True,
+ "OS-FLV-DISABLED:disabled": True, "link": [{"href": 1}]
+ },
+ {
+ "id": "2", "name": "mini", "vcpus": 2, "ram": "2MB",
+ "disk": "2G", "OS-FLV-EXT-DATA:ephemeral": True,
+ "swap": False, "os-flavor-access:is_public": True,
+ "OS-FLV-DISABLED:disabled": True
+ },
+ ]
+}
+
+MOCK_GET_FLAVOR_RESPONSE_w_hpa_numa = {
+ "flavors": [
+ {
+ "id": "1", "name": "onap.big", "vcpus": 6, "ram": "8192",
+ "disk": "10", "OS-FLV-EXT-DATA:ephemeral": False,
+ "swap": True, "os-flavor-access:is_public": True,
+ "OS-FLV-DISABLED:disabled": True, "link": [{"href": 1}]
+ }
+ ]
+}
+MOCK_GET_FLAVOR_EXTRASPECS_RESPONSE_w_hpa_numa = {
+ "hw:numa_nodes": 2
+}
+
+
+class TestRegistration2(unittest.TestCase):
+ def setUp(self):
+ self.client = Client()
+ self.view = registration.Registry()
+
+ def tearDown(self):
+ pass
+
+ def test_discover_flavors(self):
+ restcall.req_to_aai = mock.Mock()
+ restcall.req_to_aai.return_value = (0, {}, status.HTTP_200_OK)
+ mock_session = test_base.get_mock_session(
+ ["get"], {"get": {
+ "content": MOCK_GET_FLAVOR_RESPONSE}}),
+
+ resp = self.view._discover_flavors(vimid="starlingx_RegionOne",
+ session=mock_session, viminfo=MOCK_VIM_INFO)
+
+ self.assertIsNone(resp)
+
+ def test_discover_flavors_w_hpa_numa(self):
+ restcall.req_to_aai = mock.Mock()
+ restcall.req_to_aai.return_value = (0, {}, status.HTTP_200_OK)
+ mock_session = test_base.get_mock_session(
+ ["get"], {"side_effect": [{
+ "content": MOCK_GET_FLAVOR_RESPONSE_w_hpa_numa},
+ {
+ "content": MOCK_GET_FLAVOR_EXTRASPECS_RESPONSE_w_hpa_numa}
+ ]}),
+
+ resp = self.view._discover_flavors(vimid="starlingx_RegionOne",
+ session=mock_session, viminfo=MOCK_VIM_INFO)
+
+ self.assertIsNone(resp)
diff --git a/starlingx/starlingx/requests/__init__.py b/starlingx/starlingx/requests/__init__.py
new file mode 100644
index 00000000..81362a2b
--- /dev/null
+++ b/starlingx/starlingx/requests/__init__.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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.
diff --git a/starlingx/starlingx/requests/urls.py b/starlingx/starlingx/requests/urls.py
new file mode 100644
index 00000000..fbd088e3
--- /dev/null
+++ b/starlingx/starlingx/requests/urls.py
@@ -0,0 +1,49 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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.conf.urls import url
+from rest_framework.urlpatterns import format_suffix_patterns
+
+from newton_base.openoapi import network
+from newton_base.openoapi import subnet
+from newton_base.openoapi import image
+from newton_base.openoapi import volume
+from newton_base.openoapi import server
+from newton_base.openoapi import vport
+from newton_base.openoapi import limits
+from newton_base.openoapi import hosts
+from newton_base.openoapi import flavor
+
+urlpatterns = [
+ url(r'^networks(/(?P<networkid>[0-9a-zA-Z_-]+))?',
+ network.Networks.as_view()),
+ url(r'^subnets(/(?P<subnetid>[0-9a-zA-Z_-]+))?',
+ subnet.Subnets.as_view()),
+ url(r'^images(/(?P<imageid>[0-9a-zA-Z_-]+))?',
+ image.Images.as_view()),
+ url(r'^volumes(/(?P<volumeid>[0-9a-zA-Z_-]+))?',
+ volume.Volumes.as_view()),
+ url(r'^servers(/(?P<serverid>[0-9a-zA-Z_-]+))/action/?$',
+ server.ServerAction.as_view()),
+ url(r'^servers(/(?P<serverid>[0-9a-zA-Z_-]+))?',
+ server.Servers.as_view()),
+ url(r'^ports(/(?P<portid>[0-9a-zA-Z_-]+))?',
+ vport.Vports.as_view()),
+ url(r'^flavors(/(?P<flavorid>[0-9a-zA-Z_-]+))?',
+ flavor.Flavors.as_view()),
+ url(r'^limits$', limits.Limits.as_view()),
+ url(r'^hosts(/(?P<hostname>[0-9a-zA-Z_-]+))?', hosts.Hosts.as_view()),
+]
+
+urlpatterns = format_suffix_patterns(urlpatterns)
diff --git a/starlingx/starlingx/requests/urlsV1.py b/starlingx/starlingx/requests/urlsV1.py
new file mode 100644
index 00000000..1318e82b
--- /dev/null
+++ b/starlingx/starlingx/requests/urlsV1.py
@@ -0,0 +1,49 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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.conf.urls import url
+from rest_framework.urlpatterns import format_suffix_patterns
+
+from newton_base.openoapi import network
+from newton_base.openoapi import subnet
+from newton_base.openoapi import image
+from newton_base.openoapi import volume
+from newton_base.openoapi import server
+from newton_base.openoapi import vport
+from newton_base.openoapi import limits
+from newton_base.openoapi import hosts
+from newton_base.openoapi import flavor
+
+urlpatterns = [
+ url(r'^networks(/(?P<networkid>[0-9a-zA-Z_-]+))?',
+ network.APIv1Networks.as_view()),
+ url(r'^subnets(/(?P<subnetid>[0-9a-zA-Z_-]+))?',
+ subnet.APIv1Subnets.as_view()),
+ url(r'^images(/(?P<imageid>[0-9a-zA-Z_-]+))?',
+ image.APIv1Images.as_view()),
+ url(r'^volumes(/(?P<volumeid>[0-9a-zA-Z_-]+))?',
+ volume.APIv1Volumes.as_view()),
+ url(r'^servers(/(?P<serverid>[0-9a-zA-Z_-]+))/action/?$',
+ server.APIv1ServerAction.as_view()),
+ url(r'^servers(/(?P<serverid>[0-9a-zA-Z_-]+))?',
+ server.APIv1Servers.as_view()),
+ url(r'^ports(/(?P<portid>[0-9a-zA-Z_-]+))?',
+ vport.APIv1Vports.as_view()),
+ url(r'^flavors(/(?P<flavorid>[0-9a-zA-Z_-]+))?',
+ flavor.APIv1Flavors.as_view()),
+ url(r'^limits$', limits.APIv1Limits.as_view()),
+ url(r'^hosts(/(?P<hostname>[0-9a-zA-Z_-]+))?', hosts.APIv1Hosts.as_view()),
+]
+
+urlpatterns = format_suffix_patterns(urlpatterns)
diff --git a/starlingx/starlingx/requests/views/__init__.py b/starlingx/starlingx/requests/views/__init__.py
new file mode 100644
index 00000000..81362a2b
--- /dev/null
+++ b/starlingx/starlingx/requests/views/__init__.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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.
diff --git a/starlingx/starlingx/resource/__init__.py b/starlingx/starlingx/resource/__init__.py
new file mode 100644
index 00000000..81362a2b
--- /dev/null
+++ b/starlingx/starlingx/resource/__init__.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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.
diff --git a/starlingx/starlingx/resource/tests/__init__.py b/starlingx/starlingx/resource/tests/__init__.py
new file mode 100644
index 00000000..81362a2b
--- /dev/null
+++ b/starlingx/starlingx/resource/tests/__init__.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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.
diff --git a/starlingx/starlingx/resource/tests/test_capacity.py b/starlingx/starlingx/resource/tests/test_capacity.py
new file mode 100644
index 00000000..c48f0eff
--- /dev/null
+++ b/starlingx/starlingx/resource/tests/test_capacity.py
@@ -0,0 +1,277 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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 mock
+import json
+
+from rest_framework import status
+
+from newton_base.tests import mock_info
+from newton_base.tests import test_base
+from newton_base.util import VimDriverUtils
+
+MOCK_GET_TENANT_LIMIT_RESPONSE = {
+ "limits": {
+ "rate": [],
+ "absolute": {
+ "maxTotalRAMSize": 128 * 1024,
+ "totalRAMUsed": 8 * 1024,
+ "totalCoresUsed": 4,
+ "maxTotalCores": 20,
+ }
+ }
+}
+
+MOCK_GET_HYPER_STATATICS_RESPONSE = {
+ "hypervisor_statistics": {
+ "vcpus_used": 4,
+ "free_ram_mb": 120 * 1024,
+ "vcpus": 10,
+ "free_disk_gb": 300
+ }
+}
+
+MOCK_GET_STORAGE_RESPONSE_OOS = {
+ "limits": {
+ "rate": [],
+ "absolute": {
+ "totalGigabytesUsed": 498,
+ "maxTotalVolumeGigabytes": 500,
+ }
+ }
+}
+
+MOCK_GET_HYPER_STATATICS_RESPONSE_OUTOFVCPU = {
+ "hypervisor_statistics": {
+ "vcpus_used": 9,
+ "free_ram_mb": 120 * 1024,
+ "vcpus": 10,
+ "free_disk_gb": 300
+ }
+}
+
+MOCK_GET_TENANT_LIMIT_RESPONSE_OUTOFRAM = {
+ "limits": {
+ "rate": [],
+ "absolute": {
+ "maxTotalRAMSize": 12 * 1024,
+ "totalRAMUsed": 10 * 1024,
+ "totalCoresUsed": 4,
+ "maxTotalCores": 20,
+ }
+ }
+}
+
+MOCK_GET_HYPER_STATATICS_RESPONSE_OUTOFRAM = {
+ "hypervisor_statistics": {
+ "vcpus_used": 4,
+ "free_ram_mb": 1 * 1024,
+ "vcpus": 10,
+ "free_disk_gb": 300
+ }
+}
+
+MOCK_GET_HYPER_STATATICS_RESPONSE_OUTOFSTORAGE = {
+ "hypervisor_statistics": {
+ "vcpus_used": 4,
+ "free_ram_mb": 120 * 1024,
+ "vcpus": 10,
+ "free_disk_gb": 3
+ }
+}
+
+MOCK_GET_STORAGE_RESPONSE = {
+ "limits": {
+ "rate": [],
+ "absolute": {
+ "totalGigabytesUsed": 200,
+ "maxTotalVolumeGigabytes": 500,
+ }
+ }
+}
+
+TEST_REQ_SUCCESS_SOURCE = {
+ "vCPU": "4",
+ "Memory": "4096",
+ "Storage": "200"
+}
+
+TEST_REQ_FAILED_SOURCE = {
+ "vCPU": "17",
+ "Memory": "4096",
+ "Storage": "200"
+}
+
+
+class TestCapacity(test_base.TestRequest):
+ def setUp(self):
+ super(TestCapacity, self).setUp()
+
+ def _get_mock_response(self, return_value=None):
+ mock_response = mock.Mock(spec=test_base.MockResponse)
+ mock_response.status_code = status.HTTP_200_OK
+ mock_response.json.return_value = return_value
+ return mock_response
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_capacity_check_success(self, mock_get_vim_info, mock_get_session):
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_LIMIT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HYPER_STATATICS_RESPONSE),
+ self._get_mock_response(MOCK_GET_STORAGE_RESPONSE),
+ ]
+ })
+
+ response = self.client.post(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/capacity_check",
+ TEST_REQ_SUCCESS_SOURCE,
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_200_OK, response.status_code)
+ self.assertEqual({"result": True}, response.data)
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_capacity_check_nova_limits_failed(self, mock_get_vim_info, mock_get_session):
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_LIMIT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HYPER_STATATICS_RESPONSE),
+ self._get_mock_response(MOCK_GET_STORAGE_RESPONSE),
+ ]
+ })
+
+ response = self.client.post(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/capacity_check",
+ TEST_REQ_FAILED_SOURCE,
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_200_OK, response.status_code)
+ self.assertEqual({"result": False}, response.data)
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_capacity_check_nova_hypervisor_outofram(self, mock_get_vim_info, mock_get_session):
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_LIMIT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HYPER_STATATICS_RESPONSE_OUTOFRAM),
+ self._get_mock_response(MOCK_GET_STORAGE_RESPONSE),
+ ]
+ })
+
+ response = self.client.post(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/capacity_check",
+ data=json.dumps(TEST_REQ_SUCCESS_SOURCE),
+ content_type='application/json',
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_200_OK, response.status_code)
+ self.assertEqual({"result": False}, response.data)
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_capacity_check_nova_hypervisor_outofstorage(self, mock_get_vim_info, mock_get_session):
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_LIMIT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HYPER_STATATICS_RESPONSE_OUTOFSTORAGE),
+ self._get_mock_response(MOCK_GET_STORAGE_RESPONSE),
+ ]
+ })
+
+ response = self.client.post(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/capacity_check",
+ data=json.dumps(TEST_REQ_SUCCESS_SOURCE),
+ content_type='application/json',
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_200_OK, response.status_code)
+ self.assertEqual({"result": False}, response.data)
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_capacity_check_nova_hypervisor_outofvcpu(self, mock_get_vim_info, mock_get_session):
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_LIMIT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HYPER_STATATICS_RESPONSE_OUTOFVCPU),
+ self._get_mock_response(MOCK_GET_STORAGE_RESPONSE),
+ ]
+ })
+
+ response = self.client.post(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/capacity_check",
+ data=json.dumps(TEST_REQ_SUCCESS_SOURCE),
+ content_type='application/json',
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_200_OK, response.status_code)
+ self.assertEqual({"result": False}, response.data)
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_capacity_check_nova_limits_outofram(self, mock_get_vim_info, mock_get_session):
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_LIMIT_RESPONSE_OUTOFRAM),
+ self._get_mock_response(MOCK_GET_HYPER_STATATICS_RESPONSE),
+ self._get_mock_response(MOCK_GET_STORAGE_RESPONSE),
+ ]
+ })
+
+ response = self.client.post(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/capacity_check",
+ data=json.dumps(TEST_REQ_SUCCESS_SOURCE),
+ content_type='application/json',
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_200_OK, response.status_code)
+ self.assertEqual({"result": False}, response.data)
+
+ @mock.patch.object(VimDriverUtils, 'get_session')
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_capacity_check_volume_limits_outofstorage(self, mock_get_vim_info, mock_get_session):
+ mock_get_vim_info.return_value = mock_info.MOCK_VIM_INFO
+ mock_get_session.return_value = test_base.get_mock_session(
+ ["get"], {
+ "side_effect": [
+ self._get_mock_response(MOCK_GET_TENANT_LIMIT_RESPONSE),
+ self._get_mock_response(MOCK_GET_HYPER_STATATICS_RESPONSE),
+ self._get_mock_response(MOCK_GET_STORAGE_RESPONSE_OOS),
+ ]
+ })
+
+ response = self.client.post(
+ "/api/multicloud-starlingx/v0/starlingx_RegionOne/capacity_check",
+ data=json.dumps(TEST_REQ_SUCCESS_SOURCE),
+ content_type='application/json',
+ HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID)
+
+ self.assertEquals(status.HTTP_200_OK, response.status_code)
+ self.assertEqual({"result": False}, response.data)
diff --git a/starlingx/starlingx/resource/tests/tests_infra_workload.py b/starlingx/starlingx/resource/tests/tests_infra_workload.py
new file mode 100644
index 00000000..8e9f9d98
--- /dev/null
+++ b/starlingx/starlingx/resource/tests/tests_infra_workload.py
@@ -0,0 +1,280 @@
+# Copyright (c) 2019 Intel Corporation.
+#
+# 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 mock
+
+import unittest
+from rest_framework import status
+
+from common.msapi.helper import Helper as helper
+from newton_base.resource.infra_workload import InfraWorkload
+from newton_base.resource.infra_workload import APIv1InfraWorkload
+
+MOCK_TOKEN_RESPONSE = {
+ "access":
+ {"token": {"issued_at": "2018-05-10T16:56:56.000000Z",
+ "expires": "2018-05-10T17:56:56.000000Z",
+ "id": "4a832860dd744306b3f66452933f939e",
+ "tenant": {"domain": {"id": "default",
+ "name": "Default"},
+ "enabled": "true",
+ "id": "0e148b76ee8c42f78d37013bf6b7b1ae",
+ "name": "VIM"}},
+ "serviceCatalog": [],
+ "user": {"domain": {"id": "default",
+ "name": "Default"},
+ "id": "ba76c94eb5e94bb7bec6980e5507aae2",
+ "name": "demo"}
+ }
+}
+
+MOCK_HEAT_CREATE_BODY1 = {
+ "generic-vnf-id": "MOCK_GENERIF_VNF_ID1",
+ "vf-module-id": "MOCK_VF_MODULE_ID1",
+ "oof_directives": {
+ "directives": [
+ {
+ "id": "MOCK_VNFC_ID1",
+ "type": "vnfc",
+ "directives": [{
+ "type": "flavor_directives",
+ "attributes": [
+ {
+ "attribute_name": "flavor1",
+ "attribute_value": "m1.hpa.medium"
+ }
+ ]
+ },
+ {"type": "sriovNetNetwork_directives",
+ "attributes": [{
+ "attribute_name": "physnetwork_label",
+ "attribute_value": "physnet1"
+ }]
+ }
+ ]
+ }
+ ]
+ },
+ "sdnc_directives": {},
+ "template_type": "HEAT",
+ "template_data": {
+ "files": {},
+ "disable_rollback": True,
+ "parameters": {
+ "flavor1": "m1.heat"
+ },
+ "stack_name": "teststack",
+ "template": {
+ "heat_template_version": "2013-05-23",
+ "description": "Simple template to test heat commands",
+ "parameters": {
+ "flavor": {
+ "default": "m1.tiny",
+ "type": "string"
+ }
+ },
+ "resources": {
+ "hello_world": {
+ "type": "OS::Nova::Server",
+ "properties": {
+ "key_name": "heat_key",
+ "flavor": {
+ "get_param": "flavor"
+ },
+ "image": "40be8d1a-3eb9-40de-8abd-43237517384f",
+ "user_data": "#!/bin/bash -xv\necho \"hello world\" &gt; /root/hello-world.txt\n"
+ }
+ }
+ }
+ },
+ "timeout_mins": 60
+ }
+}
+
+MOCK_HEAT_CREATE_RESPONSE1 = {
+ 'stack': {
+ 'id': "MOCKED_HEAT_STACK_ID1"
+ }
+}
+
+MOCK_HEAT_LIST_RESPONSE1 = {
+ 'stacks': [
+ {
+ 'stack_status': "CREATE_IN_PROCESS"
+ }
+ ]
+}
+
+MOCK_HEAT_CREATE_BODY2 = {
+ "generic-vnf-id": "MOCK_GENERIF_VNF_ID1",
+ "vf-module-id": "MOCK_VF_MODULE_ID1",
+ "template_type": "HEAT",
+ "template_data": {
+ "files": {},
+ "disable_rollback": True,
+ "parameters": {
+ "flavor1": "m1.heat"
+ },
+ "stack_name": "teststack",
+ "template": {
+ "heat_template_version": "2013-05-23",
+ "description": "Simple template to test heat commands",
+ "parameters": {
+ "flavor": {
+ "default": "m1.tiny",
+ "type": "string"
+ }
+ },
+ "resources": {
+ "hello_world": {
+ "type": "OS::Nova::Server",
+ "properties": {
+ "key_name": "heat_key",
+ "flavor": {
+ "get_param": "flavor"
+ },
+ "image": "40be8d1a-3eb9-40de-8abd-43237517384f",
+ "user_data": "#!/bin/bash -xv\necho \"hello world\" &gt; /root/hello-world.txt\n"
+ }
+ }
+ }
+ },
+ "timeout_mins": 60
+ }
+}
+
+
+class InfraWorkloadTest(unittest.TestCase):
+ def setUp(self):
+ self._InfraWorkload = InfraWorkload()
+ pass
+
+ def tearDown(self):
+ pass
+
+ @mock.patch.object(helper, 'MultiCloudServiceHelper')
+ @mock.patch.object(helper, 'MultiCloudIdentityHelper')
+ def test_post(self, mock_MultiCloudIdentityHelper, mock_MultiCloudServiceHelper):
+ mock_request = mock.Mock()
+ mock_request.META = {"testkey": "testvalue"}
+ mock_request.data = MOCK_HEAT_CREATE_BODY1
+
+ mock_MultiCloudIdentityHelper.side_effect = [
+ (0, MOCK_TOKEN_RESPONSE, status.HTTP_201_CREATED)
+ ]
+
+ mock_MultiCloudServiceHelper.side_effect = [
+ (0, MOCK_HEAT_CREATE_RESPONSE1, status.HTTP_201_CREATED)
+ ]
+
+ vimid = "CloudOwner_Region1"
+
+ response = self._InfraWorkload.post(mock_request, vimid)
+ self.assertEqual(response.status_code, status.HTTP_201_CREATED)
+ pass
+
+ @mock.patch.object(helper, 'MultiCloudServiceHelper')
+ @mock.patch.object(helper, 'MultiCloudIdentityHelper')
+ def test_post_wo_oof_directive(self, mock_MultiCloudIdentityHelper, mock_MultiCloudServiceHelper):
+ mock_request = mock.Mock()
+ mock_request.META = {"testkey": "testvalue"}
+ mock_request.data = MOCK_HEAT_CREATE_BODY2
+
+ mock_MultiCloudIdentityHelper.side_effect = [
+ (0, MOCK_TOKEN_RESPONSE, status.HTTP_201_CREATED)
+ ]
+
+ mock_MultiCloudServiceHelper.side_effect = [
+ (0, MOCK_HEAT_CREATE_RESPONSE1, status.HTTP_201_CREATED)
+ ]
+
+ vimid = "CloudOwner_Region1"
+
+ response = self._InfraWorkload.post(mock_request, vimid)
+ self.assertEqual(response.status_code, status.HTTP_201_CREATED)
+ pass
+
+ @mock.patch.object(helper, 'MultiCloudServiceHelper')
+ @mock.patch.object(helper, 'MultiCloudIdentityHelper')
+ def test_get(self, mock_MultiCloudIdentityHelper, mock_MultiCloudServiceHelper):
+ mock_request = mock.Mock()
+ mock_request.META = {"testkey": "testvalue"}
+
+ mock_MultiCloudIdentityHelper.side_effect = [
+ (0, MOCK_TOKEN_RESPONSE, status.HTTP_201_CREATED)
+ ]
+
+ mock_MultiCloudServiceHelper.side_effect = [
+ (0, MOCK_HEAT_LIST_RESPONSE1, status.HTTP_200_OK)
+ ]
+
+ vimid = "CloudOwner_Region1"
+ mock_stack_id = "MOCKED_HEAT_STACK_ID1"
+
+ response = self._InfraWorkload.get(mock_request, vimid, mock_stack_id)
+ self.assertEqual(response.status_code, status.HTTP_200_OK)
+ pass
+
+
+class APIv1InfraWorkloadTest(unittest.TestCase):
+ def setUp(self):
+ self._APIv1InfraWorkload = APIv1InfraWorkload()
+ pass
+
+ def tearDown(self):
+ pass
+
+ @mock.patch.object(helper, 'MultiCloudServiceHelper')
+ @mock.patch.object(helper, 'MultiCloudIdentityHelper')
+ def test_post(self, mock_MultiCloudIdentityHelper, mock_MultiCloudServiceHelper):
+ mock_request = mock.Mock()
+ mock_request.META = {"testkey": "testvalue"}
+ mock_request.data = MOCK_HEAT_CREATE_BODY1
+
+ mock_MultiCloudIdentityHelper.side_effect = [
+ (0, MOCK_TOKEN_RESPONSE, status.HTTP_201_CREATED)
+ ]
+
+ mock_MultiCloudServiceHelper.side_effect = [
+ (0, MOCK_HEAT_CREATE_RESPONSE1, status.HTTP_201_CREATED)
+ ]
+
+ cloud_owner = "CloudOwner"
+ cloud_region_id = "Region1"
+
+ response = self._APIv1InfraWorkload.post(mock_request, cloud_owner, cloud_region_id)
+ self.assertEqual(response.status_code, status.HTTP_201_CREATED)
+ pass
+
+ @mock.patch.object(helper, 'MultiCloudServiceHelper')
+ @mock.patch.object(helper, 'MultiCloudIdentityHelper')
+ def test_get(self, mock_MultiCloudIdentityHelper, mock_MultiCloudServiceHelper):
+ mock_request = mock.Mock()
+ mock_request.META = {"testkey": "testvalue"}
+
+ mock_MultiCloudIdentityHelper.side_effect = [
+ (0, MOCK_TOKEN_RESPONSE, status.HTTP_201_CREATED)
+ ]
+
+ mock_MultiCloudServiceHelper.side_effect = [
+ (0, MOCK_HEAT_LIST_RESPONSE1, status.HTTP_200_OK)
+ ]
+
+ cloud_owner = "CloudOwner"
+ cloud_region_id = "Region1"
+ mock_stack_id = "MOCKED_HEAT_STACK_ID1"
+
+ response = self._APIv1InfraWorkload.get(mock_request, cloud_owner, cloud_region_id, mock_stack_id)
+ self.assertEqual(response.status_code, status.HTTP_200_OK)
+ pass
diff --git a/starlingx/starlingx/urls.py b/starlingx/starlingx/urls.py
index b9c968ec..5d597e46 100644
--- a/starlingx/starlingx/urls.py
+++ b/starlingx/starlingx/urls.py
@@ -13,8 +13,42 @@
# limitations under the License.
from django.conf.urls import include, url
+from starlingx_base.registration import registration
+from newton_base.openoapi import tenants
+from newton_base.resource import capacity
+from newton_base.resource import infra_workload
urlpatterns = [
url(r'^', include('starlingx.swagger.urls')),
url(r'^', include('starlingx.samples.urls')),
+
+ # API v0
+ url(r'^api/multicloud-starlingx/v0/(?P<vimid>[0-9a-zA-Z_-]+)/registry/?$',
+ registration.Registry.as_view()),
+ url(r'^api/multicloud-starlingx/v0/(?P<vimid>[0-9a-zA-Z_-]+)/?$',
+ registration.Registry.as_view()),
+ url(r'^api/multicloud-starlingx/v0/(?P<vimid>[0-9a-zA-Z_-]+)/',
+ include('starlingx.proxy.urls')),
+ url(r'^api/multicloud-starlingx/v0/(?P<vimid>[0-9a-zA-Z_-]+)/tenants/?$',
+ tenants.Tenants.as_view()),
+ url(r'^api/multicloud-starlingx/v0/(?P<vimid>[0-9a-zA-Z_-]+)/'
+ '(?P<tenantid>[0-9a-zA-Z_-]{20,})/', include('starlingx.requests.urls')),
+ url(r'^api/multicloud-starlingx/v0/(?P<vimid>[0-9a-zA-Z_-]+)/capacity_check/?$',
+ capacity.CapacityCheck.as_view()),
+
+ # API v1, depreciated due to MULTICLOUD-335
+ url(r'^api/multicloud-starlingx/v1/(?P<cloud_owner>[0-9a-zA-Z_-]+)/(?P<cloud_region_id>[0-9a-zA-Z_-]+)/registry/?$',
+ registration.APIv1Registry.as_view()),
+ url(r'^api/multicloud-starlingx/v1/(?P<cloud_owner>[0-9a-zA-Z_-]+)/(?P<cloud_region_id>[0-9a-zA-Z_-]+)/?$',
+ registration.APIv1Registry.as_view()),
+ url(r'^api/multicloud-starlingx/v1/(?P<cloud_owner>[0-9a-zA-Z_-]+)/(?P<cloud_region_id>[0-9a-zA-Z_-]+)/',
+ include('starlingx.proxy.urlsV1')),
+ url(r'^api/multicloud-starlingx/v1/(?P<cloud_owner>[0-9a-zA-Z_-]+)/(?P<cloud_region_id>[0-9a-zA-Z_-]+)/tenants/?$',
+ tenants.APIv1Tenants.as_view()),
+ url(r'^api/multicloud-starlingx/v1/(?P<cloud_owner>[0-9a-zA-Z_-]+)/(?P<cloud_region_id>[0-9a-zA-Z_-]+)/'
+ '(?P<tenantid>[0-9a-zA-Z_-]{20,})/', include('starlingx.requests.urlsV1')),
+ url(r'^api/multicloud-starlingx/v1/(?P<cloud_owner>[0-9a-zA-Z_-]+)/(?P<cloud_region_id>[0-9a-zA-Z_-]+)/capacity_check/?$',
+ capacity.APIv1CapacityCheck.as_view()),
+ url(r'^api/multicloud-starlingx/v1/(?P<cloud_owner>[0-9a-zA-Z_-]+)/(?P<cloud_region_id>[0-9a-zA-Z_-]+)/infra_workload/?$',
+ infra_workload.APIv1InfraWorkload.as_view()),
]