Use keystone service catalog for getting auth urls

Co-Authored-By: Andrey Pavlov <apavlov@mirantis.com>

Change-Id: I6c64f4b975d12ccaca564d248f9ccbb02615e19f
Closes-bug: #1371856
This commit is contained in:
Sergey Reshetnyak 2015-03-29 13:11:54 +03:00
parent bfa73fcc5f
commit 4eade5480e
10 changed files with 47 additions and 159 deletions

View File

@ -42,7 +42,6 @@ class Context(context.RequestContext):
roles=None,
is_admin=None,
remote_semaphore=None,
auth_uri=None,
resource_uuid=None,
current_instance_info=None,
request_id=None,
@ -64,10 +63,6 @@ class Context(context.RequestContext):
self.remote_semaphore = remote_semaphore or semaphore.Semaphore(
CONF.cluster_remote_threshold)
self.roles = roles
if auth_uri:
self.auth_uri = auth_uri
else:
self.auth_uri = _get_auth_uri()
if overwrite or not hasattr(context._request_store, 'context'):
self.update_store()
@ -87,7 +82,6 @@ class Context(context.RequestContext):
self.roles,
self.is_admin,
self.remote_semaphore,
self.auth_uri,
self.resource_uuid,
self.current_instance_info,
self.request_id,
@ -105,7 +99,6 @@ class Context(context.RequestContext):
'project_name': self.tenant_name,
'is_admin': self.is_admin,
'roles': self.roles,
'auth_uri': self.auth_uri,
'resource_uuid': self.resource_uuid,
'request_id': self.request_id,
}
@ -167,28 +160,6 @@ def set_ctx(new_ctx):
setattr(context._request_store, 'context', new_ctx)
def _get_auth_uri():
if CONF.keystone_authtoken.auth_uri is not None:
auth_uri = CONF.keystone_authtoken.auth_uri
else:
if CONF.keystone_authtoken.identity_uri is not None:
identity_uri = CONF.keystone_authtoken.identity_uri
else:
host = CONF.keystone_authtoken.auth_host
port = CONF.keystone_authtoken.auth_port
protocol = CONF.keystone_authtoken.auth_protocol
identity_uri = '%s://%s:%s' % (protocol, host, port)
if CONF.use_identity_api_v3 is False:
auth_version = 'v2.0'
else:
auth_version = 'v3'
auth_uri = '%s/%s' % (identity_uri, auth_version)
return auth_uri
def _wrapper(ctx, thread_description, thread_group, func, *args, **kwargs):
try:
set_ctx(ctx)

View File

@ -156,5 +156,4 @@ def use_os_admin_auth_token(cluster):
ctx.tenant_id = cluster.tenant_id
client = keystone.client_for_admin_from_trust(cluster.trust_id)
ctx.auth_token = client.auth_token
ctx.service_catalog = json.dumps(
client.service_catalog.catalog['catalog'])
ctx.service_catalog = json.dumps(client.service_catalog.get_data())

View File

