diff options
Diffstat (limited to 'src/rgw/rgw_zone_types.h')
-rw-r--r-- | src/rgw/rgw_zone_types.h | 625 |
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 = ≻ + 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) |