Add support for object_prefix permissions

The grammer for ceph osd capabilities shows that permissions can
be applied to a pool or to a object_prefix:

match   := [pool[=]<poolname> | object_prefix <prefix>]

This patch adds support for requesting object_prefix permissions on
a given set of prefixes.

http://docs.ceph.com/docs/firefly/man/8/ceph-authtool/#osd-capabilities

Partial-Bug: #1696073

Change-Id: I799f87fe2178ed7d3e44f14e2fa0683f917d2f0d
This commit is contained in:
Liam Young 2017-12-12 15:43:36 +00:00
parent 6ea5e98786
commit d94dc3e7b9
2 changed files with 107 additions and 1 deletions

View File

@ -187,6 +187,9 @@ def handle_add_permissions_to_key(request, service):
group = get_group(group_name=group_name)
service_obj = get_service_groups(service=service_name,
namespace=group_namespace)
if request.get('object-prefix-permissions'):
service_obj['object_prefix_perms'] = request.get(
'object-prefix-permissions')
format("Service object: {}".format(service_obj))
permission = request.get('group-permission') or "rwx"
if service_name not in group['services']:
@ -241,8 +244,13 @@ def pool_permission_list_for_service(service):
for permission, groups in permission_types.items():
permission = "allow {}".format(permission)
for group in groups:
for pool in service['groups'][group]['pools']:
for pool in service['groups'][group].get('pools', []):
permissions.append("{} pool={}".format(permission, pool))
for permission, prefixes in sorted(
service.get("object_prefix_perms", {}).items()):
for prefix in prefixes:
permissions.append("allow {} object_prefix {}".format(permission,
prefix))
return ["mon", "allow r", "osd", ', '.join(permissions)]

View File

@ -531,3 +531,101 @@ class CephBrokerTestCase(unittest.TestCase):
expect_service_name,
expect_service_obj,
expect_group_namespace)
@patch.object(ceph.broker, 'save_service')
@patch.object(ceph.broker, 'save_group')
@patch.object(ceph.broker, 'monitor_key_get')
@patch.object(ceph.broker, 'update_service_permissions')
def test_handle_add_permissions_to_key_obj_prefs(self,
mock_update_serv_perms,
mock_monitor_key_get,
mock_save_group,
mock_save_service):
mkey = {
'cephx.services.glance': ('{"groups": {}, "group_names": '
'{"rwx": ["images"]}}'),
'cephx.groups.images': ('{"services": ["glance", "cinder-ceph", '
'"nova-compute"], "pools": ["glance"]}')}
mock_monitor_key_get.side_effect = lambda service, key: mkey[key]
expect_service_name = u'glance'
expected_group = {
u'services': [
u'glance',
u'cinder-ceph',
u'nova-compute'],
u'pools': [u'glance']}
expect_service_obj = {
u'groups': {
u'images': expected_group},
u'group_names': {
u'rwx': [u'images']},
u'object_prefix_perms': {
u'rwx': [u'rbd_children'], u'r': ['another']}}
expect_group_namespace = None
ceph.broker.handle_add_permissions_to_key(
request={
u'namespace': None,
u'group-permission': u'rwx',
u'group': u'images',
u'name': u'glance',
u'object-prefix-permissions': {
u'rwx': [u'rbd_children'], u'r': ['another']},
u'op': u'add-permissions-to-key'},
service='admin')
mock_save_group.assert_called_once_with(
group=expected_group,
group_name='images')
mock_save_service.assert_called_once_with(
service=expect_service_obj,
service_name=expect_service_name)
mock_update_serv_perms.assert_called_once_with(
expect_service_name,
expect_service_obj,
expect_group_namespace)
def test_pool_permission_list_for_service_obj_pref(self):
expected_group = {
u'services': [
u'glance',
u'cinder-ceph',
u'nova-compute'],
u'pools': [u'glance']}
expect_service_obj = {
u'groups': {
u'images': expected_group},
u'group_names': {
u'rwx': [u'images']},
u'object_prefix_perms': {
u'rwx': [u'rbd_children'], u'r': ['another']}}
self.assertEqual(ceph.broker.pool_permission_list_for_service(
expect_service_obj),
[
'mon',
'allow r',
'osd',
('allow rwx pool=glance, '
'allow r object_prefix another, '
'allow rwx object_prefix rbd_children')])
def test_pool_permission_list_for_glance(self):
expected_group = {
u'services': [
u'glance',
u'cinder-ceph',
u'nova-compute'],
u'pools': [u'glance']}
expect_service_obj = {
u'groups': {
u'images': expected_group},
u'group_names': {
u'rwx': [u'images']},
u'object_prefix_perms': {
u'class-read': [u'rbd_children']}}
self.assertEqual(ceph.broker.pool_permission_list_for_service(
expect_service_obj),
[
'mon',
'allow r',
'osd',
('allow rwx pool=glance, '
'allow class-read object_prefix rbd_children')])