Add config option for keystone admin roles
RADOS Gateway supports setting keystone operator and admin roles. RADOS Gateway requires admin roles for keystone users to change their user quota. Regular operator/member roles are not allowed to do so. The lack of this config option prevents swift users with admin roles from being able to set their quotas. Therefore, a config option 'admin-roles' is now added to the charm to map to 'rgw keystone accepted admin roles' RADOS Gateway config. Please note that this is only effective from Luminous Ceph Release. Change-Id: Ic0b9aa39eef9fbc6c43eb4e66ab72d90787c2017 Closes-Bug: #1831577
This commit is contained in:
parent
c6ac5946ba
commit
fb2f757494
@ -121,10 +121,16 @@ options:
|
|||||||
# Keystone integration
|
# Keystone integration
|
||||||
operator-roles:
|
operator-roles:
|
||||||
type: string
|
type: string
|
||||||
default: "Member,Admin"
|
default: "Member"
|
||||||
description: |
|
description: |
|
||||||
Comma-separated list of Swift operator roles; used when integrating with
|
Comma-separated list of Swift operator roles; used when integrating with
|
||||||
OpenStack Keystone.
|
OpenStack Keystone.
|
||||||
|
admin-roles:
|
||||||
|
type: string
|
||||||
|
default: "Admin"
|
||||||
|
description: |
|
||||||
|
Comma-separated list of Swift admin roles; used when integrating with
|
||||||
|
OpenStack Keystone. Admin roles can set the user quota amount.
|
||||||
region:
|
region:
|
||||||
type: string
|
type: string
|
||||||
default: RegionOne
|
default: RegionOne
|
||||||
|
@ -96,7 +96,13 @@ class IdentityServiceContext(context.IdentityServiceContext):
|
|||||||
ctxt.pop('admin_domain_id')
|
ctxt.pop('admin_domain_id')
|
||||||
|
|
||||||
ctxt['auth_type'] = 'keystone'
|
ctxt['auth_type'] = 'keystone'
|
||||||
|
if cmp_pkgrevno('radosgw', "11.0.0") >= 0:
|
||||||
ctxt['user_roles'] = config('operator-roles')
|
ctxt['user_roles'] = config('operator-roles')
|
||||||
|
ctxt['admin_roles'] = config('admin-roles')
|
||||||
|
else:
|
||||||
|
ctxt['user_roles'] = config('operator-roles')
|
||||||
|
if config('admin-roles'):
|
||||||
|
ctxt['user_roles'] += (',' + config('admin-roles'))
|
||||||
ctxt['cache_size'] = config('cache-size')
|
ctxt['cache_size'] = config('cache-size')
|
||||||
if self.context_complete(ctxt):
|
if self.context_complete(ctxt):
|
||||||
return ctxt
|
return ctxt
|
||||||
|
@ -298,11 +298,15 @@ def identity_joined(relid=None):
|
|||||||
(canonical_url(CONFIGS, INTERNAL), port)
|
(canonical_url(CONFIGS, INTERNAL), port)
|
||||||
public_url = '%s:%s/swift/v1' % \
|
public_url = '%s:%s/swift/v1' % \
|
||||||
(canonical_url(CONFIGS, PUBLIC), port)
|
(canonical_url(CONFIGS, PUBLIC), port)
|
||||||
|
roles = [x for x in [config('operator-roles'), config('admin-roles')] if x]
|
||||||
|
requested_roles = ''
|
||||||
|
if roles:
|
||||||
|
requested_roles = ','.join(roles) if len(roles) > 1 else roles[0]
|
||||||
relation_set(service='swift',
|
relation_set(service='swift',
|
||||||
region=config('region'),
|
region=config('region'),
|
||||||
public_url=public_url, internal_url=internal_url,
|
public_url=public_url, internal_url=internal_url,
|
||||||
admin_url=admin_url,
|
admin_url=admin_url,
|
||||||
requested_roles=config('operator-roles'),
|
requested_roles=requested_roles,
|
||||||
relation_id=relid)
|
relation_id=relid)
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@ rgw keystone admin project = {{ admin_tenant_name }}
|
|||||||
rgw keystone admin token = {{ admin_token }}
|
rgw keystone admin token = {{ admin_token }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
rgw keystone accepted roles = {{ user_roles }}
|
rgw keystone accepted roles = {{ user_roles }}
|
||||||
|
rgw keystone accepted admin roles = {{ admin_roles }}
|
||||||
rgw keystone token cache size = {{ cache_size }}
|
rgw keystone token cache size = {{ cache_size }}
|
||||||
rgw s3 auth use keystone = true
|
rgw s3 auth use keystone = true
|
||||||
rgw s3 auth order = local, external
|
rgw s3 auth order = local, external
|
||||||
|
@ -85,8 +85,12 @@ class IdentityServiceContextTest(CharmTestCase):
|
|||||||
@patch.object(charmhelpers.contrib.openstack.context, 'log')
|
@patch.object(charmhelpers.contrib.openstack.context, 'log')
|
||||||
def test_ids_ctxt(self, _log, _rids, _runits, _rget, _ctxt_comp,
|
def test_ids_ctxt(self, _log, _rids, _runits, _rget, _ctxt_comp,
|
||||||
_format_ipv6_addr, _filter_installed_packages,
|
_format_ipv6_addr, _filter_installed_packages,
|
||||||
jewel_installed=False):
|
jewel_installed=False, cmp_pkgrevno_side_effects=None):
|
||||||
|
self.cmp_pkgrevno.side_effect = (cmp_pkgrevno_side_effects
|
||||||
|
if cmp_pkgrevno_side_effects
|
||||||
|
else [-1, -1])
|
||||||
self.test_config.set('operator-roles', 'Babel')
|
self.test_config.set('operator-roles', 'Babel')
|
||||||
|
self.test_config.set('admin-roles', 'Dart')
|
||||||
self.test_config.set('cache-size', '42')
|
self.test_config.set('cache-size', '42')
|
||||||
self.test_relation.set({'admin_token': 'ubuntutesting'})
|
self.test_relation.set({'admin_token': 'ubuntutesting'})
|
||||||
self.relation_ids.return_value = ['identity-service:5']
|
self.relation_ids.return_value = ['identity-service:5']
|
||||||
@ -95,9 +99,6 @@ class IdentityServiceContextTest(CharmTestCase):
|
|||||||
_rids.return_value = 'rid1'
|
_rids.return_value = 'rid1'
|
||||||
_runits.return_value = 'runit'
|
_runits.return_value = 'runit'
|
||||||
_ctxt_comp.return_value = True
|
_ctxt_comp.return_value = True
|
||||||
self.cmp_pkgrevno.return_value = -1
|
|
||||||
if jewel_installed:
|
|
||||||
self.cmp_pkgrevno.return_value = 0
|
|
||||||
id_data = {
|
id_data = {
|
||||||
'service_port': 9876,
|
'service_port': 9876,
|
||||||
'service_host': '127.0.0.4',
|
'service_host': '127.0.0.4',
|
||||||
@ -127,8 +128,12 @@ class IdentityServiceContextTest(CharmTestCase):
|
|||||||
'service_host': '127.0.0.4',
|
'service_host': '127.0.0.4',
|
||||||
'service_port': 9876,
|
'service_port': 9876,
|
||||||
'service_protocol': 'http',
|
'service_protocol': 'http',
|
||||||
'user_roles': 'Babel',
|
|
||||||
}
|
}
|
||||||
|
if cmp_pkgrevno_side_effects and cmp_pkgrevno_side_effects[1] >= 0:
|
||||||
|
expect['user_roles'] = 'Babel'
|
||||||
|
expect['admin_roles'] = 'Dart'
|
||||||
|
else:
|
||||||
|
expect['user_roles'] = 'Babel,Dart'
|
||||||
if jewel_installed:
|
if jewel_installed:
|
||||||
expect['auth_keystone_v3_supported'] = True
|
expect['auth_keystone_v3_supported'] = True
|
||||||
self.assertEqual(expect, ids_ctxt())
|
self.assertEqual(expect, ids_ctxt())
|
||||||
@ -145,6 +150,7 @@ class IdentityServiceContextTest(CharmTestCase):
|
|||||||
self, _log, _rids, _runits, _rget, _ctxt_comp, _format_ipv6_addr,
|
self, _log, _rids, _runits, _rget, _ctxt_comp, _format_ipv6_addr,
|
||||||
_filter_installed_packages, jewel_installed=False):
|
_filter_installed_packages, jewel_installed=False):
|
||||||
self.test_config.set('operator-roles', 'Babel')
|
self.test_config.set('operator-roles', 'Babel')
|
||||||
|
self.test_config.set('admin-roles', 'Dart')
|
||||||
self.test_config.set('cache-size', '42')
|
self.test_config.set('cache-size', '42')
|
||||||
self.test_relation.set({'admin_token': 'ubuntutesting'})
|
self.test_relation.set({'admin_token': 'ubuntutesting'})
|
||||||
self.relation_ids.return_value = ['identity-service:5']
|
self.relation_ids.return_value = ['identity-service:5']
|
||||||
@ -183,7 +189,7 @@ class IdentityServiceContextTest(CharmTestCase):
|
|||||||
'service_host': '127.0.0.4',
|
'service_host': '127.0.0.4',
|
||||||
'service_port': 9876,
|
'service_port': 9876,
|
||||||
'service_protocol': 'http',
|
'service_protocol': 'http',
|
||||||
'user_roles': 'Babel',
|
'user_roles': 'Babel,Dart',
|
||||||
}
|
}
|
||||||
if jewel_installed:
|
if jewel_installed:
|
||||||
expect['auth_keystone_v3_supported'] = True
|
expect['auth_keystone_v3_supported'] = True
|
||||||
@ -201,6 +207,7 @@ class IdentityServiceContextTest(CharmTestCase):
|
|||||||
self, _log, _rids, _runits, _rget, _ctxt_comp, _format_ipv6_addr,
|
self, _log, _rids, _runits, _rget, _ctxt_comp, _format_ipv6_addr,
|
||||||
_filter_installed_packages, jewel_installed=False):
|
_filter_installed_packages, jewel_installed=False):
|
||||||
self.test_config.set('operator-roles', 'Babel')
|
self.test_config.set('operator-roles', 'Babel')
|
||||||
|
self.test_config.set('admin-roles', 'Dart')
|
||||||
self.test_config.set('cache-size', '42')
|
self.test_config.set('cache-size', '42')
|
||||||
self.test_relation.set({'admin_token': 'ubuntutesting'})
|
self.test_relation.set({'admin_token': 'ubuntutesting'})
|
||||||
self.relation_ids.return_value = ['identity-service:5']
|
self.relation_ids.return_value = ['identity-service:5']
|
||||||
@ -244,14 +251,19 @@ class IdentityServiceContextTest(CharmTestCase):
|
|||||||
'service_host': '127.0.0.4',
|
'service_host': '127.0.0.4',
|
||||||
'service_port': 9876,
|
'service_port': 9876,
|
||||||
'service_protocol': 'http',
|
'service_protocol': 'http',
|
||||||
'user_roles': 'Babel',
|
'user_roles': 'Babel,Dart',
|
||||||
}
|
}
|
||||||
if jewel_installed:
|
if jewel_installed:
|
||||||
expect['auth_keystone_v3_supported'] = True
|
expect['auth_keystone_v3_supported'] = True
|
||||||
self.assertEqual(expect, ids_ctxt())
|
self.assertEqual(expect, ids_ctxt())
|
||||||
|
|
||||||
def test_ids_ctxt_jewel(self):
|
def test_ids_ctxt_jewel(self):
|
||||||
self.test_ids_ctxt(jewel_installed=True)
|
self.test_ids_ctxt(jewel_installed=True,
|
||||||
|
cmp_pkgrevno_side_effects=[0, -1])
|
||||||
|
|
||||||
|
def test_ids_ctxt_luminous(self):
|
||||||
|
self.test_ids_ctxt(jewel_installed=True,
|
||||||
|
cmp_pkgrevno_side_effects=[1, 0])
|
||||||
|
|
||||||
@patch.object(charmhelpers.contrib.openstack.context,
|
@patch.object(charmhelpers.contrib.openstack.context,
|
||||||
'filter_installed_packages', return_value=['absent-pkg'])
|
'filter_installed_packages', return_value=['absent-pkg'])
|
||||||
|
@ -244,22 +244,32 @@ class CephRadosGWTests(CharmTestCase):
|
|||||||
@patch('charmhelpers.contrib.openstack.ip.resolve_address')
|
@patch('charmhelpers.contrib.openstack.ip.resolve_address')
|
||||||
@patch('charmhelpers.contrib.openstack.ip.config')
|
@patch('charmhelpers.contrib.openstack.ip.config')
|
||||||
def test_identity_joined(self, _config, _resolve_address):
|
def test_identity_joined(self, _config, _resolve_address):
|
||||||
|
|
||||||
|
def _test_identify_joined(expected):
|
||||||
self.related_units = ['unit/0']
|
self.related_units = ['unit/0']
|
||||||
self.cmp_pkgrevno.return_value = 1
|
self.cmp_pkgrevno.return_value = 1
|
||||||
_resolve_address.return_value = 'myserv'
|
_resolve_address.return_value = 'myserv'
|
||||||
_config.side_effect = self.test_config.get
|
_config.side_effect = self.test_config.get
|
||||||
self.test_config.set('region', 'region1')
|
self.test_config.set('region', 'region1')
|
||||||
self.test_config.set('operator-roles', 'admin')
|
|
||||||
ceph_hooks.identity_joined(relid='rid')
|
ceph_hooks.identity_joined(relid='rid')
|
||||||
self.relation_set.assert_called_with(
|
self.relation_set.assert_called_with(
|
||||||
service='swift',
|
service='swift',
|
||||||
region='region1',
|
region='region1',
|
||||||
public_url='http://myserv:80/swift/v1',
|
public_url='http://myserv:80/swift/v1',
|
||||||
internal_url='http://myserv:80/swift/v1',
|
internal_url='http://myserv:80/swift/v1',
|
||||||
requested_roles='admin',
|
requested_roles=expected,
|
||||||
relation_id='rid',
|
relation_id='rid',
|
||||||
admin_url='http://myserv:80/swift')
|
admin_url='http://myserv:80/swift')
|
||||||
|
|
||||||
|
inputs = [{'operator': 'foo', 'admin': 'bar', 'expected': 'foo,bar'},
|
||||||
|
{'operator': 'foo', 'expected': 'foo'},
|
||||||
|
{'admin': 'bar', 'expected': 'bar'},
|
||||||
|
{'expected': ''}]
|
||||||
|
for input in inputs:
|
||||||
|
self.test_config.set('operator-roles', input.get('operator', ''))
|
||||||
|
self.test_config.set('admin-roles', input.get('admin', ''))
|
||||||
|
_test_identify_joined(input['expected'])
|
||||||
|
|
||||||
@patch('charmhelpers.contrib.openstack.ip.service_name',
|
@patch('charmhelpers.contrib.openstack.ip.service_name',
|
||||||
lambda *args: 'ceph-radosgw')
|
lambda *args: 'ceph-radosgw')
|
||||||
@patch('charmhelpers.contrib.openstack.ip.is_clustered')
|
@patch('charmhelpers.contrib.openstack.ip.is_clustered')
|
||||||
|
Loading…
Reference in New Issue
Block a user