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:
parent
3550df998f
commit
4d8f31d0ea
|
@ -255,7 +255,8 @@ def pool_permission_list_for_service(service):
|
||||||
for prefix in prefixes:
|
for prefix in prefixes:
|
||||||
permissions.append("allow {} object_prefix {}".format(permission,
|
permissions.append("allow {} object_prefix {}".format(permission,
|
||||||
prefix))
|
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):
|
def get_service_groups(service, namespace=None):
|
||||||
|
|
|
@ -1096,7 +1096,8 @@ def get_mds_bootstrap_key():
|
||||||
|
|
||||||
|
|
||||||
_default_caps = collections.OrderedDict([
|
_default_caps = collections.OrderedDict([
|
||||||
('mon', ['allow r']),
|
('mon', ['allow r',
|
||||||
|
'allow command "osd blacklist"']),
|
||||||
('osd', ['allow rwx']),
|
('osd', ['allow rwx']),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -1163,6 +1164,7 @@ def get_named_key(name, caps=None, pool_list=None):
|
||||||
:param caps: dict of cephx capabilities
|
:param caps: dict of cephx capabilities
|
||||||
:returns: Returns a cephx key
|
:returns: Returns a cephx key
|
||||||
"""
|
"""
|
||||||
|
key_name = 'client.{}'.format(name)
|
||||||
try:
|
try:
|
||||||
# Does the key already exist?
|
# Does the key already exist?
|
||||||
output = str(subprocess.check_output(
|
output = str(subprocess.check_output(
|
||||||
|
@ -1177,8 +1179,14 @@ def get_named_key(name, caps=None, pool_list=None):
|
||||||
),
|
),
|
||||||
'auth',
|
'auth',
|
||||||
'get',
|
'get',
|
||||||
'client.{}'.format(name),
|
key_name,
|
||||||
]).decode('UTF-8')).strip()
|
]).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)
|
return parse_key(output)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
# Couldn't get the key, time to create it!
|
# 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(
|
'/var/lib/ceph/mon/ceph-{}/keyring'.format(
|
||||||
socket.gethostname()
|
socket.gethostname()
|
||||||
),
|
),
|
||||||
'auth', 'get-or-create', 'client.{}'.format(name),
|
'auth', 'get-or-create', key_name,
|
||||||
]
|
]
|
||||||
# Add capabilities
|
# Add capabilities
|
||||||
for subsystem, subcaps in caps.items():
|
for subsystem, subcaps in caps.items():
|
||||||
|
@ -1213,7 +1221,7 @@ def get_named_key(name, caps=None, pool_list=None):
|
||||||
.strip()) # IGNORE:E1103
|
.strip()) # IGNORE:E1103
|
||||||
|
|
||||||
|
|
||||||
def upgrade_key_caps(key, caps):
|
def upgrade_key_caps(key, caps, pool_list=None):
|
||||||
""" Upgrade key to have capabilities caps """
|
""" Upgrade key to have capabilities caps """
|
||||||
if not is_leader():
|
if not is_leader():
|
||||||
# Not the MON leader OR not clustered
|
# 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
|
"sudo", "-u", ceph_user(), 'ceph', 'auth', 'caps', key
|
||||||
]
|
]
|
||||||
for subsystem, subcaps in caps.items():
|
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)])
|
cmd.extend([subsystem, '; '.join(subcaps)])
|
||||||
subprocess.check_call(cmd)
|
subprocess.check_call(cmd)
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,11 @@ class CephBrokerTestCase(unittest.TestCase):
|
||||||
}
|
}
|
||||||
ceph.broker.update_service_permissions(service='nova',
|
ceph.broker.update_service_permissions(service='nova',
|
||||||
service_obj=service_obj)
|
service_obj=service_obj)
|
||||||
_check_call.assert_called_with(['ceph', 'auth', 'caps',
|
_check_call.assert_called_with(
|
||||||
'client.nova', 'mon', 'allow r', 'osd',
|
['ceph', 'auth', 'caps',
|
||||||
'allow rwx pool=cinder'])
|
'client.nova',
|
||||||
|
'mon', 'allow r, allow command "osd blacklist"',
|
||||||
|
'osd', 'allow rwx pool=cinder'])
|
||||||
|
|
||||||
@patch.object(ceph.broker, 'check_call')
|
@patch.object(ceph.broker, 'check_call')
|
||||||
@patch.object(ceph.broker, 'get_service_groups')
|
@patch.object(ceph.broker, 'get_service_groups')
|
||||||
|
@ -67,8 +69,9 @@ class CephBrokerTestCase(unittest.TestCase):
|
||||||
"services": ["nova"]}, sort_keys=True))
|
"services": ["nova"]}, sort_keys=True))
|
||||||
_check_call.assert_called_with([
|
_check_call.assert_called_with([
|
||||||
'ceph', 'auth', 'caps',
|
'ceph', 'auth', 'caps',
|
||||||
'client.nova', 'mon', 'allow r', 'osd',
|
'client.nova',
|
||||||
'allow rwx pool=glance, allow rwx pool=cinder'])
|
'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_set')
|
||||||
@patch.object(ceph.broker, 'monitor_key_get')
|
@patch.object(ceph.broker, 'monitor_key_get')
|
||||||
|
@ -109,7 +112,7 @@ class CephBrokerTestCase(unittest.TestCase):
|
||||||
}
|
}
|
||||||
result = ceph.broker.pool_permission_list_for_service(service)
|
result = ceph.broker.pool_permission_list_for_service(service)
|
||||||
self.assertEqual(result, ['mon',
|
self.assertEqual(result, ['mon',
|
||||||
'allow r',
|
'allow r, allow command "osd blacklist"',
|
||||||
'osd',
|
'osd',
|
||||||
'allow rwx pool=glance'])
|
'allow rwx pool=glance'])
|
||||||
|
|
||||||
|
@ -132,7 +135,7 @@ class CephBrokerTestCase(unittest.TestCase):
|
||||||
result,
|
result,
|
||||||
[
|
[
|
||||||
'mon',
|
'mon',
|
||||||
'allow r',
|
'allow r, allow command "osd blacklist"',
|
||||||
'osd',
|
'osd',
|
||||||
'allow r pool=p2, allow rwx pool=glance, allow rwx pool=p1'])
|
'allow r pool=p2, allow rwx pool=glance, allow rwx pool=p1'])
|
||||||
|
|
||||||
|
@ -606,7 +609,7 @@ class CephBrokerTestCase(unittest.TestCase):
|
||||||
expect_service_obj),
|
expect_service_obj),
|
||||||
[
|
[
|
||||||
'mon',
|
'mon',
|
||||||
'allow r',
|
'allow r, allow command "osd blacklist"',
|
||||||
'osd',
|
'osd',
|
||||||
('allow rwx pool=glance, '
|
('allow rwx pool=glance, '
|
||||||
'allow r object_prefix another, '
|
'allow r object_prefix another, '
|
||||||
|
@ -630,7 +633,7 @@ class CephBrokerTestCase(unittest.TestCase):
|
||||||
expect_service_obj),
|
expect_service_obj),
|
||||||
[
|
[
|
||||||
'mon',
|
'mon',
|
||||||
'allow r',
|
'allow r, allow command "osd blacklist"',
|
||||||
'osd',
|
'osd',
|
||||||
('allow rwx pool=glance, '
|
('allow rwx pool=glance, '
|
||||||
'allow class-read object_prefix rbd_children')])
|
'allow class-read object_prefix rbd_children')])
|
||||||
|
|
|
@ -237,8 +237,8 @@ class CephTestCase(unittest.TestCase):
|
||||||
'mon.', '--keyring',
|
'mon.', '--keyring',
|
||||||
'/var/lib/ceph/mon/ceph-osd001/keyring',
|
'/var/lib/ceph/mon/ceph-osd001/keyring',
|
||||||
'auth', 'get-or-create', 'client.rgw001',
|
'auth', 'get-or-create', 'client.rgw001',
|
||||||
'mon', 'allow r', 'osd',
|
'mon', 'allow r; allow command "osd blacklist"',
|
||||||
'allow rwx pool=rbd pool=block'])])
|
'osd', 'allow rwx pool=rbd pool=block'])])
|
||||||
|
|
||||||
@patch.object(utils.subprocess, 'check_output')
|
@patch.object(utils.subprocess, 'check_output')
|
||||||
@patch.object(utils, 'ceph_user', lambda: "ceph")
|
@patch.object(utils, 'ceph_user', lambda: "ceph")
|
||||||
|
@ -255,8 +255,8 @@ class CephTestCase(unittest.TestCase):
|
||||||
'mon.', '--keyring',
|
'mon.', '--keyring',
|
||||||
'/var/lib/ceph/mon/ceph-osd001/keyring',
|
'/var/lib/ceph/mon/ceph-osd001/keyring',
|
||||||
'auth', 'get-or-create', 'client.rgw001',
|
'auth', 'get-or-create', 'client.rgw001',
|
||||||
'mon', 'allow r', 'osd',
|
'mon', 'allow r; allow command "osd blacklist"',
|
||||||
'allow rwx'])])
|
'osd', 'allow rwx'])])
|
||||||
|
|
||||||
def test_parse_key_with_caps_existing_key(self):
|
def test_parse_key_with_caps_existing_key(self):
|
||||||
expected = "AQCm7aVYQFXXFhAAj0WIeqcag88DKOvY4UKR/g=="
|
expected = "AQCm7aVYQFXXFhAAj0WIeqcag88DKOvY4UKR/g=="
|
||||||
|
|
Loading…
Reference in New Issue