Fix Keystone v3 auth for swift-proxy
No need for refresh of proxy-server.conf template for Mitaka. Update template for Kilo and later to make use of domain_name and project_name parameters instead of domain_id and project_id parameters. The current template sets up auth to user in default domain but project in service domain. This does not work with service domain layout. Do not request configured operator_roles roles from Keystone. From which roles swift-proxy should accept requests are still configured in proxy-server.conf, but requesting and setting up these roles for the s3_swift user in Keystone is incorrect behaviour. Register required relation data for identity-service immediatelly when relation to 'identity-service' exists. Do not postpone registration until context is complete which may cause the swift-proxy unit marking itself ready while still being in a unconfigured state. Add tests to verify configuration and operation of swift-proxy when using Keystone v3 auth. Change-Id: I8bf182a9256f96af50e4cc37505d9c0ca3d62e47 Closes-Bug: 1646765
This commit is contained in:
parent
c4cd0699c7
commit
7c24ae8128
|
@ -194,7 +194,6 @@ def keystone_joined(relid=None):
|
|||
public_url = ('%s:%s/v1/AUTH_$(tenant_id)s' %
|
||||
(canonical_url(CONFIGS, PUBLIC), port))
|
||||
region = config('region')
|
||||
roles = config('operator-roles')
|
||||
|
||||
s3_public_url = ('%s:%s' %
|
||||
(canonical_url(CONFIGS, PUBLIC), port))
|
||||
|
@ -202,7 +201,7 @@ def keystone_joined(relid=None):
|
|||
(canonical_url(CONFIGS, INTERNAL), port))
|
||||
s3_admin_url = '%s:%s' % (canonical_url(CONFIGS, ADMIN), port)
|
||||
|
||||
relation_set(requested_roles=roles, relation_id=relid,
|
||||
relation_set(relation_id=relid,
|
||||
region=None, public_url=None,
|
||||
internal_url=None, admin_url=None, service=None,
|
||||
swift_service='swift', swift_region=region,
|
||||
|
|
|
@ -14,7 +14,6 @@ from charmhelpers.core.hookenv import (
|
|||
from charmhelpers.contrib.openstack.context import (
|
||||
OSContextGenerator,
|
||||
ApacheSSLContext as SSLContext,
|
||||
context_complete,
|
||||
IdentityServiceContext,
|
||||
)
|
||||
from charmhelpers.contrib.hahelpers.cluster import (
|
||||
|
@ -183,8 +182,11 @@ class SwiftIdentityContext(OSContextGenerator):
|
|||
'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)
|
||||
ks_auth['admin_domain_name'] = relation_get(
|
||||
'service_domain', unit, relid)
|
||||
ks_auth['admin_tenant_name'] = relation_get(
|
||||
'service_tenant', unit, relid)
|
||||
ctxt.update(ks_auth)
|
||||
|
||||
if config('prefer-ipv6'):
|
||||
for key in ['keystone_host', 'service_host']:
|
||||
|
|
|
@ -87,9 +87,9 @@ 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 }}
|
||||
project_domain_name = {{ admin_domain_name }}
|
||||
user_domain_name = {{ admin_domain_name }}
|
||||
project_name = {{ admin_tenant_name }}
|
||||
{% else -%}
|
||||
admin_tenant_name = {{ service_tenant }}
|
||||
admin_user = {{ service_user }}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
import amulet
|
||||
import swiftclient
|
||||
import time
|
||||
|
||||
from charmhelpers.contrib.openstack.amulet.deployment import (
|
||||
OpenStackAmuletDeployment
|
||||
|
@ -275,7 +276,6 @@ class SwiftProxyBasicDeployment(OpenStackAmuletDeployment):
|
|||
's3_internal_url': u.valid_url,
|
||||
's3_admin_url': u.valid_url,
|
||||
'private-address': u.valid_ip,
|
||||
'requested_roles': 'Member,Admin',
|
||||
}
|
||||
|
||||
ret = u.validate_relation_data(unit, relation, expected)
|
||||
|
@ -386,9 +386,10 @@ class SwiftProxyBasicDeployment(OpenStackAmuletDeployment):
|
|||
message = "swift config error: {}".format(ret)
|
||||
amulet.raise_status(amulet.FAIL, msg=message)
|
||||
|
||||
def test_302_proxy_server_config(self):
|
||||
def test_302_proxy_server_config(self, auth_api_version='2.0'):
|
||||
"""Verify the data in the proxy-server config file."""
|
||||
u.log.debug('Checking swift proxy-server config...')
|
||||
u.log.debug("Checking swift proxy-server config auth_api_version={}..."
|
||||
"".format(auth_api_version))
|
||||
unit = self.swift_proxy_sentry
|
||||
conf = '/etc/swift/proxy-server.conf'
|
||||
keystone_relation = self.keystone_sentry.relation(
|
||||
|
@ -453,26 +454,45 @@ class SwiftProxyBasicDeployment(OpenStackAmuletDeployment):
|
|||
auth_protocol,
|
||||
auth_host,
|
||||
keystone_relation['service_port']),
|
||||
'admin_tenant_name': keystone_relation['service_tenant'],
|
||||
'admin_user': keystone_relation['service_username'],
|
||||
'admin_password': keystone_relation['service_password'],
|
||||
'delay_auth_decision': 'true',
|
||||
'signing_dir': '/var/cache/swift',
|
||||
'cache': 'swift.cache'
|
||||
},
|
||||
'filter:swift3': {'use': 'egg:swift3#swift3'}
|
||||
}
|
||||
if auth_api_version == '2.0':
|
||||
expected['filter:authtoken'].update({
|
||||
'admin_tenant_name': keystone_relation['service_tenant'],
|
||||
'admin_user': keystone_relation['service_username'],
|
||||
'admin_password': keystone_relation['service_password'],
|
||||
})
|
||||
|
||||
if self._get_openstack_release() >= self.trusty_kilo:
|
||||
# Kilo and later
|
||||
expected['filter:authtoken'].update({
|
||||
'paste.filter_factory': 'keystonemiddleware.auth_token:'
|
||||
'filter_factory',
|
||||
'identity_uri': '{}://{}:{}'.format(
|
||||
auth_protocol,
|
||||
auth_host,
|
||||
keystone_relation['auth_port']),
|
||||
})
|
||||
if auth_api_version == '3':
|
||||
expected['filter:authtoken'].update({
|
||||
'auth_url': '{}://{}:{}'.format(
|
||||
auth_protocol,
|
||||
auth_host,
|
||||
keystone_relation['auth_port']),
|
||||
'auth_plugin': 'password',
|
||||
'username': keystone_relation['service_username'],
|
||||
'password': keystone_relation['service_password'],
|
||||
'project_domain_name': keystone_relation['service_domain'],
|
||||
'user_domain_name': keystone_relation['service_domain'],
|
||||
'project_name': keystone_relation['service_tenant'],
|
||||
})
|
||||
else:
|
||||
expected['filter:authtoken'].update({
|
||||
'identity_uri': '{}://{}:{}'.format(
|
||||
auth_protocol,
|
||||
auth_host,
|
||||
keystone_relation['auth_port']),
|
||||
})
|
||||
expected['filter:s3token'] = {
|
||||
# No section commonality with J and earlier
|
||||
'paste.filter_factory': 'keystonemiddleware.s3_token'
|
||||
|
@ -553,6 +573,58 @@ class SwiftProxyBasicDeployment(OpenStackAmuletDeployment):
|
|||
u.delete_resource(self.glance.images, img_id, msg="glance image")
|
||||
u.log.info('OK')
|
||||
|
||||
def _set_auth_api_version(self, api_version, retry_count=5):
|
||||
"""Change Keystone preferred-api-version, wait for: propagation to
|
||||
relation data, update of service configuration file and restart of
|
||||
services on swift-proxy unit."""
|
||||
configs = {'keystone': {'preferred-api-version': api_version}}
|
||||
super(SwiftProxyBasicDeployment, self)._configure_services(configs)
|
||||
mtime = u.get_sentry_time(self.swift_proxy_sentry)
|
||||
for i in range(retry_count, -1, -1):
|
||||
ks_gl_rel = self.keystone_sentry.relation(
|
||||
'identity-service', 'glance:identity-service')
|
||||
ks_sw_rel = self.keystone_sentry.relation(
|
||||
'identity-service', 'swift-proxy:identity-service')
|
||||
if not (ks_gl_rel['api_version'] == api_version and
|
||||
ks_sw_rel['api_version'] == api_version):
|
||||
u.log.info("change of api_version not propagated yet "
|
||||
"retries left: '%d' "
|
||||
"glance:identity-service api_version: '%s' "
|
||||
"swift-proxy:identity-service api_version: '%s' "
|
||||
% (i,
|
||||
ks_gl_rel['api_version'],
|
||||
ks_sw_rel['api_version']))
|
||||
u.log.info("sleeping %d seconds..." % i)
|
||||
time.sleep(i)
|
||||
elif not u.validate_service_config_changed(
|
||||
self.swift_proxy_sentry,
|
||||
mtime,
|
||||
'swift-proxy-server',
|
||||
'/etc/swift/proxy-server.conf',
|
||||
sleep_time=i):
|
||||
msg = "swift-proxy-server didn't restart after change of "\
|
||||
"api_version"
|
||||
amulet.raise_status(amulet.FAIL, msg=msg)
|
||||
else:
|
||||
return True
|
||||
return False
|
||||
|
||||
def test_keystone_v3(self):
|
||||
"""Verify that the service is configured and operates correctly when
|
||||
using Keystone v3 auth."""
|
||||
os_release = self._get_openstack_release_string()
|
||||
if os_release < 'kilo':
|
||||
u.log.info('Skipping test, {} < kilo'.format(os_release))
|
||||
return
|
||||
u.log.info('Checking that service is configured and operate correctly '
|
||||
'when using Keystine v3 auth...')
|
||||
if not self._set_auth_api_version('3'):
|
||||
msg = "Unable to set auth_api_version to '3'"
|
||||
amulet.raise_status(amulet.FAIL, msg=msg)
|
||||
return
|
||||
self.test_302_proxy_server_config(auth_api_version='3')
|
||||
self.test_400_swift_backed_image_create()
|
||||
|
||||
def test_900_restart_on_config_change(self):
|
||||
"""Verify that the specified services are restarted when the config
|
||||
is changed."""
|
||||
|
|
|
@ -81,6 +81,7 @@ class SwiftIdentityContextTest(unittest.TestCase):
|
|||
'auth_port': '5000',
|
||||
'service_username': 'svcuser',
|
||||
'service_password': 'svcpasswd',
|
||||
'service_domain': 'service_domain',
|
||||
'service_tenant': 'svctenant',
|
||||
'service_port': 'svcport',
|
||||
'admin_token': 'token',
|
||||
|
@ -97,6 +98,8 @@ class SwiftIdentityContextTest(unittest.TestCase):
|
|||
self.assertEqual(ctxt()['api_version'], '3')
|
||||
self.assertEqual(ctxt()['admin_domain_id'], 'admin_dom_id')
|
||||
self.assertEqual(ctxt()['service_tenant_id'], 'svc_tenant_id')
|
||||
self.assertEqual(ctxt()['admin_domain_name'], 'service_domain')
|
||||
self.assertEqual(ctxt()['admin_tenant_name'], 'svctenant')
|
||||
|
||||
|
||||
class SwiftContextTestCase(unittest.TestCase):
|
||||
|
|
|
@ -106,7 +106,6 @@ class SwiftHooksTestCase(unittest.TestCase):
|
|||
public_url=None,
|
||||
region=None,
|
||||
relation_id=None,
|
||||
requested_roles='Operator,Monitor',
|
||||
s3_admin_url='http://swift-proxy:1234',
|
||||
s3_internal_url='http://swift-proxy:1234',
|
||||
s3_public_url='http://swift-proxy:1234',
|
||||
|
@ -163,7 +162,6 @@ class SwiftHooksTestCase(unittest.TestCase):
|
|||
public_url=None,
|
||||
region=None,
|
||||
relation_id=None,
|
||||
requested_roles='Operator,Monitor',
|
||||
s3_admin_url='http://swift-proxy:1234',
|
||||
s3_internal_url='http://swift-proxy:1234',
|
||||
s3_public_url='http://public.example.com:1234',
|
||||
|
|
Loading…
Reference in New Issue