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