Fix support for Keystone v3 API

Swift proxy is currently rejecting valid v3 tokens because it is
failing to validate them due to its credentials being in the v2
format and missing domain information. This change examines the
version of the API keystone has advertised down the identity-service
relation and configures the proxy conf appropriately

Change-Id: Id2215168ffbad1caf0e7203ded26c41913181306
Closes-Bug: 1624304
This commit is contained in:
Liam Young 2016-09-16 13:53:13 +00:00
parent a7d6349905
commit 5b8b04a213
3 changed files with 90 additions and 1 deletions

View File

@ -139,7 +139,7 @@ class SwiftIdentityContext(OSContextGenerator):
'auth_port': config('keystone-auth-port'),
'service_user': admin_user,
'service_password': admin_password,
'service_tenant': config('keystone-admin-tenant-name')
'service_tenant': config('keystone-admin-tenant-name'),
}
ctxt.update(ks_auth)
@ -168,7 +168,14 @@ class SwiftIdentityContext(OSContextGenerator):
unit, relid),
'admin_token': relation_get('admin_token',
unit, relid),
'api_version': relation_get('api_version',
unit, relid) or '2',
}
if ks_auth['api_version'] == '3':
ks_auth['admin_domain_id'] = relation_get(
'admin_domain_id', unit, relid)
ks_auth['service_tenant_id'] = relation_get(
'service_tenant_id', unit, relid)
if context_complete(ks_auth):
ctxt.update(ks_auth)

View File

@ -82,9 +82,19 @@ operator_roles = {{ operator_roles }}
paste.filter_factory = keystonemiddleware.auth_token:filter_factory
identity_uri = {{ auth_protocol }}://{{ keystone_host }}:{{ auth_port }}
auth_uri = {{ service_protocol }}://{{ service_host }}:{{ service_port }}
{% if api_version == '3' -%}
auth_plugin = password
auth_url = {{ auth_protocol }}://{{ keystone_host }}:{{ auth_port }}
username = {{ service_user }}
password = {{ service_password }}
user_domain_name = default
project_id = {{ service_tenant_id }}
project_domain_id = {{ admin_domain_id }}
{% else -%}
admin_tenant_name = {{ service_tenant }}
admin_user = {{ service_user }}
admin_password = {{ service_password }}
{% endif -%}
delay_auth_decision = {{ delay_auth_decision|lower }}
signing_dir = {{ signing_dir }}
cache = swift.cache

View File

@ -23,6 +23,78 @@ with mock.patch('charmhelpers.core.hookenv.config'):
import lib.swift_context as swift_context
class SwiftIdentityContextTest(unittest.TestCase):
@mock.patch('lib.swift_context.relation_get')
@mock.patch('lib.swift_context.related_units')
@mock.patch('lib.swift_context.relation_ids')
@mock.patch('lib.swift_context.IdentityServiceContext')
@mock.patch('lib.swift_context.determine_api_port')
@mock.patch('lib.swift_context.unit_get')
@mock.patch('lib.swift_context.get_host_ip')
@mock.patch('lib.swift_context.config')
def test_context_api_v2(self, mock_config, mock_get_host_ip,
mock_unit_get, mock_determine_api_port,
mock_IdentityServiceContext, mock_relation_ids,
mock_related_units, mock_relation_get):
_relinfo = {
'auth_protocol': 'http',
'service_protocol': 'http',
'auth_host': 'kshost',
'service_host': 'kshost',
'auth_port': '5000',
'service_username': 'svcuser',
'service_password': 'svcpasswd',
'service_tenant': 'svctenant',
'service_port': 'svcport',
'admin_token': 'token',
'api_version': None,
}
mock_config.return_value = None
mock_relation_ids.return_value = ['rid1']
mock_related_units.return_value = ['ksunit/0']
mock_relation_get.side_effect = lambda x, y, z: _relinfo[x]
ctxt = swift_context.SwiftIdentityContext()
self.assertEqual(ctxt()['api_version'], '2')
@mock.patch('lib.swift_context.relation_get')
@mock.patch('lib.swift_context.related_units')
@mock.patch('lib.swift_context.relation_ids')
@mock.patch('lib.swift_context.IdentityServiceContext')
@mock.patch('lib.swift_context.determine_api_port')
@mock.patch('lib.swift_context.unit_get')
@mock.patch('lib.swift_context.get_host_ip')
@mock.patch('lib.swift_context.config')
def test_context_api_v3(self, mock_config, mock_get_host_ip,
mock_unit_get, mock_determine_api_port,
mock_IdentityServiceContext, mock_relation_ids,
mock_related_units, mock_relation_get):
_relinfo = {
'auth_protocol': 'http',
'service_protocol': 'http',
'auth_host': 'kshost',
'service_host': 'kshost',
'auth_port': '5000',
'service_username': 'svcuser',
'service_password': 'svcpasswd',
'service_tenant': 'svctenant',
'service_port': 'svcport',
'admin_token': 'token',
'api_version': '3',
'admin_domain_id': 'admin_dom_id',
'service_tenant_id': 'svc_tenant_id',
}
self.maxDiff = None
mock_relation_ids.return_value = ['rid1']
mock_related_units.return_value = ['ksunit/0']
mock_relation_get.side_effect = lambda x, y, z: _relinfo[x]
mock_config.return_value = None
ctxt = swift_context.SwiftIdentityContext()
self.assertEqual(ctxt()['api_version'], '3')
self.assertEqual(ctxt()['admin_domain_id'], 'admin_dom_id')
self.assertEqual(ctxt()['service_tenant_id'], 'svc_tenant_id')
class SwiftContextTestCase(unittest.TestCase):
@mock.patch('lib.swift_context.config')