114 lines
4.8 KiB
Diff
114 lines
4.8 KiB
Diff
|
|
From 621fea6fda4f06876295f67d4767914332ff82d3 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Kotresh HR <khiremat@redhat.com>
|
||
|
|
Date: Thu, 26 Nov 2020 14:48:16 +0530
|
||
|
|
Subject: [PATCH 3/5] pybind/ceph_volume_client: Preserve existing caps while
|
||
|
|
authorize/deauthorize auth-id
|
||
|
|
|
||
|
|
Authorize/Deauthorize used to overwrite the caps of auth-id which would
|
||
|
|
end up deleting existing caps. This patch fixes the same by retaining
|
||
|
|
the existing caps by appending or deleting the new caps as needed.
|
||
|
|
|
||
|
|
Fixes: https://tracker.ceph.com/issues/48555
|
||
|
|
Signed-off-by: Kotresh HR <khiremat@redhat.com>
|
||
|
|
(cherry picked from commit 47100e528ef77e7e82dc9877424243dc6a7e7533)
|
||
|
|
---
|
||
|
|
src/pybind/ceph_volume_client.py | 43 ++++++++++++++++++++++----------
|
||
|
|
1 file changed, 30 insertions(+), 13 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/src/pybind/ceph_volume_client.py b/src/pybind/ceph_volume_client.py
|
||
|
|
index e2ab64ee226..ca1f361d03c 100644
|
||
|
|
--- a/src/pybind/ceph_volume_client.py
|
||
|
|
+++ b/src/pybind/ceph_volume_client.py
|
||
|
|
@@ -973,6 +973,26 @@ class CephFSVolumeClient(object):
|
||
|
|
data['version'] = self.version
|
||
|
|
return self._metadata_set(self._volume_metadata_path(volume_path), data)
|
||
|
|
|
||
|
|
+ def _prepare_updated_caps_list(self, existing_caps, mds_cap_str, osd_cap_str, authorize=True):
|
||
|
|
+ caps_list = []
|
||
|
|
+ for k, v in existing_caps['caps'].items():
|
||
|
|
+ if k == 'mds' or k == 'osd':
|
||
|
|
+ continue
|
||
|
|
+ elif k == 'mon':
|
||
|
|
+ if not authorize and v == 'allow r':
|
||
|
|
+ continue
|
||
|
|
+ caps_list.extend((k,v))
|
||
|
|
+
|
||
|
|
+ if mds_cap_str:
|
||
|
|
+ caps_list.extend(('mds', mds_cap_str))
|
||
|
|
+ if osd_cap_str:
|
||
|
|
+ caps_list.extend(('osd', osd_cap_str))
|
||
|
|
+
|
||
|
|
+ if authorize and 'mon' not in caps_list:
|
||
|
|
+ caps_list.extend(('mon', 'allow r'))
|
||
|
|
+
|
||
|
|
+ return caps_list
|
||
|
|
+
|
||
|
|
def authorize(self, volume_path, auth_id, readonly=False, tenant_id=None):
|
||
|
|
"""
|
||
|
|
Get-or-create a Ceph auth identity for `auth_id` and grant them access
|
||
|
|
@@ -1151,8 +1171,8 @@ class CephFSVolumeClient(object):
|
||
|
|
if not orig_mds_caps:
|
||
|
|
return want_mds_cap, want_osd_cap
|
||
|
|
|
||
|
|
- mds_cap_tokens = orig_mds_caps.split(",")
|
||
|
|
- osd_cap_tokens = orig_osd_caps.split(",")
|
||
|
|
+ mds_cap_tokens = [x.strip() for x in orig_mds_caps.split(",")]
|
||
|
|
+ osd_cap_tokens = [x.strip() for x in orig_osd_caps.split(",")]
|
||
|
|
|
||
|
|
if want_mds_cap in mds_cap_tokens:
|
||
|
|
return orig_mds_caps, orig_osd_caps
|
||
|
|
@@ -1173,15 +1193,14 @@ class CephFSVolumeClient(object):
|
||
|
|
orig_mds_caps, orig_osd_caps, want_mds_cap, want_osd_cap,
|
||
|
|
unwanted_mds_cap, unwanted_osd_cap)
|
||
|
|
|
||
|
|
+ caps_list = self._prepare_updated_caps_list(cap, mds_cap_str, osd_cap_str)
|
||
|
|
caps = self._rados_command(
|
||
|
|
'auth caps',
|
||
|
|
{
|
||
|
|
'entity': client_entity,
|
||
|
|
- 'caps': [
|
||
|
|
- 'mds', mds_cap_str,
|
||
|
|
- 'osd', osd_cap_str,
|
||
|
|
- 'mon', cap['caps'].get('mon', 'allow r')]
|
||
|
|
+ 'caps': caps_list
|
||
|
|
})
|
||
|
|
+
|
||
|
|
caps = self._rados_command(
|
||
|
|
'auth get',
|
||
|
|
{
|
||
|
|
@@ -1306,8 +1325,8 @@ class CephFSVolumeClient(object):
|
||
|
|
)
|
||
|
|
|
||
|
|
def cap_remove(orig_mds_caps, orig_osd_caps, want_mds_caps, want_osd_caps):
|
||
|
|
- mds_cap_tokens = orig_mds_caps.split(",")
|
||
|
|
- osd_cap_tokens = orig_osd_caps.split(",")
|
||
|
|
+ mds_cap_tokens = [x.strip() for x in orig_mds_caps.split(",")]
|
||
|
|
+ osd_cap_tokens = [x.strip() for x in orig_osd_caps.split(",")]
|
||
|
|
|
||
|
|
for want_mds_cap, want_osd_cap in zip(want_mds_caps, want_osd_caps):
|
||
|
|
if want_mds_cap in mds_cap_tokens:
|
||
|
|
@@ -1323,17 +1342,15 @@ class CephFSVolumeClient(object):
|
||
|
|
mds_cap_str, osd_cap_str = cap_remove(orig_mds_caps, orig_osd_caps,
|
||
|
|
want_mds_caps, want_osd_caps)
|
||
|
|
|
||
|
|
- if not mds_cap_str:
|
||
|
|
+ caps_list = self._prepare_updated_caps_list(cap, mds_cap_str, osd_cap_str, authorize=False)
|
||
|
|
+ if not caps_list:
|
||
|
|
self._rados_command('auth del', {'entity': client_entity}, decode=False)
|
||
|
|
else:
|
||
|
|
self._rados_command(
|
||
|
|
'auth caps',
|
||
|
|
{
|
||
|
|
'entity': client_entity,
|
||
|
|
- 'caps': [
|
||
|
|
- 'mds', mds_cap_str,
|
||
|
|
- 'osd', osd_cap_str,
|
||
|
|
- 'mon', cap['caps'].get('mon', 'allow r')]
|
||
|
|
+ 'caps': caps_list
|
||
|
|
})
|
||
|
|
|
||
|
|
# FIXME: rados raising Error instead of ObjectNotFound in auth get failure
|
||
|
|
--
|
||
|
|
2.23.0
|
||
|
|
|