summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_zone_types.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/rgw/rgw_zone_types.h')
-rw-r--r--src/rgw/rgw_zone_types.h625
1 files changed, 625 insertions, 0 deletions
diff --git a/src/rgw/rgw_zone_types.h b/src/rgw/rgw_zone_types.h
new file mode 100644
index 000000000..f2881dfef
--- /dev/null
+++ b/src/rgw/rgw_zone_types.h
@@ -0,0 +1,625 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+/* N.B., this header defines fundamental serialized types. Do not
+ * introduce changes or include files which can only be compiled in
+ * radosgw or OSD contexts (e.g., rgw_sal.h, rgw_common.h)
+ */
+
+#pragma once
+
+#include <string>
+#include <set>
+#include <map>
+#include <list>
+#include <boost/optional.hpp>
+
+#include <fmt/format.h>
+
+#include "include/types.h"
+#include "rgw_bucket_layout.h"
+#include "rgw_zone_features.h"
+#include "rgw_pool_types.h"
+#include "rgw_acl_types.h"
+#include "rgw_placement_types.h"
+
+#include "common/Formatter.h"
+
+class JSONObj;
+
+namespace rgw_zone_defaults {
+
+extern std::string zone_names_oid_prefix;
+extern std::string region_info_oid_prefix;
+extern std::string realm_names_oid_prefix;
+extern std::string zone_group_info_oid_prefix;
+extern std::string realm_info_oid_prefix;
+extern std::string default_region_info_oid;
+extern std::string default_zone_group_info_oid;
+extern std::string region_map_oid;
+extern std::string default_realm_info_oid;
+extern std::string default_zonegroup_name;
+extern std::string default_zone_name;
+extern std::string zonegroup_names_oid_prefix;
+extern std::string RGW_DEFAULT_ZONE_ROOT_POOL;
+extern std::string RGW_DEFAULT_ZONEGROUP_ROOT_POOL;
+extern std::string RGW_DEFAULT_REALM_ROOT_POOL;
+extern std::string RGW_DEFAULT_PERIOD_ROOT_POOL;
+extern std::string avail_pools;
+extern std::string default_storage_pool_suffix;
+
+} /* namespace rgw_zone_defaults */
+
+struct RGWNameToId {
+ std::string obj_id;
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(obj_id, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(obj_id, bl);
+ DECODE_FINISH(bl);
+ }
+
+ void dump(Formatter *f) const;
+ void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWNameToId)
+
+struct RGWDefaultSystemMetaObjInfo {
+ std::string default_id;
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(default_id, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(default_id, bl);
+ DECODE_FINISH(bl);
+ }
+
+ void dump(Formatter *f) const;
+ void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWDefaultSystemMetaObjInfo)
+
+struct RGWZoneStorageClass {
+ boost::optional<rgw_pool> data_pool;
+ boost::optional<std::string> compression_type;
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(data_pool, bl);
+ encode(compression_type, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(data_pool, bl);
+ decode(compression_type, bl);
+ DECODE_FINISH(bl);
+ }
+
+ void dump(Formatter *f) const;
+ void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWZoneStorageClass)
+
+class RGWZoneStorageClasses {
+ std::map<std::string, RGWZoneStorageClass> m;
+
+ /* in memory only */
+ RGWZoneStorageClass *standard_class;
+
+public:
+ RGWZoneStorageClasses() {
+ standard_class = &m[RGW_STORAGE_CLASS_STANDARD];
+ }
+ RGWZoneStorageClasses(const RGWZoneStorageClasses& rhs) {
+ m = rhs.m;
+ standard_class = &m[RGW_STORAGE_CLASS_STANDARD];
+ }
+ RGWZoneStorageClasses& operator=(const RGWZoneStorageClasses& rhs) {
+ m = rhs.m;
+ standard_class = &m[RGW_STORAGE_CLASS_STANDARD];
+ return *this;
+ }
+
+ const RGWZoneStorageClass& get_standard() const {
+ return *standard_class;
+ }
+
+ bool find(const std::string& sc, const RGWZoneStorageClass** pstorage_class) const {
+ auto iter = m.find(sc);
+ if (iter == m.end()) {
+ return false;
+ }
+ *pstorage_class = &iter->second;
+ return true;
+ }
+
+ bool exists(const std::string& sc) const {
+ if (sc.empty()) {
+ return true;
+ }
+ auto iter = m.find(sc);
+ return (iter != m.end());
+ }
+
+ const std::map<std::string, RGWZoneStorageClass>& get_all() const {
+ return m;
+ }
+
+ std::map<std::string, RGWZoneStorageClass>& get_all() {
+ return m;
+ }
+
+ void set_storage_class(const std::string& sc, const rgw_pool* data_pool, const std::string* compression_type) {
+ const std::string *psc = &sc;
+ if (sc.empty()) {
+ psc = &RGW_STORAGE_CLASS_STANDARD;
+ }
+ RGWZoneStorageClass& storage_class = m[*psc];
+ if (data_pool) {
+ storage_class.data_pool = *data_pool;
+ }
+ if (compression_type) {
+ storage_class.compression_type = *compression_type;
+ }
+ }
+
+ void remove_storage_class(const std::string& sc) {
+ if (!sc.empty()) {
+ m.erase(sc);
+ }
+ }
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(m, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(m, bl);
+ standard_class = &m[RGW_STORAGE_CLASS_STANDARD];
+ DECODE_FINISH(bl);
+ }
+
+ void dump(Formatter *f) const;
+ void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWZoneStorageClasses)
+
+struct RGWZonePlacementInfo {
+ rgw_pool index_pool;
+ rgw_pool data_extra_pool; /* if not set we should use data_pool */
+ RGWZoneStorageClasses storage_classes;
+ rgw::BucketIndexType index_type;
+ bool inline_data;
+
+ RGWZonePlacementInfo() : index_type(rgw::BucketIndexType::Normal), inline_data(true) {}
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(8, 1, bl);
+ encode(index_pool.to_str(), bl);
+ rgw_pool standard_data_pool = get_data_pool(RGW_STORAGE_CLASS_STANDARD);
+ encode(standard_data_pool.to_str(), bl);
+ encode(data_extra_pool.to_str(), bl);
+ encode((uint32_t)index_type, bl);
+ std::string standard_compression_type = get_compression_type(RGW_STORAGE_CLASS_STANDARD);
+ encode(standard_compression_type, bl);
+ encode(storage_classes, bl);
+ encode(inline_data, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(8, bl);
+ std::string index_pool_str;
+ std::string data_pool_str;
+ decode(index_pool_str, bl);
+ index_pool = rgw_pool(index_pool_str);
+ decode(data_pool_str, bl);
+ rgw_pool standard_data_pool(data_pool_str);
+ if (struct_v >= 4) {
+ std::string data_extra_pool_str;
+ decode(data_extra_pool_str, bl);
+ data_extra_pool = rgw_pool(data_extra_pool_str);
+ }
+ if (struct_v >= 5) {
+ uint32_t it;
+ decode(it, bl);
+ index_type = (rgw::BucketIndexType)it;
+ }
+ std::string standard_compression_type;
+ if (struct_v >= 6) {
+ decode(standard_compression_type, bl);
+ }
+ if (struct_v >= 7) {
+ decode(storage_classes, bl);
+ } else {
+ storage_classes.set_storage_class(RGW_STORAGE_CLASS_STANDARD, &standard_data_pool,
+ (!standard_compression_type.empty() ? &standard_compression_type : nullptr));
+ }
+ if (struct_v >= 8) {
+ decode(inline_data, bl);
+ }
+ DECODE_FINISH(bl);
+ }
+ const rgw_pool& get_data_extra_pool() const {
+ static rgw_pool no_pool;
+ if (data_extra_pool.empty()) {
+ return storage_classes.get_standard().data_pool.get_value_or(no_pool);
+ }
+ return data_extra_pool;
+ }
+ const rgw_pool& get_data_pool(const std::string& sc) const {
+ const RGWZoneStorageClass *storage_class;
+ static rgw_pool no_pool;
+
+ if (!storage_classes.find(sc, &storage_class)) {
+ return storage_classes.get_standard().data_pool.get_value_or(no_pool);
+ }
+
+ return storage_class->data_pool.get_value_or(no_pool);
+ }
+ const rgw_pool& get_standard_data_pool() const {
+ return get_data_pool(RGW_STORAGE_CLASS_STANDARD);
+ }
+
+ const std::string& get_compression_type(const std::string& sc) const {
+ const RGWZoneStorageClass *storage_class;
+ static std::string no_compression;
+
+ if (!storage_classes.find(sc, &storage_class)) {
+ return no_compression;
+ }
+ return storage_class->compression_type.get_value_or(no_compression);
+ }
+
+ bool storage_class_exists(const std::string& sc) const {
+ return storage_classes.exists(sc);
+ }
+
+ void dump(Formatter *f) const;
+ void decode_json(JSONObj *obj);
+
+};
+WRITE_CLASS_ENCODER(RGWZonePlacementInfo)
+
+struct RGWZone {
+ std::string id;
+ std::string name;
+ std::list<std::string> endpoints; // std::vector?
+ bool log_meta;
+ bool log_data;
+ bool read_only;
+ std::string tier_type;
+ std::string redirect_zone;
+
+/**
+ * Represents the number of shards for the bucket index object, a value of zero
+ * indicates there is no sharding. By default (no sharding, the name of the object
+ * is '.dir.{marker}', with sharding, the name is '.dir.{marker}.{sharding_id}',
+ * sharding_id is zero-based value. It is not recommended to set a too large value
+ * (e.g. thousand) as it increases the cost for bucket listing.
+ */
+ uint32_t bucket_index_max_shards;
+
+ // pre-shard buckets on creation to enable some write-parallism by default,
+ // delay the need to reshard as the bucket grows, and (in multisite) get some
+ // bucket index sharding where dynamic resharding is not supported
+ static constexpr uint32_t default_bucket_index_max_shards = 11;
+
+ bool sync_from_all;
+ std::set<std::string> sync_from; /* list of zones to sync from */
+
+ rgw::zone_features::set supported_features;
+
+ RGWZone()
+ : log_meta(false), log_data(false), read_only(false),
+ bucket_index_max_shards(default_bucket_index_max_shards),
+ sync_from_all(true) {}
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(8, 1, bl);
+ encode(name, bl);
+ encode(endpoints, bl);
+ encode(log_meta, bl);
+ encode(log_data, bl);
+ encode(bucket_index_max_shards, bl);
+ encode(id, bl);
+ encode(read_only, bl);
+ encode(tier_type, bl);
+ encode(sync_from_all, bl);
+ encode(sync_from, bl);
+ encode(redirect_zone, bl);
+ encode(supported_features, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(8, bl);
+ decode(name, bl);
+ if (struct_v < 4) {
+ id = name;
+ }
+ decode(endpoints, bl);
+ if (struct_v >= 2) {
+ decode(log_meta, bl);
+ decode(log_data, bl);
+ }
+ if (struct_v >= 3) {
+ decode(bucket_index_max_shards, bl);
+ }
+ if (struct_v >= 4) {
+ decode(id, bl);
+ decode(read_only, bl);
+ }
+ if (struct_v >= 5) {
+ decode(tier_type, bl);
+ }
+ if (struct_v >= 6) {
+ decode(sync_from_all, bl);
+ decode(sync_from, bl);
+ }
+ if (struct_v >= 7) {
+ decode(redirect_zone, bl);
+ }
+ if (struct_v >= 8) {
+ decode(supported_features, bl);
+ }
+ DECODE_FINISH(bl);
+ }
+ void dump(Formatter *f) const;
+ void decode_json(JSONObj *obj);
+ static void generate_test_instances(std::list<RGWZone*>& o);
+
+ bool is_read_only() const { return read_only; }
+
+ bool syncs_from(const std::string& zone_name) const {
+ return (sync_from_all || sync_from.find(zone_name) != sync_from.end());
+ }
+
+ bool supports(std::string_view feature) const {
+ return supported_features.contains(feature);
+ }
+};
+WRITE_CLASS_ENCODER(RGWZone)
+
+struct RGWDefaultZoneGroupInfo {
+ std::string default_zonegroup;
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(default_zonegroup, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(default_zonegroup, bl);
+ DECODE_FINISH(bl);
+ }
+ void dump(Formatter *f) const;
+ void decode_json(JSONObj *obj);
+ //todo: implement ceph-dencoder
+};
+WRITE_CLASS_ENCODER(RGWDefaultZoneGroupInfo)
+
+struct RGWTierACLMapping {
+ ACLGranteeTypeEnum type{ACL_TYPE_CANON_USER};
+ std::string source_id;
+ std::string dest_id;
+
+ RGWTierACLMapping() = default;
+
+ RGWTierACLMapping(ACLGranteeTypeEnum t,
+ const std::string& s,
+ const std::string& d) : type(t),
+ source_id(s),
+ dest_id(d) {}
+
+ void init(const JSONFormattable& config) {
+ const std::string& t = config["type"];
+
+ if (t == "email") {
+ type = ACL_TYPE_EMAIL_USER;
+ } else if (t == "uri") {
+ type = ACL_TYPE_GROUP;
+ } else {
+ type = ACL_TYPE_CANON_USER;
+ }
+
+ source_id = config["source_id"];
+ dest_id = config["dest_id"];
+ }
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode((uint32_t)type, bl);
+ encode(source_id, bl);
+ encode(dest_id, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ uint32_t it;
+ decode(it, bl);
+ type = (ACLGranteeTypeEnum)it;
+ decode(source_id, bl);
+ decode(dest_id, bl);
+ DECODE_FINISH(bl);
+ }
+ void dump(Formatter *f) const;
+ void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWTierACLMapping)
+
+enum HostStyle {
+ PathStyle = 0,
+ VirtualStyle = 1,
+};
+
+struct RGWZoneGroupPlacementTierS3 {
+#define DEFAULT_MULTIPART_SYNC_PART_SIZE (32 * 1024 * 1024)
+ std::string endpoint;
+ RGWAccessKey key;
+ std::string region;
+ HostStyle host_style{PathStyle};
+ std::string target_storage_class;
+
+ /* Should below be bucket/zone specific?? */
+ std::string target_path;
+ std::map<std::string, RGWTierACLMapping> acl_mappings;
+
+ uint64_t multipart_sync_threshold{DEFAULT_MULTIPART_SYNC_PART_SIZE};
+ uint64_t multipart_min_part_size{DEFAULT_MULTIPART_SYNC_PART_SIZE};
+
+ int update_params(const JSONFormattable& config);
+ int clear_params(const JSONFormattable& config);
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(endpoint, bl);
+ encode(key, bl);
+ encode(region, bl);
+ encode((uint32_t)host_style, bl); // XXX kill C-style casts
+ encode(target_storage_class, bl);
+ encode(target_path, bl);
+ encode(acl_mappings, bl);
+ encode(multipart_sync_threshold, bl);
+ encode(multipart_min_part_size, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(endpoint, bl);
+ decode(key, bl);
+ decode(region, bl);
+
+ uint32_t it;
+ decode(it, bl);
+ host_style = (HostStyle)it; // XXX can't this be HostStyle(it)?
+
+ decode(target_storage_class, bl);
+ decode(target_path, bl);
+ decode(acl_mappings, bl);
+ decode(multipart_sync_threshold, bl);
+ decode(multipart_min_part_size, bl);
+ DECODE_FINISH(bl);
+ }
+ void dump(Formatter *f) const;
+ void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWZoneGroupPlacementTierS3)
+
+struct RGWZoneGroupPlacementTier {
+ std::string tier_type;
+ std::string storage_class;
+ bool retain_head_object = false;
+
+ struct _tier {
+ RGWZoneGroupPlacementTierS3 s3;
+ } t;
+
+ int update_params(const JSONFormattable& config);
+ int clear_params(const JSONFormattable& config);
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(tier_type, bl);
+ encode(storage_class, bl);
+ encode(retain_head_object, bl);
+ if (tier_type == "cloud-s3") {
+ encode(t.s3, bl);
+ }
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(tier_type, bl);
+ decode(storage_class, bl);
+ decode(retain_head_object, bl);
+ if (tier_type == "cloud-s3") {
+ decode(t.s3, bl);
+ }
+ DECODE_FINISH(bl);
+ }
+
+ void dump(Formatter *f) const;
+ void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWZoneGroupPlacementTier)
+
+struct RGWZoneGroupPlacementTarget {
+ std::string name;
+ std::set<std::string> tags;
+ std::set<std::string> storage_classes;
+ std::map<std::string, RGWZoneGroupPlacementTier> tier_targets;
+
+ bool user_permitted(const std::list<std::string>& user_tags) const {
+ if (tags.empty()) {
+ return true;
+ }
+ for (auto& rule : user_tags) {
+ if (tags.find(rule) != tags.end()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(3, 1, bl);
+ encode(name, bl);
+ encode(tags, bl);
+ encode(storage_classes, bl);
+ encode(tier_targets, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(3, bl);
+ decode(name, bl);
+ decode(tags, bl);
+ if (struct_v >= 2) {
+ decode(storage_classes, bl);
+ }
+ if (storage_classes.empty()) {
+ storage_classes.insert(RGW_STORAGE_CLASS_STANDARD);
+ }
+ if (struct_v >= 3) {
+ decode(tier_targets, bl);
+ }
+ DECODE_FINISH(bl);
+ }
+ void dump(Formatter *f) const;
+ void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWZoneGroupPlacementTarget)