]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/volumes/fs/operations/access.py
import quincy beta 17.1.0
[ceph.git] / ceph / src / pybind / mgr / volumes / fs / operations / access.py
1 import errno
2 import json
3 from typing import List
4
5
6 def prepare_updated_caps_list(existing_caps, mds_cap_str, osd_cap_str, authorize=True):
7 caps_list = [] # type: List[str]
8 for k, v in existing_caps['caps'].items():
9 if k == 'mds' or k == 'osd':
10 continue
11 elif k == 'mon':
12 if not authorize and v == 'allow r':
13 continue
14 caps_list.extend((k, v))
15
16 if mds_cap_str:
17 caps_list.extend(('mds', mds_cap_str))
18 if osd_cap_str:
19 caps_list.extend(('osd', osd_cap_str))
20
21 if authorize and 'mon' not in caps_list:
22 caps_list.extend(('mon', 'allow r'))
23
24 return caps_list
25
26
27 def allow_access(mgr, client_entity, want_mds_cap, want_osd_cap,
28 unwanted_mds_cap, unwanted_osd_cap, existing_caps):
29 if existing_caps is None:
30 ret, out, err = mgr.mon_command({
31 "prefix": "auth get-or-create",
32 "entity": client_entity,
33 "caps": ['mds', want_mds_cap, 'osd', want_osd_cap, 'mon', 'allow r'],
34 "format": "json"})
35 else:
36 cap = existing_caps[0]
37
38 def cap_update(
39 orig_mds_caps, orig_osd_caps, want_mds_cap,
40 want_osd_cap, unwanted_mds_cap, unwanted_osd_cap):
41
42 if not orig_mds_caps:
43 return want_mds_cap, want_osd_cap
44
45 mds_cap_tokens = [x.strip() for x in orig_mds_caps.split(",")]
46 osd_cap_tokens = [x.strip() for x in orig_osd_caps.split(",")]
47
48 if want_mds_cap in mds_cap_tokens:
49 return orig_mds_caps, orig_osd_caps
50
51 if unwanted_mds_cap in mds_cap_tokens:
52 mds_cap_tokens.remove(unwanted_mds_cap)
53 osd_cap_tokens.remove(unwanted_osd_cap)
54
55 mds_cap_tokens.append(want_mds_cap)
56 osd_cap_tokens.append(want_osd_cap)
57
58 return ",".join(mds_cap_tokens), ",".join(osd_cap_tokens)
59
60 orig_mds_caps = cap['caps'].get('mds', "")
61 orig_osd_caps = cap['caps'].get('osd', "")
62
63 mds_cap_str, osd_cap_str = cap_update(
64 orig_mds_caps, orig_osd_caps, want_mds_cap, want_osd_cap,
65 unwanted_mds_cap, unwanted_osd_cap)
66
67 caps_list = prepare_updated_caps_list(cap, mds_cap_str, osd_cap_str)
68 mgr.mon_command(
69 {
70 "prefix": "auth caps",
71 'entity': client_entity,
72 'caps': caps_list
73 })
74 ret, out, err = mgr.mon_command(
75 {
76 'prefix': 'auth get',
77 'entity': client_entity,
78 'format': 'json'
79 })
80
81 # Result expected like this:
82 # [
83 # {
84 # "entity": "client.foobar",
85 # "key": "AQBY0\/pViX\/wBBAAUpPs9swy7rey1qPhzmDVGQ==",
86 # "caps": {
87 # "mds": "allow *",
88 # "mon": "allow *"
89 # }
90 # }
91 # ]
92
93 caps = json.loads(out)
94 assert len(caps) == 1
95 assert caps[0]['entity'] == client_entity
96 return caps[0]['key']
97
98
99 def deny_access(mgr, client_entity, want_mds_caps, want_osd_caps):
100 ret, out, err = mgr.mon_command({
101 "prefix": "auth get",
102 "entity": client_entity,
103 "format": "json",
104 })
105
106 if ret == -errno.ENOENT:
107 # Already gone, great.
108 return
109
110 def cap_remove(orig_mds_caps, orig_osd_caps, want_mds_caps, want_osd_caps):
111 mds_cap_tokens = [x.strip() for x in orig_mds_caps.split(",")]
112 osd_cap_tokens = [x.strip() for x in orig_osd_caps.split(",")]
113
114 for want_mds_cap, want_osd_cap in zip(want_mds_caps, want_osd_caps):
115 if want_mds_cap in mds_cap_tokens:
116 mds_cap_tokens.remove(want_mds_cap)
117 osd_cap_tokens.remove(want_osd_cap)
118 break
119
120 return ",".join(mds_cap_tokens), ",".join(osd_cap_tokens)
121
122 cap = json.loads(out)[0]
123 orig_mds_caps = cap['caps'].get('mds', "")
124 orig_osd_caps = cap['caps'].get('osd', "")
125 mds_cap_str, osd_cap_str = cap_remove(orig_mds_caps, orig_osd_caps,
126 want_mds_caps, want_osd_caps)
127
128 caps_list = prepare_updated_caps_list(cap, mds_cap_str, osd_cap_str, authorize=False)
129 if not caps_list:
130 mgr.mon_command(
131 {
132 'prefix': 'auth rm',
133 'entity': client_entity
134 })
135 else:
136 mgr.mon_command(
137 {
138 "prefix": "auth caps",
139 'entity': client_entity,
140 'caps': caps_list
141 })