]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_basic_types.h
0ba03bd0e27f860ac243f0013dcfb42b6a051cf3
[ceph.git] / ceph / src / rgw / rgw_basic_types.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #ifndef CEPH_RGW_BASIC_TYPES_H
5 #define CEPH_RGW_BASIC_TYPES_H
6
7 #include <string>
8
9 #include "include/types.h"
10
11 class JSONObj;
12 class cls_user_bucket;
13
14 struct rgw_user {
15 std::string tenant;
16 std::string id;
17
18 rgw_user() {}
19 explicit rgw_user(const std::string& s) {
20 from_str(s);
21 }
22 rgw_user(const std::string& tenant, const std::string& id)
23 : tenant(tenant),
24 id(id) {
25 }
26 rgw_user(std::string&& tenant, std::string&& id)
27 : tenant(std::move(tenant)),
28 id(std::move(id)) {
29 }
30
31 void encode(bufferlist& bl) const {
32 ENCODE_START(1, 1, bl);
33 encode(tenant, bl);
34 encode(id, bl);
35 ENCODE_FINISH(bl);
36 }
37 void decode(bufferlist::const_iterator& bl) {
38 DECODE_START(1, bl);
39 decode(tenant, bl);
40 decode(id, bl);
41 DECODE_FINISH(bl);
42 }
43
44 void to_str(std::string& str) const {
45 if (!tenant.empty()) {
46 str = tenant + '$' + id;
47 } else {
48 str = id;
49 }
50 }
51
52 void clear() {
53 tenant.clear();
54 id.clear();
55 }
56
57 bool empty() const {
58 return id.empty();
59 }
60
61 string to_str() const {
62 string s;
63 to_str(s);
64 return s;
65 }
66
67 void from_str(const std::string& str) {
68 size_t pos = str.find('$');
69 if (pos != std::string::npos) {
70 tenant = str.substr(0, pos);
71 id = str.substr(pos + 1);
72 } else {
73 tenant.clear();
74 id = str;
75 }
76 }
77
78 rgw_user& operator=(const string& str) {
79 from_str(str);
80 return *this;
81 }
82
83 int compare(const rgw_user& u) const {
84 int r = tenant.compare(u.tenant);
85 if (r != 0)
86 return r;
87
88 return id.compare(u.id);
89 }
90 int compare(const string& str) const {
91 rgw_user u(str);
92 return compare(u);
93 }
94
95 bool operator!=(const rgw_user& rhs) const {
96 return (compare(rhs) != 0);
97 }
98 bool operator==(const rgw_user& rhs) const {
99 return (compare(rhs) == 0);
100 }
101 bool operator<(const rgw_user& rhs) const {
102 if (tenant < rhs.tenant) {
103 return true;
104 } else if (tenant > rhs.tenant) {
105 return false;
106 }
107 return (id < rhs.id);
108 }
109 void dump(Formatter *f) const;
110 static void generate_test_instances(list<rgw_user*>& o);
111 };
112 WRITE_CLASS_ENCODER(rgw_user)
113
114 struct rgw_pool {
115 std::string name;
116 std::string ns;
117
118 rgw_pool() = default;
119 rgw_pool(const rgw_pool& _p) : name(_p.name), ns(_p.ns) {}
120 rgw_pool(rgw_pool&&) = default;
121 rgw_pool(const string& _s) {
122 from_str(_s);
123 }
124 rgw_pool(const string& _name, const string& _ns) : name(_name), ns(_ns) {}
125
126 string to_str() const;
127 void from_str(const string& s);
128
129 void init(const string& _s) {
130 from_str(_s);
131 }
132
133 bool empty() const {
134 return name.empty();
135 }
136
137 int compare(const rgw_pool& p) const {
138 int r = name.compare(p.name);
139 if (r != 0) {
140 return r;
141 }
142 return ns.compare(p.ns);
143 }
144
145 void encode(bufferlist& bl) const {
146 ENCODE_START(10, 10, bl);
147 encode(name, bl);
148 encode(ns, bl);
149 ENCODE_FINISH(bl);
150 }
151
152 void decode_from_bucket(bufferlist::const_iterator& bl);
153
154 void decode(bufferlist::const_iterator& bl) {
155 DECODE_START_LEGACY_COMPAT_LEN(10, 3, 3, bl);
156
157 decode(name, bl);
158
159 if (struct_v < 10) {
160
161 /*
162 * note that rgw_pool can be used where rgw_bucket was used before
163 * therefore we inherit rgw_bucket's old versions. However, we only
164 * need the first field from rgw_bucket. unless we add more fields
165 * in which case we'll need to look at struct_v, and check the actual
166 * version. Anything older than 10 needs to be treated as old rgw_bucket
167 */
168
169 } else {
170 decode(ns, bl);
171 }
172
173 DECODE_FINISH(bl);
174 }
175
176 rgw_pool& operator=(const rgw_pool&) = default;
177
178 bool operator==(const rgw_pool& p) const {
179 return (compare(p) == 0);
180 }
181 bool operator!=(const rgw_pool& p) const {
182 return !(*this == p);
183 }
184 bool operator<(const rgw_pool& p) const {
185 int r = name.compare(p.name);
186 if (r == 0) {
187 return (ns.compare(p.ns) < 0);
188 }
189 return (r < 0);
190 }
191 };
192 WRITE_CLASS_ENCODER(rgw_pool)
193
194 inline ostream& operator<<(ostream& out, const rgw_pool& p) {
195 out << p.to_str();
196 return out;
197 }
198
199 struct rgw_data_placement_target {
200 rgw_pool data_pool;
201 rgw_pool data_extra_pool;
202 rgw_pool index_pool;
203
204 rgw_data_placement_target() = default;
205 rgw_data_placement_target(const rgw_data_placement_target&) = default;
206 rgw_data_placement_target(rgw_data_placement_target&&) = default;
207
208 rgw_data_placement_target(const rgw_pool& data_pool,
209 const rgw_pool& data_extra_pool,
210 const rgw_pool& index_pool)
211 : data_pool(data_pool),
212 data_extra_pool(data_extra_pool),
213 index_pool(index_pool) {
214 }
215
216 rgw_data_placement_target&
217 operator=(const rgw_data_placement_target&) = default;
218
219 const rgw_pool& get_data_extra_pool() const {
220 if (data_extra_pool.empty()) {
221 return data_pool;
222 }
223 return data_extra_pool;
224 }
225
226 int compare(const rgw_data_placement_target& t) {
227 int c = data_pool.compare(t.data_pool);
228 if (c != 0) {
229 return c;
230 }
231 c = data_extra_pool.compare(t.data_extra_pool);
232 if (c != 0) {
233 return c;
234 }
235 return index_pool.compare(t.index_pool);
236 };
237
238 void dump(Formatter *f) const;
239 void decode_json(JSONObj *obj);
240 };
241
242 struct rgw_bucket_key {
243 std::string tenant;
244 std::string name;
245 std::string bucket_id;
246
247 rgw_bucket_key(const std::string& _tenant,
248 const std::string& _name,
249 const std::string& _bucket_id) : tenant(_tenant),
250 name(_name),
251 bucket_id(_bucket_id) {}
252 rgw_bucket_key(const std::string& _tenant,
253 const std::string& _name) : tenant(_tenant),
254 name(_name) {}
255 };
256
257 struct rgw_bucket {
258 std::string tenant;
259 std::string name;
260 std::string marker;
261 std::string bucket_id;
262 rgw_data_placement_target explicit_placement;
263
264 rgw_bucket() { }
265 // cppcheck-suppress noExplicitConstructor
266 explicit rgw_bucket(const rgw_user& u, const cls_user_bucket& b);
267
268 rgw_bucket(const rgw_bucket_key& bk) : tenant(bk.tenant),
269 name(bk.name),
270 bucket_id(bk.bucket_id) {}
271 rgw_bucket(const rgw_bucket&) = default;
272 rgw_bucket(rgw_bucket&&) = default;
273
274 bool match(const rgw_bucket& b) const {
275 return (tenant == b.tenant &&
276 name == b.name &&
277 (bucket_id == b.bucket_id ||
278 bucket_id.empty() ||
279 b.bucket_id.empty()));
280 }
281
282 void convert(cls_user_bucket *b) const;
283
284 void encode(bufferlist& bl) const {
285 ENCODE_START(10, 10, bl);
286 encode(name, bl);
287 encode(marker, bl);
288 encode(bucket_id, bl);
289 encode(tenant, bl);
290 bool encode_explicit = !explicit_placement.data_pool.empty();
291 encode(encode_explicit, bl);
292 if (encode_explicit) {
293 encode(explicit_placement.data_pool, bl);
294 encode(explicit_placement.data_extra_pool, bl);
295 encode(explicit_placement.index_pool, bl);
296 }
297 ENCODE_FINISH(bl);
298 }
299 void decode(bufferlist::const_iterator& bl) {
300 DECODE_START_LEGACY_COMPAT_LEN(10, 3, 3, bl);
301 decode(name, bl);
302 if (struct_v < 10) {
303 decode(explicit_placement.data_pool.name, bl);
304 }
305 if (struct_v >= 2) {
306 decode(marker, bl);
307 if (struct_v <= 3) {
308 uint64_t id;
309 decode(id, bl);
310 char buf[16];
311 snprintf(buf, sizeof(buf), "%" PRIu64, id);
312 bucket_id = buf;
313 } else {
314 decode(bucket_id, bl);
315 }
316 }
317 if (struct_v < 10) {
318 if (struct_v >= 5) {
319 decode(explicit_placement.index_pool.name, bl);
320 } else {
321 explicit_placement.index_pool = explicit_placement.data_pool;
322 }
323 if (struct_v >= 7) {
324 decode(explicit_placement.data_extra_pool.name, bl);
325 }
326 }
327 if (struct_v >= 8) {
328 decode(tenant, bl);
329 }
330 if (struct_v >= 10) {
331 bool decode_explicit = !explicit_placement.data_pool.empty();
332 decode(decode_explicit, bl);
333 if (decode_explicit) {
334 decode(explicit_placement.data_pool, bl);
335 decode(explicit_placement.data_extra_pool, bl);
336 decode(explicit_placement.index_pool, bl);
337 }
338 }
339 DECODE_FINISH(bl);
340 }
341
342 void update_bucket_id(const string& new_bucket_id) {
343 bucket_id = new_bucket_id;
344 }
345
346 // format a key for the bucket/instance. pass delim=0 to skip a field
347 std::string get_key(char tenant_delim = '/',
348 char id_delim = ':',
349 size_t reserve = 0) const;
350
351 const rgw_pool& get_data_extra_pool() const {
352 return explicit_placement.get_data_extra_pool();
353 }
354
355 void dump(Formatter *f) const;
356 void decode_json(JSONObj *obj);
357 static void generate_test_instances(list<rgw_bucket*>& o);
358
359 rgw_bucket& operator=(const rgw_bucket&) = default;
360
361 bool operator<(const rgw_bucket& b) const {
362 if (name < b.name) {
363 return true;
364 } else if (name > b.name) {
365 return false;
366 }
367
368 if (bucket_id < b.bucket_id) {
369 return true;
370 } else if (bucket_id > b.bucket_id) {
371 return false;
372 }
373
374 return (tenant < b.tenant);
375 }
376
377 bool operator==(const rgw_bucket& b) const {
378 return (tenant == b.tenant) && (name == b.name) && \
379 (bucket_id == b.bucket_id);
380 }
381 bool operator!=(const rgw_bucket& b) const {
382 return (tenant != b.tenant) || (name != b.name) ||
383 (bucket_id != b.bucket_id);
384 }
385 };
386 WRITE_CLASS_ENCODER(rgw_bucket)
387
388 inline ostream& operator<<(ostream& out, const rgw_bucket &b) {
389 out << b.tenant << ":" << b.name << "[" << b.bucket_id << "])";
390 return out;
391 }
392
393 struct rgw_bucket_shard {
394 rgw_bucket bucket;
395 int shard_id;
396
397 rgw_bucket_shard() : shard_id(-1) {}
398 rgw_bucket_shard(const rgw_bucket& _b, int _sid) : bucket(_b), shard_id(_sid) {}
399
400 std::string get_key(char tenant_delim = '/', char id_delim = ':',
401 char shard_delim = ':') const;
402
403 bool operator<(const rgw_bucket_shard& b) const {
404 if (bucket < b.bucket) {
405 return true;
406 }
407 if (b.bucket < bucket) {
408 return false;
409 }
410 return shard_id < b.shard_id;
411 }
412
413 bool operator==(const rgw_bucket_shard& b) const {
414 return (bucket == b.bucket &&
415 shard_id == b.shard_id);
416 }
417 };
418
419 inline ostream& operator<<(ostream& out, const rgw_bucket_shard& bs) {
420 if (bs.shard_id <= 0) {
421 return out << bs.bucket;
422 }
423
424 return out << bs.bucket << ":" << bs.shard_id;
425 }
426
427
428 struct rgw_zone_id {
429 string id;
430
431 rgw_zone_id() {}
432 rgw_zone_id(const string& _id) : id(_id) {}
433 rgw_zone_id(string&& _id) : id(std::move(_id)) {}
434
435 void encode(bufferlist& bl) const {
436 /* backward compatiblity, not using ENCODE_{START,END} macros */
437 ceph::encode(id, bl);
438 }
439
440 void decode(bufferlist::const_iterator& bl) {
441 /* backward compatiblity, not using DECODE_{START,END} macros */
442 ceph::decode(id, bl);
443 }
444
445 void clear() {
446 id.clear();
447 }
448
449 bool operator==(const string& _id) const {
450 return (id == _id);
451 }
452 bool operator==(const rgw_zone_id& zid) const {
453 return (id == zid.id);
454 }
455 bool operator!=(const rgw_zone_id& zid) const {
456 return (id != zid.id);
457 }
458 bool operator<(const rgw_zone_id& zid) const {
459 return (id < zid.id);
460 }
461 bool operator>(const rgw_zone_id& zid) const {
462 return (id > zid.id);
463 }
464
465 bool empty() const {
466 return id.empty();
467 }
468 };
469 WRITE_CLASS_ENCODER(rgw_zone_id)
470
471 static inline ostream& operator<<(ostream& os, const rgw_zone_id& zid) {
472 os << zid.id;
473 return os;
474 }
475
476 void encode_json_impl(const char *name, const rgw_zone_id& zid, Formatter *f);
477 void decode_json_obj(rgw_zone_id& zid, JSONObj *obj);
478
479
480 // Represents an identity. This is more wide-ranging than a
481 // 'User'. Its purposes is to be matched against by an
482 // IdentityApplier. The internal representation will doubtless change as
483 // more types are added. We may want to expose the type enum and make
484 // the member public so people can switch/case on it.
485
486 namespace rgw {
487 namespace auth {
488 class Principal {
489 enum types { User, Role, Tenant, Wildcard, OidcProvider };
490 types t;
491 rgw_user u;
492 string idp_url;
493
494 explicit Principal(types t)
495 : t(t) {}
496
497 Principal(types t, std::string&& n, std::string i)
498 : t(t), u(std::move(n), std::move(i)) {}
499
500 Principal(string&& idp_url)
501 : t(OidcProvider), idp_url(std::move(idp_url)) {}
502
503 public:
504
505 static Principal wildcard() {
506 return Principal(Wildcard);
507 }
508
509 static Principal user(std::string&& t, std::string&& u) {
510 return Principal(User, std::move(t), std::move(u));
511 }
512
513 static Principal role(std::string&& t, std::string&& u) {
514 return Principal(Role, std::move(t), std::move(u));
515 }
516
517 static Principal tenant(std::string&& t) {
518 return Principal(Tenant, std::move(t), {});
519 }
520
521 static Principal oidc_provider(string&& idp_url) {
522 return Principal(std::move(idp_url));
523 }
524
525 bool is_wildcard() const {
526 return t == Wildcard;
527 }
528
529 bool is_user() const {
530 return t == User;
531 }
532
533 bool is_role() const {
534 return t == Role;
535 }
536
537 bool is_tenant() const {
538 return t == Tenant;
539 }
540
541 bool is_oidc_provider() const {
542 return t == OidcProvider;
543 }
544
545 const std::string& get_tenant() const {
546 return u.tenant;
547 }
548
549 const std::string& get_id() const {
550 return u.id;
551 }
552
553 const string& get_idp_url() const {
554 return idp_url;
555 }
556
557 bool operator ==(const Principal& o) const {
558 return (t == o.t) && (u == o.u);
559 }
560
561 bool operator <(const Principal& o) const {
562 return (t < o.t) || ((t == o.t) && (u < o.u));
563 }
564 };
565
566 std::ostream& operator <<(std::ostream& m, const Principal& p);
567 }
568 }
569
570 class JSONObj;
571
572 void decode_json_obj(rgw_user& val, JSONObj *obj);
573 void encode_json(const char *name, const rgw_user& val, Formatter *f);
574 void encode_xml(const char *name, const rgw_user& val, Formatter *f);
575
576 inline ostream& operator<<(ostream& out, const rgw_user &u) {
577 string s;
578 u.to_str(s);
579 return out << s;
580 }
581
582
583 #endif