]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/mon/moncap.cc
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / test / mon / moncap.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2012 Inktank
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15#include <iostream>
16
17#include "include/stringify.h"
18#include "mon/MonCap.h"
19
20#include "gtest/gtest.h"
21
20effc67
TL
22using namespace std;
23
7c673cae
FG
24const char *parse_good[] = {
25
26 // MonCapMatch
27 "allow *",
28 "allow r",
29 "allow rwx",
30 "allow r",
31 " allow rwx",
32 "allow rwx ",
33 " allow rwx ",
34 " allow\t rwx ",
35 "\tallow\nrwx\t",
36 "allow service=foo x",
37 "allow service=\"froo\" x",
38 "allow profile osd",
39 "allow profile osd-bootstrap",
40 "allow profile \"mds-bootstrap\", allow *",
41 "allow command \"a b c\"",
42 "allow command abc",
43 "allow command abc with arg=foo",
44 "allow command abc with arg=foo arg2=bar",
45 "allow command abc with arg=foo arg2=bar",
46 "allow command abc with arg=foo arg2 prefix bar arg3 prefix baz",
47 "allow command abc with arg=foo arg2 prefix \"bar bingo\" arg3 prefix baz",
c07f9fc5
FG
48 "allow command abc with arg regex \"^[0-9a-z.]*$\"",
49 "allow command abc with arg regex \"\(invaluid regex\"",
7c673cae
FG
50 "allow service foo x",
51 "allow service foo x; allow service bar x",
52 "allow service foo w ;allow service bar x",
53 "allow service foo w , allow service bar x",
54 "allow service foo r , allow service bar x",
55 "allow service foo_foo r, allow service bar r",
56 "allow service foo-foo r, allow service bar r",
57 "allow service \" foo \" w, allow service bar r",
58 "allow command abc with arg=foo arg2=bar, allow service foo r",
59 "allow command abc.def with arg=foo arg2=bar, allow service foo r",
60 "allow command \"foo bar\" with arg=\"baz\"",
61 "allow command \"foo bar\" with arg=\"baz.xx\"",
c07f9fc5
FG
62 "profile osd",
63 "profile \"mds-bootstrap\", profile foo",
11fdf7f2
TL
64 "allow * network 1.2.3.4/24",
65 "allow * network ::1/128",
66 "allow * network [aa:bb::1]/128",
67 "allow service=foo x network 1.2.3.4/16",
68 "allow command abc network 1.2.3.4/8",
69 "profile osd network 1.2.3.4/32",
70 "allow profile mon network 1.2.3.4/32",
7c673cae
FG
71 0
72};
73
74TEST(MonCap, ParseGood) {
75 for (int i=0; parse_good[i]; ++i) {
76 string str = parse_good[i];
77 MonCap cap;
78 std::cout << "Testing good input: '" << str << "'" << std::endl;
79 ASSERT_TRUE(cap.parse(str, &cout));
80 std::cout << " -> " << cap << std::endl;
81 }
82}
83
84// these should stringify to the input value
85const char *parse_identity[] = {
86 "allow *",
87 "allow r",
88 "allow rwx",
89 "allow service foo x",
90 "allow profile osd",
91 "allow profile osd-bootstrap",
92 "allow profile mds-bootstrap, allow *",
93 "allow profile \"foo bar\", allow *",
94 "allow command abc",
95 "allow command \"a b c\"",
96 "allow command abc with arg=foo",
97 "allow command abc with arg=foo arg2=bar",
98 "allow command abc with arg=foo arg2=bar",
99 "allow command abc with arg=foo arg2 prefix bar arg3 prefix baz",
100 "allow command abc with arg=foo arg2 prefix \"bar bingo\" arg3 prefix baz",
101 "allow service foo x",
102 "allow service foo x, allow service bar x",
103 "allow service foo w, allow service bar x",
104 "allow service foo r, allow service bar x",
105 "allow service foo_foo r, allow service bar r",
106 "allow service foo-foo r, allow service bar r",
107 "allow service \" foo \" w, allow service bar r",
108 "allow command abc with arg=foo arg2=bar, allow service foo r",
109 0
110};
111
112TEST(MonCap, ParseIdentity)
113{
114 for (int i=0; parse_identity[i]; ++i) {
115 string str = parse_identity[i];
116 MonCap cap;
117 std::cout << "Testing good input: '" << str << "'" << std::endl;
118 ASSERT_TRUE(cap.parse(str, &cout));
119 string out = stringify(cap);
120 ASSERT_EQ(out, str);
121 }
122}
123
124const char *parse_bad[] = {
125 "allow r foo",
126 "allow*",
127 "foo allow *",
128 "allow profile foo rwx",
129 "allow profile",
130 "allow profile foo bar rwx",
131 "allow service bar",
132 "allow command baz x",
133 "allow r w",
134 "ALLOW r",
135 "allow rwx,",
136 "allow rwx x",
137 "allow r pool foo r",
138 "allow wwx pool taco",
139 "allow wwx pool taco^funny&chars",
140 "allow rwx pool 'weird name''",
141 "allow rwx object_prefix \"beforepool\" pool weird",
142 "allow rwx auid 123 pool asdf",
143 "allow command foo a prefix b",
144 "allow command foo with a prefixb",
145 "allow command foo with a = prefix b",
146 "allow command foo with a prefix b c",
147 0
148};
149
150TEST(MonCap, ParseBad) {
151 for (int i=0; parse_bad[i]; ++i) {
152 string str = parse_bad[i];
153 MonCap cap;
154 std::cout << "Testing bad input: '" << str << "'" << std::endl;
155 ASSERT_FALSE(cap.parse(str, &cout));
156 }
157}
158
159TEST(MonCap, AllowAll) {
160 MonCap cap;
161 ASSERT_FALSE(cap.is_allow_all());
162
163 ASSERT_TRUE(cap.parse("allow r", NULL));
164 ASSERT_FALSE(cap.is_allow_all());
165 cap.grants.clear();
166
167 ASSERT_TRUE(cap.parse("allow w", NULL));
168 ASSERT_FALSE(cap.is_allow_all());
169 cap.grants.clear();
170
171 ASSERT_TRUE(cap.parse("allow x", NULL));
172 ASSERT_FALSE(cap.is_allow_all());
173 cap.grants.clear();
174
175 ASSERT_TRUE(cap.parse("allow rwx", NULL));
176 ASSERT_FALSE(cap.is_allow_all());
177 cap.grants.clear();
178
179 ASSERT_TRUE(cap.parse("allow rw", NULL));
180 ASSERT_FALSE(cap.is_allow_all());
181 cap.grants.clear();
182
183 ASSERT_TRUE(cap.parse("allow rx", NULL));
184 ASSERT_FALSE(cap.is_allow_all());
185 cap.grants.clear();
186
187 ASSERT_TRUE(cap.parse("allow wx", NULL));
188 ASSERT_FALSE(cap.is_allow_all());
189 cap.grants.clear();
190
191 ASSERT_TRUE(cap.parse("allow *", NULL));
192 ASSERT_TRUE(cap.is_allow_all());
92f5a8d4
TL
193 ASSERT_TRUE(cap.is_capable(NULL, {}, "foo", "asdf", {}, true, true, true,
194 {}));
7c673cae
FG
195
196 MonCap cap2;
197 ASSERT_FALSE(cap2.is_allow_all());
198 cap2.set_allow_all();
199 ASSERT_TRUE(cap2.is_allow_all());
200}
201
11fdf7f2
TL
202TEST(MonCap, Network) {
203 MonCap cap;
204 bool r = cap.parse("allow * network 192.168.0.0/16, allow * network 10.0.0.0/8", NULL);
205 ASSERT_TRUE(r);
206
207 entity_addr_t a, b, c;
208 a.parse("10.1.2.3");
209 b.parse("192.168.2.3");
210 c.parse("192.167.2.3");
211
92f5a8d4 212 ASSERT_TRUE(cap.is_capable(NULL, {}, "foo", "asdf", {}, true, true, true,
11fdf7f2 213 a));
92f5a8d4 214 ASSERT_TRUE(cap.is_capable(NULL, {}, "foo", "asdf", {}, true, true, true,
11fdf7f2 215 b));
92f5a8d4 216 ASSERT_FALSE(cap.is_capable(NULL, {}, "foo", "asdf", {}, true, true, true,
11fdf7f2
TL
217 c));
218}
219
7c673cae
FG
220TEST(MonCap, ProfileOSD) {
221 MonCap cap;
222 bool r = cap.parse("allow profile osd", NULL);
223 ASSERT_TRUE(r);
224
225 EntityName name;
226 name.from_str("osd.123");
227 map<string,string> ca;
228
92f5a8d4
TL
229 ASSERT_TRUE(cap.is_capable(NULL, name, "osd", "", ca, true, false, false,
230 {}));
231 ASSERT_TRUE(cap.is_capable(NULL, name, "osd", "", ca, true, true, false, {}));
232 ASSERT_TRUE(cap.is_capable(NULL, name, "osd", "", ca, true, true, true, {}));
233 ASSERT_TRUE(cap.is_capable(NULL, name, "osd", "", ca, true, true, true, {}));
234 ASSERT_TRUE(cap.is_capable(NULL, name, "mon", "", ca, true, false, false,
235 {}));
236
237 ASSERT_FALSE(cap.is_capable(NULL, name, "mds", "", ca, true, true, true, {}));
238 ASSERT_FALSE(cap.is_capable(NULL, name, "mon", "", ca, true, true, true, {}));
7c673cae
FG
239
240 ca.clear();
92f5a8d4
TL
241 ASSERT_FALSE(cap.is_capable(NULL, name, "", "config-key get", ca, true, true,
242 true, {}));
7c673cae 243 ca["key"] = "daemon-private/osd.123";
92f5a8d4
TL
244 ASSERT_FALSE(cap.is_capable(NULL, name, "", "config-key get", ca, true, true,
245 true, {}));
7c673cae 246 ca["key"] = "daemon-private/osd.12/asdf";
92f5a8d4
TL
247 ASSERT_FALSE(cap.is_capable(NULL, name, "", "config-key get", ca, true, true,
248 true, {}));
7c673cae 249 ca["key"] = "daemon-private/osd.123/";
92f5a8d4
TL
250 ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key get", ca, true, true,
251 true, {}));
252 ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key get", ca, true, true,
253 true, {}));
254 ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key get", ca, true, true,
255 true, {}));
7c673cae 256 ca["key"] = "daemon-private/osd.123/foo";
92f5a8d4
TL
257 ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key get", ca, true, true,
258 true, {}));
259 ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key put", ca, true, true,
260 true, {}));
261 ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key set", ca, true, true,
262 true, {}));
263 ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key exists", ca, true,
264 true, true, {}));
265 ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key delete", ca, true,
266 true, true, {}));
7c673cae
FG
267}
268
c07f9fc5
FG
269TEST(MonCap, CommandRegEx) {
270 MonCap cap;
271 ASSERT_FALSE(cap.is_allow_all());
92f5a8d4
TL
272 ASSERT_TRUE(cap.parse("allow command abc with arg regex \"^[0-9a-z.]*$\"",
273 NULL));
c07f9fc5
FG
274
275 EntityName name;
276 name.from_str("osd.123");
92f5a8d4
TL
277 ASSERT_TRUE(cap.is_capable(nullptr, name, "", "abc", {{"arg", "12345abcde"}},
278 true, true, true, {}));
279 ASSERT_FALSE(cap.is_capable(nullptr, name, "", "abc", {{"arg", "~!@#$"}},
280 true, true, true, {}));
c07f9fc5
FG
281
282 ASSERT_TRUE(cap.parse("allow command abc with arg regex \"[*\"", NULL));
92f5a8d4
TL
283 ASSERT_FALSE(cap.is_capable(nullptr, name, "", "abc", {{"arg", ""}}, true,
284 true, true, {}));
c07f9fc5 285}
d2e6a577
FG
286
287TEST(MonCap, ProfileBootstrapRBD) {
288 MonCap cap;
289 ASSERT_FALSE(cap.is_allow_all());
290 ASSERT_TRUE(cap.parse("profile bootstrap-rbd", NULL));
291
292 EntityName name;
293 name.from_str("mon.a");
92f5a8d4 294 ASSERT_TRUE(cap.is_capable(nullptr, name, "",
d2e6a577
FG
295 "auth get-or-create", {
296 {"entity", "client.rbd"},
297 {"caps_mon", "profile rbd"},
298 {"caps_osd", "profile rbd pool=foo, profile rbd-read-only"},
11fdf7f2 299 }, true, true, true,
92f5a8d4
TL
300 {}));
301 ASSERT_FALSE(cap.is_capable(nullptr, name, "",
d2e6a577
FG
302 "auth get-or-create", {
303 {"entity", "client.rbd"},
304 {"caps_mon", "allow *"},
305 {"caps_osd", "profile rbd"},
11fdf7f2 306 }, true, true, true,
92f5a8d4
TL
307 {}));
308 ASSERT_FALSE(cap.is_capable(nullptr, name, "",
11fdf7f2
TL
309 "auth get-or-create", {
310 {"entity", "client.rbd"},
311 {"caps_mon", "profile rbd"},
312 {"caps_osd", "profile rbd pool=foo, allow *, profile rbd-read-only"},
313 }, true, true, true,
92f5a8d4 314 {}));
11fdf7f2
TL
315}
316
317TEST(MonCap, ProfileBootstrapRBDMirror) {
318 MonCap cap;
319 ASSERT_FALSE(cap.is_allow_all());
320 ASSERT_TRUE(cap.parse("profile bootstrap-rbd-mirror", NULL));
321
322 EntityName name;
323 name.from_str("mon.a");
92f5a8d4 324 ASSERT_TRUE(cap.is_capable(nullptr, name, "",
11fdf7f2
TL
325 "auth get-or-create", {
326 {"entity", "client.rbd"},
327 {"caps_mon", "profile rbd-mirror"},
328 {"caps_osd", "profile rbd pool=foo, profile rbd-read-only"},
329 }, true, true, true,
92f5a8d4
TL
330 {}));
331 ASSERT_FALSE(cap.is_capable(nullptr, name, "",
d2e6a577
FG
332 "auth get-or-create", {
333 {"entity", "client.rbd"},
334 {"caps_mon", "profile rbd"},
11fdf7f2
TL
335 {"caps_osd", "profile rbd pool=foo, profile rbd-read-only"},
336 }, true, true, true,
92f5a8d4
TL
337 {}));
338 ASSERT_FALSE(cap.is_capable(nullptr, name, "",
11fdf7f2
TL
339 "auth get-or-create", {
340 {"entity", "client.rbd"},
341 {"caps_mon", "allow *"},
342 {"caps_osd", "profile rbd"},
343 }, true, true, true,
92f5a8d4
TL
344 {}));
345 ASSERT_FALSE(cap.is_capable(nullptr, name, "",
11fdf7f2
TL
346 "auth get-or-create", {
347 {"entity", "client.rbd"},
348 {"caps_mon", "profile rbd-mirror"},
d2e6a577 349 {"caps_osd", "profile rbd pool=foo, allow *, profile rbd-read-only"},
11fdf7f2 350 }, true, true, true,
92f5a8d4 351 {}));
11fdf7f2
TL
352}
353
354TEST(MonCap, ProfileRBD) {
355 MonCap cap;
356 ASSERT_FALSE(cap.is_allow_all());
357 ASSERT_TRUE(cap.parse("profile rbd", NULL));
358
359 EntityName name;
360 name.from_str("mon.a");
92f5a8d4 361 ASSERT_FALSE(cap.is_capable(nullptr, name, "config-key",
11fdf7f2
TL
362 "config-key get", {
363 {"key", "rbd/mirror/peer/1/1234"},
92f5a8d4 364 }, true, false, false, {}));
11fdf7f2
TL
365}
366
367TEST(MonCap, ProfileRBDMirror) {
368 MonCap cap;
369 ASSERT_FALSE(cap.is_allow_all());
370 ASSERT_TRUE(cap.parse("profile rbd-mirror", NULL));
371
372 EntityName name;
373 name.from_str("mon.a");
92f5a8d4 374 ASSERT_TRUE(cap.is_capable(nullptr, name, "config-key",
11fdf7f2
TL
375 "config-key get", {
376 {"key", "rbd/mirror/peer/1/1234"},
92f5a8d4 377 }, true, false, false, {}));
d2e6a577 378}