Add 'osd blacklist' to default mon perms

Ensure that the default permissions for clients include the
'osd blacklist' command;  This ensures that in the event of
a client crashing (due to power outage or segfault), the
client and re-connect and write to any devices on reboot.

Change-Id: I0b43dece4e1c56fb838b0147bfb75fb9906e6657
Closes-Bug: 1773449
This commit is contained in:
James Page 2018-06-08 11:34:28 +01:00
parent 3550df998f
commit 4d8f31d0ea
4 changed files with 36 additions and 18 deletions

View File

@ -255,7 +255,8 @@ def pool_permission_list_for_service(service):
for prefix in prefixes:
permissions.append("allow {} object_prefix {}".format(permission,
prefix))
return ["mon", "allow r", "osd", ', '.join(permissions)]
return ['mon', 'allow r, allow command "osd blacklist"',
'osd', ', '.join(permissions)]
def get_service_groups(service, namespace=None):

View File

@ -1096,7 +1096,8 @@ def get_mds_bootstrap_key():
_default_caps = collections.OrderedDict([
('mon', ['allow r']),
('mon', ['allow r',
'allow command "osd blacklist"']),
('osd', ['allow rwx']),
])
@ -1163,6 +1164,7 @@ def get_named_key(name, caps=None, pool_list=None):
:param caps: dict of cephx capabilities
:returns: Returns a cephx key
"""
key_name = 'client.{}'.format(name)
try:
# Does the key already exist?
output = str(subprocess.check_output(
@ -1177,8 +1179,14 @@ def get_named_key(name, caps=None, pool_list=None):
),
'auth',
'get',
'client.{}'.format(name),
key_name,
]).decode('UTF-8')).strip()
# NOTE(jamespage);
# Apply any changes to key capabilities, dealing with
# upgrades which requires new caps for operation.
upgrade_key_caps(key_name,
caps or _default_caps,
pool_list)
return parse_key(output)
except subprocess.CalledProcessError:
# Couldn't get the key, time to create it!
@ -1194,7 +1202,7 @@ def get_named_key(name, caps=None, pool_list=None):
'/var/lib/ceph/mon/ceph-{}/keyring'.format(
socket.gethostname()
),
'auth', 'get-or-create', 'client.{}'.format(name),
'auth', 'get-or-create', key_name,
]
# Add capabilities
for subsystem, subcaps in caps.items():
@ -1213,7 +1221,7 @@ def get_named_key(name, caps=None, pool_list=None):
.strip()) # IGNORE:E1103
def upgrade_key_caps(key, caps):
def upgrade_key_caps(key, caps, pool_list=None):
""" Upgrade key to have capabilities caps """
if not is_leader():
# Not the MON leader OR not clustered
@ -1222,6 +1230,12 @@ def upgrade_key_caps(key, caps):
"sudo", "-u", ceph_user(), 'ceph', 'auth', 'caps', key
]
for subsystem, subcaps in caps.items():
if subsystem == 'osd':
if pool_list:
# This will output a string similar to:
# "pool=rgw pool=rbd pool=something"
pools = " ".join(['pool={0}'.format(i) for i in pool_list])
subcaps[0] = subcaps[0] + " " + pools
cmd.extend([subsystem, '; '.join(subcaps)])
subprocess.check_call(cmd)

View File

@ -34,9 +34,11 @@ class CephBrokerTestCase(unittest.TestCase):
}
ceph.broker.update_service_permissions(service='nova',
service_obj=service_obj)
_check_call.assert_called_with(['ceph', 'auth', 'caps',
'client.nova', 'mon', 'allow r', 'osd',
'allow rwx pool=cinder'])
_check_call.assert_called_with(
['ceph', 'auth', 'caps',
'client.nova',
'mon', 'allow r, allow command "osd blacklist"',
'osd', 'allow rwx pool=cinder'])
@patch.object(ceph.broker, 'check_call')
@patch.object(ceph.broker, 'get_service_groups')
@ -67,8 +69,9 @@ class CephBrokerTestCase(unittest.TestCase):
"services": ["nova"]}, sort_keys=True))
_check_call.assert_called_with([
'ceph', 'auth', 'caps',
'client.nova', 'mon', 'allow r', 'osd',
'allow rwx pool=glance, allow rwx pool=cinder'])
'client.nova',
'mon', 'allow r, allow command "osd blacklist"',
'osd', 'allow rwx pool=glance, allow rwx pool=cinder'])
@patch.object(ceph.broker, 'monitor_key_set')
@patch.object(ceph.broker, 'monitor_key_get')
@ -109,7 +112,7 @@ class CephBrokerTestCase(unittest.TestCase):
}
result = ceph.broker.pool_permission_list_for_service(service)
self.assertEqual(result, ['mon',
'allow r',
'allow r, allow command "osd blacklist"',
'osd',
'allow rwx pool=glance'])
@ -132,7 +135,7 @@ class CephBrokerTestCase(unittest.TestCase):
result,
[
'mon',
'allow r',
'allow r, allow command "osd blacklist"',
'osd',
'allow r pool=p2, allow rwx pool=glance, allow rwx pool=p1'])
@ -606,7 +609,7 @@ class CephBrokerTestCase(unittest.TestCase):
expect_service_obj),
[
'mon',
'allow r',
'allow r, allow command "osd blacklist"',
'osd',
('allow rwx pool=glance, '
'allow r object_prefix another, '
@ -630,7 +633,7 @@ class CephBrokerTestCase(unittest.TestCase):
expect_service_obj),
[
'mon',
'allow r',
'allow r, allow command "osd blacklist"',
'osd',
('allow rwx pool=glance, '
'allow class-read object_prefix rbd_children')])

View File

@ -237,8 +237,8 @@ class CephTestCase(unittest.TestCase):
'mon.', '--keyring',
'/var/lib/ceph/mon/ceph-osd001/keyring',
'auth', 'get-or-create', 'client.rgw001',
'mon', 'allow r', 'osd',
'allow rwx pool=rbd pool=block'])])
'mon', 'allow r; allow command "osd blacklist"',
'osd', 'allow rwx pool=rbd pool=block'])])
@patch.object(utils.subprocess, 'check_output')
@patch.object(utils, 'ceph_user', lambda: "ceph")
@ -255,8 +255,8 @@ class CephTestCase(unittest.TestCase):
'mon.', '--keyring',
'/var/lib/ceph/mon/ceph-osd001/keyring',
'auth', 'get-or-create', 'client.rgw001',
'mon', 'allow r', 'osd',
'allow rwx'])])
'mon', 'allow r; allow command "osd blacklist"',
'osd', 'allow rwx'])])
def test_parse_key_with_caps_existing_key(self):
expected = "AQCm7aVYQFXXFhAAj0WIeqcag88DKOvY4UKR/g=="