summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_basic_types.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/rgw/rgw_basic_types.h')
-rw-r--r--src/rgw/rgw_basic_types.h631
1 files changed, 631 insertions, 0 deletions
diff --git a/src/rgw/rgw_basic_types.h b/src/rgw/rgw_basic_types.h
new file mode 100644
index 000000000..81094fe56
--- /dev/null
+++ b/src/rgw/rgw_basic_types.h
@@ -0,0 +1,631 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+#ifndef CEPH_RGW_BASIC_TYPES_H
+#define CEPH_RGW_BASIC_TYPES_H
+
+#include <string>
+
+#include "include/types.h"
+
+class JSONObj;
+class cls_user_bucket;
+
+struct rgw_user {
+ std::string tenant;
+ std::string id;
+ std::string ns;
+
+ rgw_user() {}
+ explicit rgw_user(const std::string& s) {
+ from_str(s);
+ }
+ rgw_user(const std::string& tenant, const std::string& id, const std::string& ns="")
+ : tenant(tenant),
+ id(id),
+ ns(ns) {
+ }
+ rgw_user(std::string&& tenant, std::string&& id, std::string&& ns="")
+ : tenant(std::move(tenant)),
+ id(std::move(id)),
+ ns(std::move(ns)) {
+ }
+
+ void encode(ceph::buffer::list& bl) const {
+ ENCODE_START(2, 1, bl);
+ encode(tenant, bl);
+ encode(id, bl);
+ encode(ns, bl);
+ ENCODE_FINISH(bl);
+ }
+ void decode(ceph::buffer::list::const_iterator& bl) {
+ DECODE_START(2, bl);
+ decode(tenant, bl);
+ decode(id, bl);
+ if (struct_v >= 2) {
+ decode(ns, bl);
+ }
+ DECODE_FINISH(bl);
+ }
+
+ void to_str(std::string& str) const {
+ if (!tenant.empty()) {
+ if (!ns.empty()) {
+ str = tenant + '$' + ns + '$' + id;
+ } else {
+ str = tenant + '$' + id;
+ }
+ } else if (!ns.empty()) {
+ str = '$' + ns + '$' + id;
+ } else {
+ str = id;
+ }
+ }
+
+ void clear() {
+ tenant.clear();
+ id.clear();
+ ns.clear();
+ }
+
+ bool empty() const {
+ return id.empty();
+ }
+
+ std::string to_str() const {
+ std::string s;
+ to_str(s);
+ return s;
+ }
+
+ void from_str(const std::string& str) {
+ size_t pos = str.find('$');
+ if (pos != std::string::npos) {
+ tenant = str.substr(0, pos);
+ string_view sv = str;
+ string_view ns_id = sv.substr(pos + 1);
+ size_t ns_pos = ns_id.find('$');
+ if (ns_pos != std::string::npos) {
+ ns = string(ns_id.substr(0, ns_pos));
+ id = string(ns_id.substr(ns_pos + 1));
+ } else {
+ ns.clear();
+ id = string(ns_id);
+ }
+ } else {
+ tenant.clear();
+ ns.clear();
+ id = str;
+ }
+ }
+
+ rgw_user& operator=(const std::string& str) {
+ from_str(str);
+ return *this;
+ }
+
+ int compare(const rgw_user& u) const {
+ int r = tenant.compare(u.tenant);
+ if (r != 0)
+ return r;
+ r = ns.compare(u.ns);
+ if (r != 0) {
+ return r;
+ }
+ return id.compare(u.id);
+ }
+ int compare(const std::string& str) const {
+ rgw_user u(str);
+ return compare(u);
+ }
+
+ bool operator!=(const rgw_user& rhs) const {
+ return (compare(rhs) != 0);
+ }
+ bool operator==(const rgw_user& rhs) const {
+ return (compare(rhs) == 0);
+ }
+ bool operator<(const rgw_user& rhs) const {
+ if (tenant < rhs.tenant) {
+ return true;
+ } else if (tenant > rhs.tenant) {
+ return false;
+ }
+ if (ns < rhs.ns) {
+ return true;
+ } else if (ns > rhs.ns) {
+ return false;
+ }
+ return (id < rhs.id);
+ }
+ void dump(ceph::Formatter *f) const;
+ static void generate_test_instances(std::list<rgw_user*>& o);
+};
+WRITE_CLASS_ENCODER(rgw_user)
+
+struct rgw_pool {
+ std::string name;
+ std::string ns;
+
+ rgw_pool() = default;
+ rgw_pool(const rgw_pool& _p) : name(_p.name), ns(_p.ns) {}
+ rgw_pool(rgw_pool&&) = default;
+ rgw_pool(const std::string& _s) {
+ from_str(_s);
+ }
+ rgw_pool(const std::string& _name, const std::string& _ns) : name(_name), ns(_ns) {}
+
+ std::string to_str() const;
+ void from_str(const std::string& s);
+
+ void init(const std::string& _s) {
+ from_str(_s);
+ }
+
+ bool empty() const {
+ return name.empty();
+ }
+
+ int compare(const rgw_pool& p) const {
+ int r = name.compare(p.name);
+ if (r != 0) {
+ return r;
+ }
+ return ns.compare(p.ns);
+ }
+
+ void encode(ceph::buffer::list& bl) const {
+ ENCODE_START(10, 10, bl);
+ encode(name, bl);
+ encode(ns, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode_from_bucket(ceph::buffer::list::const_iterator& bl);
+
+ void decode(ceph::buffer::list::const_iterator& bl) {
+ DECODE_START_LEGACY_COMPAT_LEN(10, 3, 3, bl);
+
+ decode(name, bl);
+
+ if (struct_v < 10) {
+
+ /*
+ * note that rgw_pool can be used where rgw_bucket was used before
+ * therefore we inherit rgw_bucket's old versions. However, we only
+ * need the first field from rgw_bucket. unless we add more fields
+ * in which case we'll need to look at struct_v, and check the actual
+ * version. Anything older than 10 needs to be treated as old rgw_bucket
+ */
+
+ } else {
+ decode(ns, bl);
+ }
+
+ DECODE_FINISH(bl);
+ }
+
+ rgw_pool& operator=(const rgw_pool&) = default;
+
+ bool operator==(const rgw_pool& p) const {
+ return (compare(p) == 0);
+ }
+ bool operator!=(const rgw_pool& p) const {
+ return !(*this == p);
+ }
+ bool operator<(const rgw_pool& p) const {
+ int r = name.compare(p.name);
+ if (r == 0) {
+ return (ns.compare(p.ns) < 0);
+ }
+ return (r < 0);
+ }
+};
+WRITE_CLASS_ENCODER(rgw_pool)
+
+inline std::ostream& operator<<(std::ostream& out, const rgw_pool& p) {
+ out << p.to_str();
+ return out;
+}
+
+struct rgw_data_placement_target {
+ rgw_pool data_pool;
+ rgw_pool data_extra_pool;
+ rgw_pool index_pool;
+
+ rgw_data_placement_target() = default;
+ rgw_data_placement_target(const rgw_data_placement_target&) = default;
+ rgw_data_placement_target(rgw_data_placement_target&&) = default;
+
+ rgw_data_placement_target(const rgw_pool& data_pool,
+ const rgw_pool& data_extra_pool,
+ const rgw_pool& index_pool)
+ : data_pool(data_pool),
+ data_extra_pool(data_extra_pool),
+ index_pool(index_pool) {
+ }
+
+ rgw_data_placement_target&
+ operator=(const rgw_data_placement_target&) = default;
+
+ const rgw_pool& get_data_extra_pool() const {
+ if (data_extra_pool.empty()) {
+ return data_pool;
+ }
+ return data_extra_pool;
+ }
+
+ int compare(const rgw_data_placement_target& t) {
+ int c = data_pool.compare(t.data_pool);
+ if (c != 0) {
+ return c;
+ }
+ c = data_extra_pool.compare(t.data_extra_pool);
+ if (c != 0) {
+ return c;
+ }
+ return index_pool.compare(t.index_pool);
+ };
+
+ void dump(ceph::Formatter *f) const;
+ void decode_json(JSONObj *obj);
+};
+
+struct rgw_bucket_key {
+ std::string tenant;
+ std::string name;
+ std::string bucket_id;
+
+ rgw_bucket_key(const std::string& _tenant,
+ const std::string& _name,
+ const std::string& _bucket_id) : tenant(_tenant),
+ name(_name),
+ bucket_id(_bucket_id) {}
+ rgw_bucket_key(const std::string& _tenant,
+ const std::string& _name) : tenant(_tenant),
+ name(_name) {}
+};
+
+struct rgw_bucket {
+ std::string tenant;
+ std::string name;
+ std::string marker;
+ std::string bucket_id;
+ rgw_data_placement_target explicit_placement;
+
+ rgw_bucket() { }
+ // cppcheck-suppress noExplicitConstructor
+ explicit rgw_bucket(const rgw_user& u, const cls_user_bucket& b);
+
+ rgw_bucket(const rgw_bucket_key& bk) : tenant(bk.tenant),
+ name(bk.name),
+ bucket_id(bk.bucket_id) {}
+ rgw_bucket(const rgw_bucket&) = default;
+ rgw_bucket(rgw_bucket&&) = default;
+
+ bool match(const rgw_bucket& b) const {
+ return (tenant == b.tenant &&
+ name == b.name &&
+ (bucket_id == b.bucket_id ||
+ bucket_id.empty() ||
+ b.bucket_id.empty()));
+ }
+
+ void convert(cls_user_bucket *b) const;
+
+ void encode(ceph::buffer::list& bl) const {
+ ENCODE_START(10, 10, bl);
+ encode(name, bl);
+ encode(marker, bl);
+ encode(bucket_id, bl);
+ encode(tenant, bl);
+ bool encode_explicit = !explicit_placement.data_pool.empty();
+ encode(encode_explicit, bl);
+ if (encode_explicit) {
+ encode(explicit_placement.data_pool, bl);
+ encode(explicit_placement.data_extra_pool, bl);
+ encode(explicit_placement.index_pool, bl);
+ }
+ ENCODE_FINISH(bl);
+ }
+ void decode(ceph::buffer::list::const_iterator& bl) {
+ DECODE_START_LEGACY_COMPAT_LEN(10, 3, 3, bl);
+ decode(name, bl);
+ if (struct_v < 10) {
+ decode(explicit_placement.data_pool.name, bl);
+ }
+ if (struct_v >= 2) {
+ decode(marker, bl);
+ if (struct_v <= 3) {
+ uint64_t id;
+ decode(id, bl);
+ char buf[16];
+ snprintf(buf, sizeof(buf), "%" PRIu64, id);
+ bucket_id = buf;
+ } else {
+ decode(bucket_id, bl);
+ }
+ }
+ if (struct_v < 10) {
+ if (struct_v >= 5) {
+ decode(explicit_placement.index_pool.name, bl);
+ } else {
+ explicit_placement.index_pool = explicit_placement.data_pool;
+ }
+ if (struct_v >= 7) {
+ decode(explicit_placement.data_extra_pool.name, bl);
+ }
+ }
+ if (struct_v >= 8) {
+ decode(tenant, bl);
+ }
+ if (struct_v >= 10) {
+ bool decode_explicit = !explicit_placement.data_pool.empty();
+ decode(decode_explicit, bl);
+ if (decode_explicit) {
+ decode(explicit_placement.data_pool, bl);
+ decode(explicit_placement.data_extra_pool, bl);
+ decode(explicit_placement.index_pool, bl);
+ }
+ }
+ DECODE_FINISH(bl);
+ }
+
+ void update_bucket_id(const std::string& new_bucket_id) {
+ bucket_id = new_bucket_id;
+ }
+
+ // format a key for the bucket/instance. pass delim=0 to skip a field
+ std::string get_key(char tenant_delim = '/',
+ char id_delim = ':',
+ size_t reserve = 0) const;
+
+ const rgw_pool& get_data_extra_pool() const {
+ return explicit_placement.get_data_extra_pool();
+ }
+
+ void dump(ceph::Formatter *f) const;
+ void decode_json(JSONObj *obj);
+ static void generate_test_instances(std::list<rgw_bucket*>& o);
+
+ rgw_bucket& operator=(const rgw_bucket&) = default;
+
+ bool operator<(const rgw_bucket& b) const {
+ if (tenant < b.tenant) {
+ return true;
+ } else if (tenant > b.tenant) {
+ return false;
+ }
+
+ if (name < b.name) {
+ return true;
+ } else if (name > b.name) {
+ return false;
+ }
+
+ return (bucket_id < b.bucket_id);
+ }
+
+ bool operator==(const rgw_bucket& b) const {
+ return (tenant == b.tenant) && (name == b.name) && \
+ (bucket_id == b.bucket_id);
+ }
+ bool operator!=(const rgw_bucket& b) const {
+ return (tenant != b.tenant) || (name != b.name) ||
+ (bucket_id != b.bucket_id);
+ }
+};
+WRITE_CLASS_ENCODER(rgw_bucket)
+
+inline std::ostream& operator<<(std::ostream& out, const rgw_bucket &b) {
+ out << b.tenant << ":" << b.name << "[" << b.bucket_id << "])";
+ return out;
+}
+
+struct rgw_bucket_shard {
+ rgw_bucket bucket;
+ int shard_id;
+
+ rgw_bucket_shard() : shard_id(-1) {}
+ rgw_bucket_shard(const rgw_bucket& _b, int _sid) : bucket(_b), shard_id(_sid) {}
+
+ std::string get_key(char tenant_delim = '/', char id_delim = ':',
+ char shard_delim = ':') const;
+
+ bool operator<(const rgw_bucket_shard& b) const {
+ if (bucket < b.bucket) {
+ return true;
+ }
+ if (b.bucket < bucket) {
+ return false;
+ }
+ return shard_id < b.shard_id;
+ }
+
+ bool operator==(const rgw_bucket_shard& b) const {
+ return (bucket == b.bucket &&
+ shard_id == b.shard_id);
+ }
+};
+
+inline std::ostream& operator<<(std::ostream& out, const rgw_bucket_shard& bs) {
+ if (bs.shard_id <= 0) {
+ return out << bs.bucket;
+ }
+
+ return out << bs.bucket << ":" << bs.shard_id;
+}
+
+
+struct rgw_zone_id {
+ std::string id;
+
+ rgw_zone_id() {}
+ rgw_zone_id(const std::string& _id) : id(_id) {}
+ rgw_zone_id(std::string&& _id) : id(std::move(_id)) {}
+
+ void encode(ceph::buffer::list& bl) const {
+ /* backward compatiblity, not using ENCODE_{START,END} macros */
+ ceph::encode(id, bl);
+ }
+
+ void decode(ceph::buffer::list::const_iterator& bl) {
+ /* backward compatiblity, not using DECODE_{START,END} macros */
+ ceph::decode(id, bl);
+ }
+
+ void clear() {
+ id.clear();
+ }
+
+ bool operator==(const std::string& _id) const {
+ return (id == _id);
+ }
+ bool operator==(const rgw_zone_id& zid) const {
+ return (id == zid.id);
+ }
+ bool operator!=(const rgw_zone_id& zid) const {
+ return (id != zid.id);
+ }
+ bool operator<(const rgw_zone_id& zid) const {
+ return (id < zid.id);
+ }
+ bool operator>(const rgw_zone_id& zid) const {
+ return (id > zid.id);
+ }
+
+ bool empty() const {
+ return id.empty();
+ }
+};
+WRITE_CLASS_ENCODER(rgw_zone_id)
+
+inline std::ostream& operator<<(std::ostream& os, const rgw_zone_id& zid) {
+ os << zid.id;
+ return os;
+}
+
+void encode_json_impl(const char *name, const rgw_zone_id& zid, ceph::Formatter *f);
+void decode_json_obj(rgw_zone_id& zid, JSONObj *obj);
+
+
+// Represents an identity. This is more wide-ranging than a
+// 'User'. Its purposes is to be matched against by an
+// IdentityApplier. The internal representation will doubtless change as
+// more types are added. We may want to expose the type enum and make
+// the member public so people can switch/case on it.
+
+namespace rgw {
+namespace auth {
+class Principal {
+ enum types { User, Role, Tenant, Wildcard, OidcProvider, AssumedRole };
+ types t;
+ rgw_user u;
+ std::string idp_url;
+
+ explicit Principal(types t)
+ : t(t) {}
+
+ Principal(types t, std::string&& n, std::string i)
+ : t(t), u(std::move(n), std::move(i)) {}
+
+ Principal(std::string&& idp_url)
+ : t(OidcProvider), idp_url(std::move(idp_url)) {}
+
+public:
+
+ static Principal wildcard() {
+ return Principal(Wildcard);
+ }
+
+ static Principal user(std::string&& t, std::string&& u) {
+ return Principal(User, std::move(t), std::move(u));
+ }
+
+ static Principal role(std::string&& t, std::string&& u) {
+ return Principal(Role, std::move(t), std::move(u));
+ }
+
+ static Principal tenant(std::string&& t) {
+ return Principal(Tenant, std::move(t), {});
+ }
+
+ static Principal oidc_provider(std::string&& idp_url) {
+ return Principal(std::move(idp_url));
+ }
+
+ static Principal assumed_role(std::string&& t, std::string&& u) {
+ return Principal(AssumedRole, std::move(t), std::move(u));
+ }
+
+ bool is_wildcard() const {
+ return t == Wildcard;
+ }
+
+ bool is_user() const {
+ return t == User;
+ }
+
+ bool is_role() const {
+ return t == Role;
+ }
+
+ bool is_tenant() const {
+ return t == Tenant;
+ }
+
+ bool is_oidc_provider() const {
+ return t == OidcProvider;
+ }
+
+ bool is_assumed_role() const {
+ return t == AssumedRole;
+ }
+
+ const std::string& get_tenant() const {
+ return u.tenant;
+ }
+
+ const std::string& get_id() const {
+ return u.id;
+ }
+
+ const std::string& get_idp_url() const {
+ return idp_url;
+ }
+
+ const string& get_role_session() const {
+ return u.id;
+ }
+
+ const string& get_role() const {
+ return u.id;
+ }
+
+ bool operator ==(const Principal& o) const {
+ return (t == o.t) && (u == o.u);
+ }
+
+ bool operator <(const Principal& o) const {
+ return (t < o.t) || ((t == o.t) && (u < o.u));
+ }
+};
+
+std::ostream& operator <<(std::ostream& m, const Principal& p);
+}
+}
+
+class JSONObj;
+
+void decode_json_obj(rgw_user& val, JSONObj *obj);
+void encode_json(const char *name, const rgw_user& val, ceph::Formatter *f);
+void encode_xml(const char *name, const rgw_user& val, ceph::Formatter *f);
+
+inline std::ostream& operator<<(std::ostream& out, const rgw_user &u) {
+ std::string s;
+ u.to_str(s);
+ return out << s;
+}
+
+
+#endif