Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / mon / moncap.cc
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
22 const char *parse_good[] = {
23
24   // MonCapMatch
25   "allow *",
26   "allow r",
27   "allow rwx",
28   "allow  r",
29   " allow rwx",
30   "allow rwx ",
31   " allow rwx ",
32   " allow\t   rwx ",
33   "\tallow\nrwx\t",
34   "allow service=foo x",
35   "allow service=\"froo\" x",
36   "allow profile osd",
37   "allow profile osd-bootstrap",
38   "allow profile \"mds-bootstrap\", allow *",
39   "allow command \"a b c\"",
40   "allow command abc",
41   "allow command abc with arg=foo",
42   "allow command abc with arg=foo arg2=bar",
43   "allow command abc with arg=foo arg2=bar",
44   "allow command abc with arg=foo arg2 prefix bar arg3 prefix baz",
45   "allow command abc with arg=foo arg2 prefix \"bar bingo\" arg3 prefix baz",
46   "allow command abc with arg regex \"^[0-9a-z.]*$\"",
47   "allow command abc with arg regex \"\(invaluid regex\"",
48   "allow service foo x",
49   "allow service foo x; allow service bar x",
50   "allow service foo w ;allow service bar x",
51   "allow service foo  w , allow service bar x",
52   "allow service foo r , allow service bar x",
53   "allow service foo_foo r, allow service bar r",
54   "allow service foo-foo r, allow service bar r",
55   "allow service \" foo \" w, allow service bar r",
56   "allow command abc with arg=foo arg2=bar, allow service foo r",
57   "allow command abc.def with arg=foo arg2=bar, allow service foo r",
58   "allow command \"foo bar\" with arg=\"baz\"",
59   "allow command \"foo bar\" with arg=\"baz.xx\"",
60   "profile osd",
61   "profile \"mds-bootstrap\", profile foo",
62   0
63 };
64
65 TEST(MonCap, ParseGood) {
66   for (int i=0; parse_good[i]; ++i) {
67     string str = parse_good[i];
68     MonCap cap;
69     std::cout << "Testing good input: '" << str << "'" << std::endl;
70     ASSERT_TRUE(cap.parse(str, &cout));
71     std::cout << "                                         -> " << cap << std::endl;
72   }
73 }
74
75 // these should stringify to the input value
76 const char *parse_identity[] = {
77   "allow *",
78   "allow r",
79   "allow rwx",
80   "allow service foo x",
81   "allow profile osd",
82   "allow profile osd-bootstrap",
83   "allow profile mds-bootstrap, allow *",
84   "allow profile \"foo bar\", allow *",
85   "allow command abc",
86   "allow command \"a b c\"",
87   "allow command abc with arg=foo",
88   "allow command abc with arg=foo arg2=bar",
89   "allow command abc with arg=foo arg2=bar",
90   "allow command abc with arg=foo arg2 prefix bar arg3 prefix baz",
91   "allow command abc with arg=foo arg2 prefix \"bar bingo\" arg3 prefix baz",
92   "allow service foo x",
93   "allow service foo x, allow service bar x",
94   "allow service foo w, allow service bar x",
95   "allow service foo r, allow service bar x",
96   "allow service foo_foo r, allow service bar r",
97   "allow service foo-foo r, allow service bar r",
98   "allow service \" foo \" w, allow service bar r",
99   "allow command abc with arg=foo arg2=bar, allow service foo r",
100   0
101 };
102
103 TEST(MonCap, ParseIdentity)
104 {
105   for (int i=0; parse_identity[i]; ++i) {
106     string str = parse_identity[i];
107     MonCap cap;
108     std::cout << "Testing good input: '" << str << "'" << std::endl;
109     ASSERT_TRUE(cap.parse(str, &cout));
110     string out = stringify(cap);
111     ASSERT_EQ(out, str);
112   }
113 }
114
115 const char *parse_bad[] = {
116   "allow r foo",
117   "allow*",
118   "foo allow *",
119   "allow profile foo rwx",
120   "allow profile",
121   "allow profile foo bar rwx",
122   "allow service bar",
123   "allow command baz x",
124   "allow r w",
125   "ALLOW r",
126   "allow rwx,",
127   "allow rwx x",
128   "allow r pool foo r",
129   "allow wwx pool taco",
130   "allow wwx pool taco^funny&chars",
131   "allow rwx pool 'weird name''",
132   "allow rwx object_prefix \"beforepool\" pool weird",
133   "allow rwx auid 123 pool asdf",
134   "allow command foo a prefix b",
135   "allow command foo with a prefixb",
136   "allow command foo with a = prefix b",
137   "allow command foo with a prefix b c",
138   0
139 };
140
141 TEST(MonCap, ParseBad) {
142   for (int i=0; parse_bad[i]; ++i) {
143     string str = parse_bad[i];
144     MonCap cap;
145     std::cout << "Testing bad input: '" << str << "'" << std::endl;
146     ASSERT_FALSE(cap.parse(str, &cout));
147   }
148 }
149
150 TEST(MonCap, AllowAll) {
151   MonCap cap;
152   ASSERT_FALSE(cap.is_allow_all());
153
154   ASSERT_TRUE(cap.parse("allow r", NULL));
155   ASSERT_FALSE(cap.is_allow_all());
156   cap.grants.clear();
157
158   ASSERT_TRUE(cap.parse("allow w", NULL));
159   ASSERT_FALSE(cap.is_allow_all());
160   cap.grants.clear();
161
162   ASSERT_TRUE(cap.parse("allow x", NULL));
163   ASSERT_FALSE(cap.is_allow_all());
164   cap.grants.clear();
165
166   ASSERT_TRUE(cap.parse("allow rwx", NULL));
167   ASSERT_FALSE(cap.is_allow_all());
168   cap.grants.clear();
169
170   ASSERT_TRUE(cap.parse("allow rw", NULL));
171   ASSERT_FALSE(cap.is_allow_all());
172   cap.grants.clear();
173
174   ASSERT_TRUE(cap.parse("allow rx", NULL));
175   ASSERT_FALSE(cap.is_allow_all());
176   cap.grants.clear();
177
178   ASSERT_TRUE(cap.parse("allow wx", NULL));
179   ASSERT_FALSE(cap.is_allow_all());
180   cap.grants.clear();
181
182   ASSERT_TRUE(cap.parse("allow *", NULL));
183   ASSERT_TRUE(cap.is_allow_all());
184   ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON, EntityName(),
185                              "foo", "asdf", map<string,string>(), true, true, true));
186
187   MonCap cap2;
188   ASSERT_FALSE(cap2.is_allow_all());
189   cap2.set_allow_all();
190   ASSERT_TRUE(cap2.is_allow_all());
191 }
192
193 TEST(MonCap, ProfileOSD) {
194   MonCap cap;
195   bool r = cap.parse("allow profile osd", NULL);
196   ASSERT_TRUE(r);
197
198   EntityName name;
199   name.from_str("osd.123");
200   map<string,string> ca;
201
202   ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
203                              name, "osd", "", ca, true, false, false));
204   ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
205                              name, "osd", "", ca, true, true, false));
206   ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
207                              name, "osd", "", ca, true, true, true));
208   ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
209                              name, "osd", "", ca, true, true, true));
210   ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
211                              name, "mon", "", ca, true, false,false));
212
213   ASSERT_FALSE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
214                              name, "mds", "", ca, true, true, true));
215   ASSERT_FALSE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
216                              name, "mon", "", ca, true, true, true));
217
218   ca.clear();
219   ASSERT_FALSE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
220                              name, "", "config-key get", ca, true, true, true));
221   ca["key"] = "daemon-private/osd.123";
222   ASSERT_FALSE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
223                              name, "", "config-key get", ca, true, true, true));
224   ca["key"] = "daemon-private/osd.12/asdf";
225   ASSERT_FALSE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
226                              name, "", "config-key get", ca, true, true, true));
227   ca["key"] = "daemon-private/osd.123/";
228   ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
229                              name, "", "config-key get", ca, true, true, true));
230   ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
231                              name, "", "config-key get", ca, true, true, true));
232   ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
233                              name, "", "config-key get", ca, true, true, true));
234   ca["key"] = "daemon-private/osd.123/foo";
235   ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
236                              name, "", "config-key get", ca, true, true, true));
237   ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
238                              name, "", "config-key put", ca, true, true, true));
239   ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
240                              name, "", "config-key set", ca, true, true, true));
241   ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
242                              name, "", "config-key exists", ca, true, true, true));
243   ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
244                              name, "", "config-key delete", ca, true, true, true));
245 }
246
247 TEST(MonCap, CommandRegEx) {
248   MonCap cap;
249   ASSERT_FALSE(cap.is_allow_all());
250   ASSERT_TRUE(cap.parse("allow command abc with arg regex \"^[0-9a-z.]*$\"", NULL));
251
252   EntityName name;
253   name.from_str("osd.123");
254   ASSERT_TRUE(cap.is_capable(nullptr, CEPH_ENTITY_TYPE_OSD, name, "",
255                              "abc", {{"arg", "12345abcde"}}, true, true, true));
256   ASSERT_FALSE(cap.is_capable(nullptr, CEPH_ENTITY_TYPE_OSD, name, "",
257                               "abc", {{"arg", "~!@#$"}}, true, true, true));
258
259   ASSERT_TRUE(cap.parse("allow command abc with arg regex \"[*\"", NULL));
260   ASSERT_FALSE(cap.is_capable(nullptr, CEPH_ENTITY_TYPE_OSD, name, "",
261                               "abc", {{"arg", ""}}, true, true, true));
262 }
263
264 TEST(MonCap, ProfileBootstrapRBD) {
265   MonCap cap;
266   ASSERT_FALSE(cap.is_allow_all());
267   ASSERT_TRUE(cap.parse("profile bootstrap-rbd", NULL));
268
269   EntityName name;
270   name.from_str("mon.a");
271   ASSERT_TRUE(cap.is_capable(nullptr, CEPH_ENTITY_TYPE_MON, name, "",
272                              "auth get-or-create", {
273                                {"entity", "client.rbd"},
274                                {"caps_mon", "profile rbd"},
275                                {"caps_osd", "profile rbd pool=foo, profile rbd-read-only"},
276                              }, true, true, true));
277   ASSERT_FALSE(cap.is_capable(nullptr, CEPH_ENTITY_TYPE_MON, name, "",
278                               "auth get-or-create", {
279                                 {"entity", "client.rbd"},
280                                 {"caps_mon", "allow *"},
281                                 {"caps_osd", "profile rbd"},
282                               }, true, true, true));
283   ASSERT_FALSE(cap.is_capable(nullptr, CEPH_ENTITY_TYPE_MON, name, "",
284                               "auth get-or-create", {
285                                 {"entity", "client.rbd"},
286                                 {"caps_mon", "profile rbd"},
287                                 {"caps_osd", "profile rbd pool=foo, allow *, profile rbd-read-only"},
288                               }, true, true, true));
289 }