@ -18,9 +18,7 @@ from oslo_config import cfg
import six
from six.moves.urllib import parse as urlparse
from sahara import context
from sahara.utils.openstack import base as clients_base
from sahara.utils.openstack import keystone as k
CONF = cfg.CONF
@ -35,8 +33,7 @@ def retrieve_auth_url():
Hadoop Swift library doesn't support keystone v3 api.
"""
auth_url = clients_base.url_for(context.current().service_catalog,
'identity')
auth_url = clients_base.retrieve_auth_url()
info = urlparse.urlparse(auth_url)
if CONF.use_domain_for_proxy_users:
@ -56,22 +53,6 @@ def retrieve_auth_url():
url=url)
def retrieve_preauth_url():
'''This function returns the storage URL for Swift in the current project.
:returns: The storage URL for the current project's Swift store, or None
if it can't be found.
'''
client = k.client()
catalog = clients_base.execute_with_retries(
client.service_catalog.get_endpoints, 'object-store')
for ep in catalog.get('object-store'):
if ep.get('interface') == 'public':
return ep.get('url')
return None
def inject_swift_url_suffix(url):
if isinstance(url, six.string_types) and url.startswith("swift://"):
u = urlparse.urlparse(url)

View File

@ -33,7 +33,7 @@ SERVICE_SPECIFIC = ["auth.url", "tenant",
class SwiftIntegrationTestCase(base.SaharaTestCase):
@mock.patch('sahara.utils.openstack.base.url_for')
@mock.patch('sahara.utils.openstack.base.retrieve_auth_url')
def test_get_swift_configs(self, url_for_mock):
url_for_mock.return_value = 'http://localhost:5000/v2.0'
self.setup_context(tenant_name='test_tenant')

View File

@ -25,7 +25,7 @@ class SwiftUtilsTest(testbase.SaharaTestCase):
super(SwiftUtilsTest, self).setUp()
self.override_config('use_identity_api_v3', True)
@mock.patch('sahara.utils.openstack.base.url_for')
@mock.patch('sahara.utils.openstack.base.retrieve_auth_url')
def test_retrieve_auth_url(self, url_for_mock):
correct = "https://127.0.0.1:8080/v2.0/"
@ -41,7 +41,7 @@ class SwiftUtilsTest(testbase.SaharaTestCase):
_assert("https://127.0.0.1:8080/v42/")
_assert("https://127.0.0.1:8080/foo")
@mock.patch('sahara.utils.openstack.base.url_for')
@mock.patch('sahara.utils.openstack.base.retrieve_auth_url')
def test_retrieve_auth_url_without_port(self, url_for_mock):
correct = "https://127.0.0.1/v2.0/"

View File

@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import functools
import random
import fixtures
@ -23,7 +22,6 @@ import testtools
from sahara import context
from sahara import exceptions as ex
from sahara.tests.unit import base as test_base
rnd = random.Random()
@ -137,31 +135,3 @@ class ContextTest(testtools.TestCase):
class TestException(Exception):
pass
class GetAuthURITest(test_base.SaharaTestCase):
def setUp(self):
super(GetAuthURITest, self).setUp()
self.override_auth_config = functools.partial(
self.override_config, group='keystone_authtoken')
def test_get_auth_url_from_auth_uri_param(self):
self.override_auth_config('auth_uri', 'http://pony:5000/v2.0')
self.assertEqual('http://pony:5000/v2.0', context._get_auth_uri())
def test_get_auth_uri_from_identity_uri(self):
self.override_auth_config('identity_uri', 'http://spam:35357')
self.assertEqual('http://spam:35357/v3', context._get_auth_uri())
self.override_config('use_identity_api_v3', False)
self.assertEqual('http://spam:35357/v2.0', context._get_auth_uri())
def test_get_auth_uri_from_auth_params(self):
self.override_auth_config('auth_host', 'eggs')
self.override_auth_config('auth_port', 12345)
self.override_auth_config('auth_protocol', 'http')
self.assertEqual('http://eggs:12345/v3', context._get_auth_uri())
self.override_config('use_identity_api_v3', False)
self.assertEqual('http://eggs:12345/v2.0', context._get_auth_uri())

View File

@ -58,10 +58,10 @@ class AuthUrlTest(testbase.SaharaTestCase):
def test_retrieve_auth_url_api_v3(self):
self.override_config('use_identity_api_v3', True)
correct = "https://127.0.0.1:8080/v3/"
correct = "https://127.0.0.1:8080/v3"
def _assert(uri):
self.setup_context(auth_uri=uri)
self.override_config('auth_uri', uri, 'keystone_authtoken')
self.assertEqual(correct, base.retrieve_auth_url())
_assert("%s/" % correct)
@ -74,12 +74,14 @@ class AuthUrlTest(testbase.SaharaTestCase):
_assert("https://127.0.0.1:8080/v42")
_assert("https://127.0.0.1:8080/v42/")
def test_retrieve_auth_url_api_v3_without_port(self):
@mock.patch("sahara.utils.openstack.base.url_for")
def test_retrieve_auth_url_api_v3_without_port(self, mock_url_for):
self.override_config('use_identity_api_v3', True)
correct = "https://127.0.0.1/v3/"
self.setup_context(service_catalog=True)
correct = "https://127.0.0.1/v3"
def _assert(uri):
self.setup_context(auth_uri=uri)
mock_url_for.return_value = uri
self.assertEqual(correct, base.retrieve_auth_url())
_assert("%s/" % correct)
@ -94,10 +96,10 @@ class AuthUrlTest(testbase.SaharaTestCase):
def test_retrieve_auth_url_api_v20(self):
self.override_config('use_identity_api_v3', False)
correct = "https://127.0.0.1:8080/v2.0/"
correct = "https://127.0.0.1:8080/v2.0"
def _assert(uri):
self.setup_context(auth_uri=uri)
self.override_config('auth_uri', uri, 'keystone_authtoken')
self.assertEqual(correct, base.retrieve_auth_url())
_assert("%s/" % correct)
@ -110,12 +112,14 @@ class AuthUrlTest(testbase.SaharaTestCase):
_assert("https://127.0.0.1:8080/v42")
_assert("https://127.0.0.1:8080/v42/")
def test_retrieve_auth_url_api_v20_without_port(self):
@mock.patch("sahara.utils.openstack.base.url_for")
def test_retrieve_auth_url_api_v20_without_port(self, mock_url_for):
self.override_config('use_identity_api_v3', False)
correct = "https://127.0.0.1/v2.0/"
self.setup_context(service_catalog=True)
correct = "https://127.0.0.1/v2.0"
def _assert(uri):
self.setup_context(auth_uri=uri)
mock_url_for.return_value = uri
self.assertEqual(correct, base.retrieve_auth_url())
_assert("%s/" % correct)

View File

@ -29,6 +29,8 @@ class FakeImage(object):
class TestImages(base.SaharaTestCase):
@mock.patch('sahara.utils.openstack.base.url_for', return_value='')
def test_list_registered_images(self, url_for_mock):
self.override_config('auth_uri', 'https://127.0.0.1:8080/v3/',
'keystone_authtoken')
some_images = [
FakeImage('foo', ['bar', 'baz'], 'test'),
FakeImage('baz', [], 'test'),

View File

@ -13,6 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from keystoneclient import exceptions as keystone_ex
from keystoneclient import service_catalog as keystone_service_catalog
from oslo_config import cfg
from oslo_log import log as logging
from oslo_serialization import jsonutils as json
@ -20,7 +22,6 @@ from six.moves.urllib import parse as urlparse
from sahara import context
from sahara import exceptions as ex
from sahara.i18n import _
from sahara.i18n import _LE
from sahara.i18n import _LW
@ -47,74 +48,32 @@ CONF.register_group(retries)
CONF.register_opts(opts, group=retries)
def url_for(service_catalog, service_type, admin=False, endpoint_type=None):
if not endpoint_type:
endpoint_type = 'publicURL'
if admin:
endpoint_type = 'adminURL'
service = _get_service_from_catalog(service_catalog, service_type)
if service:
endpoints = service['endpoints']
if CONF.os_region_name:
endpoints = [e for e in endpoints
if e['region'] == CONF.os_region_name]
def url_for(service_catalog=None, service_type='identity',
endpoint_type='publicURL'):
if not service_catalog:
service_catalog = context.current().service_catalog
try:
return _get_endpoint_url(endpoints, endpoint_type)
except Exception:
raise ex.SystemError(
_("Endpoint with type %(type)s is not found for service "
"%(service)s")
% {'type': endpoint_type,
'service': service_type})
else:
raise ex.SystemError(
_('Service "%s" not found in service catalog') % service_type)
def _get_service_from_catalog(catalog, service_type):
if catalog:
catalog = json.loads(catalog)
for service in catalog:
if service['type'] == service_type:
return service
return None
def _get_endpoint_url(endpoints, endpoint_type):
if 'interface' in endpoints[0]:
endpoint_type = endpoint_type[0:-3]
for endpoint in endpoints:
if endpoint['interface'] == endpoint_type:
return endpoint['url']
return _get_case_insensitive(endpoints[0], endpoint_type)
def _get_case_insensitive(dictionary, key):
for k, v in dictionary.items():
if str(k).lower() == str(key).lower():
return v
# this will raise an exception as usual if key was not found
return dictionary[key]
return keystone_service_catalog.ServiceCatalogV2(
{'serviceCatalog': json.loads(service_catalog)}).url_for(
service_type=service_type, endpoint_type=endpoint_type,
region_name=CONF.os_region_name)
except keystone_ex.EndpointNotFound:
ctx = context.current()
return keystone_service_catalog.ServiceCatalogV3(
ctx.auth_token,
{'catalog': json.loads(service_catalog)}).url_for(
service_type=service_type, endpoint_type=endpoint_type,
region_name=CONF.os_region_name)
def retrieve_auth_url():
info = urlparse.urlparse(context.current().auth_uri)
version = 'v3' if CONF.use_identity_api_v3 else 'v2.0'
if info.port:
return "%s://%s:%s/%s/" % (info.scheme,
info.hostname,
info.port,
version)
ctx = context.current()
if ctx.service_catalog:
info = urlparse.urlparse(url_for(ctx.service_catalog, 'identity'))
else:
return "%s://%s/%s/" % (info.scheme,
info.hostname,
version)
info = urlparse.urlparse(CONF.keystone_authtoken.auth_uri)
return "%s://%s/%s" % (info[:2] + (version,))
def execute_with_retries(method, *args, **kwargs):

View File

@ -18,6 +18,7 @@ import swiftclient
from sahara.swift import swift_helper as sh
from sahara.swift import utils as su
from sahara.utils.openstack import base
from sahara.utils.openstack import keystone as k
opts = [
@ -76,7 +77,8 @@ def client_from_token(token):
return swiftclient.Connection(auth_version='2.0',
cacert=CONF.swift.ca_file,
insecure=CONF.swift.api_insecure,
preauthurl=su.retrieve_preauth_url(),
preauthurl=base.url_for(
service_type="object-store"),
preauthtoken=token,
retries=CONF.retries.retries_number,
retry_on_ratelimit=True,