Merge "Fix identity url version detection"

This commit is contained in:
Zuul 2018-08-10 13:17:34 +00:00 committed by Gerrit Code Review
commit 83e6ecb079
5 changed files with 99 additions and 24 deletions

View File

@ -13,6 +13,9 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import re
import requests
from six.moves import urllib
from tempest.lib import auth from tempest.lib import auth
@ -62,16 +65,37 @@ class Credentials(object):
# tool keeps them in identity section for further usage # tool keeps them in identity section for further usage
return self._conf.get_defaulted('identity', key) return self._conf.get_defaulted('identity', key)
def _get_base_url(self, endpoint):
"""Return the base url.
:param key: endpoint
:type key: string
:returns: base_url
:rtype: string
"""
url = urllib.parse.urlsplit(endpoint)
new_path = re.split(r'(^|/)+v\d+(\.\d+)?', url.path)[0]
url = list(url)
url[2] = new_path + '/'
return urllib.parse.urlunsplit(url)
def _list_versions(self, base_url):
resp = requests.get(base_url)
data = resp.json()
return data["versions"]["values"]
def _get_identity_version(self): def _get_identity_version(self):
"""Looks for identity version in TempestConf object. """Looks for identity version in TempestConf object.
:returns: identity version :returns: identity version
:rtype: string :rtype: string
""" """
if "v3" in self._conf.get("identity", "uri"): base_url = self._get_base_url(self._conf.get("identity", "uri"))
return "v3" versions = self._list_versions(base_url)
else: for version in versions:
return "v2" if version["status"] == "stable" and "v3" in version["id"]:
return "v3"
return "v2"
def _get_creds_kwargs(self): def _get_creds_kwargs(self):
"""Creates kwargs. """Creates kwargs.
@ -111,6 +135,11 @@ class Credentials(object):
:rtype: auth.KeystoneV2AuthProvider/auth.KeystoneV3AuthProvider :rtype: auth.KeystoneV2AuthProvider/auth.KeystoneV3AuthProvider
""" """
if isinstance(self.tempest_creds, auth.KeystoneV3Credentials): if isinstance(self.tempest_creds, auth.KeystoneV3Credentials):
# We set uri and uri_v3 to /v3 here because if the endpoint on the
# rc file don't set the /v3 it will fail with a error 404
uri = self._conf.get_defaulted('identity', 'uri_v3')
uri = self._get_base_url(uri) + 'v3'
self._conf.set('identity', 'uri_v3', uri)
return auth.KeystoneV3AuthProvider( return auth.KeystoneV3AuthProvider(
self.tempest_creds, self.tempest_creds,
self._conf.get_defaulted('identity', 'uri_v3'), self._conf.get_defaulted('identity', 'uri_v3'),

View File

@ -29,6 +29,25 @@ class BaseConfigTempestTest(base.BaseTestCase):
"""Test case base class for all config_tempest unit tests""" """Test case base class for all config_tempest unit tests"""
FAKE_V3_VERSIONS = (
[{
'status': 'stable',
'id': 'v3.8',
}, {
'status': 'deprecated',
'id': 'v2.0',
}]
)
FAKE_V2_VERSIONS = (
[{
'status': 'deprecated',
'id': 'v3.8',
}, {
'status': 'stable',
'id': 'v2.0',
}]
)
def _get_conf(self, V2, V3): def _get_conf(self, V2, V3):
"""Creates fake conf for testing purposes""" """Creates fake conf for testing purposes"""
conf = tempest_conf.TempestConf() conf = tempest_conf.TempestConf()
@ -63,14 +82,21 @@ class BaseConfigTempestTest(base.BaseTestCase):
conf.set("auth", "use_dynamic_credentials", "True") conf.set("auth", "use_dynamic_credentials", "True")
return conf return conf
def _get_creds(self, conf, admin=False): def _get_creds(self, conf, admin=False, v2=False):
# We return creds configured to v2 or v3
func2mock = 'config_tempest.credentials.Credentials._list_versions'
return_value = self.FAKE_V3_VERSIONS
if v2:
return_value = self.FAKE_V2_VERSIONS
mock_function = mock.Mock(return_value=return_value)
self.useFixture(MonkeyPatch(func2mock, mock_function))
return Credentials(conf, admin) return Credentials(conf, admin)
@mock.patch('os_client_config.cloud_config.CloudConfig') @mock.patch('os_client_config.cloud_config.CloudConfig')
def _get_clients(self, conf, mock_args, creds=None): def _get_clients(self, conf, mock_args, creds=None):
"""Returns ClientManager instance""" """Returns ClientManager instance"""
if creds is None: if creds is None:
creds = self._get_creds(conf) creds = self._get_creds(conf, v2=True)
mock_function = mock.Mock(return_value=False) mock_function = mock.Mock(return_value=False)
func2mock = 'os_client_config.cloud_config.CloudConfig.config.get' func2mock = 'os_client_config.cloud_config.CloudConfig.config.get'
self.useFixture(MonkeyPatch(func2mock, mock_function)) self.useFixture(MonkeyPatch(func2mock, mock_function))

View File

@ -37,15 +37,15 @@ class TestServices(BaseConfigTempestTest):
super(TestServices, self).setUp() super(TestServices, self).setUp()
@mock.patch('config_tempest.services.services.Services.discover') @mock.patch('config_tempest.services.services.Services.discover')
def _create_services_instance(self, mock_discover): def _create_services_instance(self, mock_discover, v2=False):
conf = self._get_conf('v2', 'v3') conf = self._get_conf('v2', 'v3')
creds = self._get_creds(conf) creds = self._get_creds(conf, v2=v2)
clients = mock.Mock() clients = mock.Mock()
services = Services(clients, conf, creds) services = Services(clients, conf, creds)
return services return services
def test_get_endpoints_api_2(self): def test_get_endpoints_api_2(self):
services = self._create_services_instance() services = self._create_services_instance(v2=True)
services._region = 'my_region' services._region = 'my_region'
resp = services.get_endpoints(self.FAKE_ENTRY) resp = services.get_endpoints(self.FAKE_ENTRY)
self.assertEqual(resp, self.FAKE_ENTRY['endpoints'][0]) self.assertEqual(resp, self.FAKE_ENTRY['endpoints'][0])
@ -72,13 +72,13 @@ class TestServices(BaseConfigTempestTest):
self.assertEqual(resp, []) self.assertEqual(resp, [])
def test_set_catalog_and_url(self): def test_set_catalog_and_url(self):
services = self._create_services_instance()
# api version = 2 # api version = 2
services = self._create_services_instance(v2=True)
services.set_catalog_and_url() services.set_catalog_and_url()
self.assertEqual(services.service_catalog, 'serviceCatalog') self.assertEqual(services.service_catalog, 'serviceCatalog')
self.assertEqual(services.public_url, 'publicURL') self.assertEqual(services.public_url, 'publicURL')
# api version = 3 # api version = 3
services._creds.api_version = 3 services = self._create_services_instance()
services.set_catalog_and_url() services.set_catalog_and_url()
self.assertEqual(services.service_catalog, 'catalog') self.assertEqual(services.service_catalog, 'catalog')
self.assertEqual(services.public_url, 'url') self.assertEqual(services.public_url, 'url')
@ -101,10 +101,10 @@ class TestServices(BaseConfigTempestTest):
url = services.parse_endpoints(ep, "ServiceName") url = services.parse_endpoints(ep, "ServiceName")
self.assertEqual('http://10.0.0.107:8386/v1.1/96409a589d', url) self.assertEqual('http://10.0.0.107:8386/v1.1/96409a589d', url)
ep['url'] = 'https://10.0.0.101/identity' ep['url'] = 'https://10.0.0.101/identity'
auth_url = 'https://10.0.0.101:13000/v2.0' auth_url = 'https://10.0.0.101:13000/v3.0'
services._clients.auth_provider.auth_url = auth_url services._clients.auth_provider.auth_url = auth_url
url = services.parse_endpoints(ep, 'ServiceName') url = services.parse_endpoints(ep, 'ServiceName')
self.assertEqual('https://10.0.0.101:13000/identity/v2', url) self.assertEqual('https://10.0.0.101:13000/identity/v3', url)
def test_parse_endpoints_not_ip_hostname(self): def test_parse_endpoints_not_ip_hostname(self):
services = self._create_services_instance() services = self._create_services_instance()
@ -119,8 +119,24 @@ class TestServices(BaseConfigTempestTest):
url_resp = services.parse_endpoints(ep, "ServiceName") url_resp = services.parse_endpoints(ep, "ServiceName")
self.assertEqual(url, url_resp) self.assertEqual(url, url_resp)
def test_edit_identity_url(self): def test_edit_identity_url_v3(self):
services = self._create_services_instance() services = self._create_services_instance()
url_port = 'https://10.0.0.101:13000/v3.0'
identity_url = 'https://10.0.0.101/identity'
url_no_port = 'https://10.0.0.101/v333'
services._clients.auth_provider.auth_url = url_port
url = services.edit_identity_url(url_port)
self.assertEqual(url_port, url)
url = services.edit_identity_url(identity_url)
self.assertEqual("https://10.0.0.101:13000/identity/v3", url)
url = services.edit_identity_url(url_no_port)
self.assertEqual(url_no_port, url)
services._clients.auth_provider.auth_url = url_no_port
url = services.edit_identity_url(identity_url)
self.assertEqual(identity_url + "/v3", url)
def test_edit_identity_url_v2(self):
services = self._create_services_instance(v2=True)
url_port = 'https://10.0.0.101:13000/v2.0' url_port = 'https://10.0.0.101:13000/v2.0'
identity_url = 'https://10.0.0.101/identity' identity_url = 'https://10.0.0.101/identity'
url_no_port = 'https://10.0.0.101/v2.0' url_no_port = 'https://10.0.0.101/v2.0'

View File

@ -27,6 +27,7 @@ class TestCredentials(BaseConfigTempestTest):
super(TestCredentials, self).setUp() super(TestCredentials, self).setUp()
self.conf = self._get_conf("v2.0", "v3") self.conf = self._get_conf("v2.0", "v3")
self.creds = self._get_creds(self.conf) self.creds = self._get_creds(self.conf)
self.creds_v2 = self._get_creds(self.conf, v2=True)
def test_get_credential(self): def test_get_credential(self):
# set conf containing the newer values (admin creds in auth section) # set conf containing the newer values (admin creds in auth section)
@ -39,7 +40,7 @@ class TestCredentials(BaseConfigTempestTest):
self.assertEqual(resp, "admin") self.assertEqual(resp, "admin")
def test_get_identity_version_v2(self): def test_get_identity_version_v2(self):
resp = self.creds._get_identity_version() resp = self.creds_v2._get_identity_version()
self.assertEqual(resp, 'v2') self.assertEqual(resp, 'v2')
def test_get_identity_version_v3(self): def test_get_identity_version_v3(self):
@ -54,8 +55,8 @@ class TestCredentials(BaseConfigTempestTest):
'password': 'secret', 'password': 'secret',
'project_name': 'demo' 'project_name': 'demo'
} }
self.assertEqual(self.creds._get_creds_kwargs(), expected_resp) self.assertEqual(self.creds_v2._get_creds_kwargs(), expected_resp)
self.creds.identity_version = 'v3' self.creds_v2.identity_version = 'v3'
expected_resp = { expected_resp = {
'username': 'demo', 'username': 'demo',
'password': 'secret', 'password': 'secret',
@ -69,10 +70,10 @@ class TestCredentials(BaseConfigTempestTest):
mock_function = mock.Mock() mock_function = mock.Mock()
function2mock = 'config_tempest.credentials.auth.get_credentials' function2mock = 'config_tempest.credentials.auth.get_credentials'
self.useFixture(MonkeyPatch(function2mock, mock_function)) self.useFixture(MonkeyPatch(function2mock, mock_function))
self.creds.username = "name" self.creds_v2.username = "name"
self.creds.password = "pass" self.creds_v2.password = "pass"
self.creds.project_name = "Tname" self.creds_v2.project_name = "Tname"
self.creds.set_credentials() self.creds_v2.set_credentials()
mock_function.assert_called_with( mock_function.assert_called_with(
auth_url=None, fill_in=False, identity_version='v2', auth_url=None, fill_in=False, identity_version='v2',
disable_ssl_certificate_validation='true', disable_ssl_certificate_validation='true',
@ -103,11 +104,11 @@ class TestCredentials(BaseConfigTempestTest):
# mock V2Provider, if other provider is called, it fails # mock V2Provider, if other provider is called, it fails
func2mock = 'config_tempest.credentials.auth.KeystoneV2AuthProvider' func2mock = 'config_tempest.credentials.auth.KeystoneV2AuthProvider'
self.useFixture(MonkeyPatch(func2mock, mock_function)) self.useFixture(MonkeyPatch(func2mock, mock_function))
resp = self.creds.get_auth_provider() resp = self.creds_v2.get_auth_provider()
self.assertEqual(resp, mock_function()) self.assertEqual(resp, mock_function())
# check parameters of returned function # check parameters of returned function
self.creds.get_auth_provider() self.creds_v2.get_auth_provider()
mock_function.assert_called_with(self.creds.tempest_creds, mock_function.assert_called_with(self.creds_v2.tempest_creds,
'http://172.16.52.151:5000/v2.0', 'http://172.16.52.151:5000/v2.0',
'true', None) 'true', None)

View File

@ -23,6 +23,9 @@ from tempest.lib import exceptions
class TestUsers(BaseConfigTempestTest): class TestUsers(BaseConfigTempestTest):
def setUp(self): def setUp(self):
# TODO(arxcruz): All these tests are running on identity v2 only, we
# need to create tests for v3 too!
# Story 2003388
super(TestUsers, self).setUp() super(TestUsers, self).setUp()
self.conf = self._get_conf("v2.0", "v3") self.conf = self._get_conf("v2.0", "v3")
projects_client = self._get_clients(self.conf).projects projects_client = self._get_clients(self.conf).projects