rgw_lua_background.cc)
list(APPEND librgw_common_srcs
+ store/immutable_config/store.cc
+ store/json_config/store.cc
store/rados/config/impl.cc
store/rados/config/period.cc
store/rados/config/period_config.cc
--- /dev/null
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2022 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.
+ *
+ */
+
+#include "rgw_zone.h"
+#include "store.h"
+
+namespace rgw::sal {
+
+ImmutableConfigStore::ImmutableConfigStore(const RGWZoneGroup& zonegroup,
+ const RGWZoneParams& zone,
+ const RGWPeriodConfig& period_config)
+ : zonegroup(zonegroup), zone(zone), period_config(period_config)
+{
+}
+
+// Realm
+int ImmutableConfigStore::write_default_realm_id(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ std::string_view realm_id)
+{
+ return -EROFS;
+}
+
+int ImmutableConfigStore::read_default_realm_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string& realm_id)
+{
+ return -ENOENT;
+}
+
+int ImmutableConfigStore::delete_default_realm_id(const DoutPrefixProvider* dpp,
+ optional_yield y)
+{
+ return -EROFS;
+}
+
+
+int ImmutableConfigStore::create_realm(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ const RGWRealm& info,
+ std::unique_ptr<RealmWriter>* writer)
+{
+ return -EROFS;
+}
+
+int ImmutableConfigStore::read_realm_by_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id,
+ RGWRealm& info,
+ std::unique_ptr<RealmWriter>* writer)
+{
+ return -ENOENT;
+}
+
+int ImmutableConfigStore::read_realm_by_name(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_name,
+ RGWRealm& info,
+ std::unique_ptr<RealmWriter>* writer)
+{
+ return -ENOENT;
+}
+
+int ImmutableConfigStore::read_default_realm(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ RGWRealm& info,
+ std::unique_ptr<RealmWriter>* writer)
+{
+ return -ENOENT;
+}
+
+int ImmutableConfigStore::read_realm_id(const DoutPrefixProvider* dpp,
+ optional_yield y, std::string_view realm_name,
+ std::string& realm_id)
+{
+ return -ENOENT;
+}
+
+int ImmutableConfigStore::realm_notify_new_period(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ const RGWPeriod& period)
+{
+ return -ENOTSUP;
+}
+
+int ImmutableConfigStore::list_realm_names(const DoutPrefixProvider* dpp,
+ optional_yield y, const std::string& marker,
+ std::span<std::string> entries,
+ ListResult<std::string>& result)
+{
+ result.next.clear();
+ result.entries = entries.first(0);
+ return 0;
+}
+
+
+// Period
+int ImmutableConfigStore::create_period(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ const RGWPeriod& info)
+{
+ return -EROFS;
+}
+
+int ImmutableConfigStore::read_period(const DoutPrefixProvider* dpp,
+ optional_yield y, std::string_view period_id,
+ std::optional<uint32_t> epoch, RGWPeriod& info)
+{
+ return -ENOENT;
+}
+
+int ImmutableConfigStore::delete_period(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view period_id)
+{
+ return -EROFS;
+}
+
+int ImmutableConfigStore::list_period_ids(const DoutPrefixProvider* dpp,
+ optional_yield y, const std::string& marker,
+ std::span<std::string> entries,
+ ListResult<std::string>& result)
+{
+ result.next.clear();
+ result.entries = entries.first(0);
+ return 0;
+}
+
+
+// ZoneGroup
+
+class ImmutableZoneGroupWriter : public ZoneGroupWriter {
+ public:
+ int write(const DoutPrefixProvider* dpp, optional_yield y,
+ const RGWZoneGroup& info) override
+ {
+ return -EROFS;
+ }
+ int rename(const DoutPrefixProvider* dpp, optional_yield y,
+ RGWZoneGroup& info, std::string_view new_name) override
+ {
+ return -EROFS;
+ }
+ int remove(const DoutPrefixProvider* dpp, optional_yield y) override
+ {
+ return -EROFS;
+ }
+};
+
+int ImmutableConfigStore::write_default_zonegroup_id(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ std::string_view realm_id,
+ std::string_view zonegroup_id)
+{
+ return -EROFS;
+}
+
+int ImmutableConfigStore::read_default_zonegroup_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id,
+ std::string& zonegroup_id)
+{
+ if (!realm_id.empty()) {
+ return -ENOENT;
+ }
+ zonegroup_id = zonegroup.id;
+ return 0;
+}
+
+int ImmutableConfigStore::delete_default_zonegroup_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id)
+{
+ return -EROFS;
+}
+
+
+int ImmutableConfigStore::create_zonegroup(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ const RGWZoneGroup& info,
+ std::unique_ptr<ZoneGroupWriter>* writer)
+{
+ return -EROFS;
+}
+
+int ImmutableConfigStore::read_zonegroup_by_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view zonegroup_id,
+ RGWZoneGroup& info,
+ std::unique_ptr<ZoneGroupWriter>* writer)
+{
+ if (zonegroup_id != zonegroup.id) {
+ return -ENOENT;
+ }
+
+ info = zonegroup;
+
+ if (writer) {
+ *writer = std::make_unique<ImmutableZoneGroupWriter>();
+ }
+ return 0;
+}
+int ImmutableConfigStore::read_zonegroup_by_name(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view zonegroup_name,
+ RGWZoneGroup& info,
+ std::unique_ptr<ZoneGroupWriter>* writer)
+{
+ if (zonegroup_name != zonegroup.name) {
+ return -ENOENT;
+ }
+
+ info = zonegroup;
+
+ if (writer) {
+ *writer = std::make_unique<ImmutableZoneGroupWriter>();
+ }
+ return 0;
+}
+
+int ImmutableConfigStore::read_default_zonegroup(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id,
+ RGWZoneGroup& info,
+ std::unique_ptr<ZoneGroupWriter>* writer)
+{
+ info = zonegroup;
+
+ if (writer) {
+ *writer = std::make_unique<ImmutableZoneGroupWriter>();
+ }
+ return 0;
+}
+
+int ImmutableConfigStore::list_zonegroup_names(const DoutPrefixProvider* dpp,
+ optional_yield y, const std::string& marker,
+ std::span<std::string> entries,
+ ListResult<std::string>& result)
+{
+ if (marker < zonegroup.name) {
+ entries[0] = zonegroup.name;
+ result.next = zonegroup.name;
+ result.entries = entries.first(1);
+ } else {
+ result.next.clear();
+ result.entries = entries.first(0);
+ }
+ return 0;
+}
+
+// Zone
+
+class ImmutableZoneWriter : public ZoneWriter {
+ public:
+ int write(const DoutPrefixProvider* dpp, optional_yield y,
+ const RGWZoneParams& info) override
+ {
+ return -EROFS;
+ }
+ int rename(const DoutPrefixProvider* dpp, optional_yield y,
+ RGWZoneParams& info, std::string_view new_name) override
+ {
+ return -EROFS;
+ }
+ int remove(const DoutPrefixProvider* dpp, optional_yield y) override
+ {
+ return -EROFS;
+ }
+};
+
+int ImmutableConfigStore::write_default_zone_id(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ std::string_view realm_id,
+ std::string_view zone_id)
+{
+ return -EROFS;
+}
+
+int ImmutableConfigStore::read_default_zone_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id,
+ std::string& zone_id)
+{
+ if (realm_id.empty()) {
+ return -ENOENT;
+ }
+ zone_id = zone.id;
+ return 0;
+}
+
+int ImmutableConfigStore::delete_default_zone_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id)
+{
+ return -EROFS;
+}
+
+
+int ImmutableConfigStore::create_zone(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ const RGWZoneParams& info,
+ std::unique_ptr<ZoneWriter>* writer)
+{
+ return -EROFS;
+}
+
+int ImmutableConfigStore::read_zone_by_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view zone_id,
+ RGWZoneParams& info,
+ std::unique_ptr<ZoneWriter>* writer)
+{
+ if (zone_id != zone.id) {
+ return -ENOENT;
+ }
+
+ info = zone;
+
+ if (writer) {
+ *writer = std::make_unique<ImmutableZoneWriter>();
+ }
+ return 0;
+}
+
+int ImmutableConfigStore::read_zone_by_name(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view zone_name,
+ RGWZoneParams& info,
+ std::unique_ptr<ZoneWriter>* writer)
+{
+ if (zone_name != zone.name) {
+ return -ENOENT;
+ }
+
+ info = zone;
+
+ if (writer) {
+ *writer = std::make_unique<ImmutableZoneWriter>();
+ }
+ return 0;
+}
+
+int ImmutableConfigStore::read_default_zone(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id,
+ RGWZoneParams& info,
+ std::unique_ptr<ZoneWriter>* writer)
+{
+ if (!realm_id.empty()) {
+ return -ENOENT;
+ }
+
+ info = zone;
+
+ if (writer) {
+ *writer = std::make_unique<ImmutableZoneWriter>();
+ }
+ return 0;
+}
+
+int ImmutableConfigStore::list_zone_names(const DoutPrefixProvider* dpp,
+ optional_yield y, const std::string& marker,
+ std::span<std::string> entries,
+ ListResult<std::string>& result)
+{
+ if (marker < zone.name) {
+ entries[0] = zone.name;
+ result.next = zone.name;
+ result.entries = entries.first(1);
+ } else {
+ result.next.clear();
+ result.entries = entries.first(0);
+ }
+ return 0;
+}
+
+
+// PeriodConfig
+int ImmutableConfigStore::read_period_config(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id,
+ RGWPeriodConfig& info)
+{
+ if (!realm_id.empty()) {
+ return -ENOENT;
+ }
+
+ info = period_config;
+ return 0;
+}
+
+int ImmutableConfigStore::write_period_config(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ std::string_view realm_id,
+ const RGWPeriodConfig& info)
+{
+ return -EROFS;
+}
+
+
+/// ImmutableConfigStore factory function
+auto create_immutable_config_store(const DoutPrefixProvider* dpp,
+ const RGWZoneGroup& zonegroup,
+ const RGWZoneParams& zone,
+ const RGWPeriodConfig& period_config)
+ -> std::unique_ptr<ConfigStore>
+{
+ return std::make_unique<ImmutableConfigStore>(zonegroup, zone, period_config);
+}
+
+} // namespace rgw::sal
--- /dev/null
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2022 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.
+ *
+ */
+
+#pragma once
+
+#include "rgw_sal_config.h"
+
+namespace rgw::sal {
+
+/// A read-only ConfigStore that serves the given default zonegroup and zone.
+class ImmutableConfigStore : public ConfigStore {
+ public:
+ explicit ImmutableConfigStore(const RGWZoneGroup& zonegroup,
+ const RGWZoneParams& zone,
+ const RGWPeriodConfig& period_config);
+
+ // Realm
+ virtual int write_default_realm_id(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ std::string_view realm_id) override;
+ virtual int read_default_realm_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string& realm_id) override;
+ virtual int delete_default_realm_id(const DoutPrefixProvider* dpp,
+ optional_yield y) override;
+
+ virtual int create_realm(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ const RGWRealm& info,
+ std::unique_ptr<RealmWriter>* writer) override;
+ virtual int read_realm_by_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id,
+ RGWRealm& info,
+ std::unique_ptr<RealmWriter>* writer) override;
+ virtual int read_realm_by_name(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_name,
+ RGWRealm& info,
+ std::unique_ptr<RealmWriter>* writer) override;
+ virtual int read_default_realm(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ RGWRealm& info,
+ std::unique_ptr<RealmWriter>* writer) override;
+ virtual int read_realm_id(const DoutPrefixProvider* dpp,
+ optional_yield y, std::string_view realm_name,
+ std::string& realm_id) override;
+ virtual int realm_notify_new_period(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ const RGWPeriod& period) override;
+ virtual int list_realm_names(const DoutPrefixProvider* dpp,
+ optional_yield y, const std::string& marker,
+ std::span<std::string> entries,
+ ListResult<std::string>& result) override;
+
+ // Period
+ virtual int create_period(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ const RGWPeriod& info) override;
+ virtual int read_period(const DoutPrefixProvider* dpp,
+ optional_yield y, std::string_view period_id,
+ std::optional<uint32_t> epoch, RGWPeriod& info) override;
+ virtual int delete_period(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view period_id) override;
+ virtual int list_period_ids(const DoutPrefixProvider* dpp,
+ optional_yield y, const std::string& marker,
+ std::span<std::string> entries,
+ ListResult<std::string>& result) override;
+
+ // ZoneGroup
+ virtual int write_default_zonegroup_id(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ std::string_view realm_id,
+ std::string_view zonegroup_id) override;
+ virtual int read_default_zonegroup_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id,
+ std::string& zonegroup_id) override;
+ virtual int delete_default_zonegroup_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id) override;
+
+ virtual int create_zonegroup(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ const RGWZoneGroup& info,
+ std::unique_ptr<ZoneGroupWriter>* writer) override;
+ virtual int read_zonegroup_by_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view zonegroup_id,
+ RGWZoneGroup& info,
+ std::unique_ptr<ZoneGroupWriter>* writer) override;
+ virtual int read_zonegroup_by_name(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view zonegroup_name,
+ RGWZoneGroup& info,
+ std::unique_ptr<ZoneGroupWriter>* writer) override;
+ virtual int read_default_zonegroup(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id,
+ RGWZoneGroup& info,
+ std::unique_ptr<ZoneGroupWriter>* writer) override;
+ virtual int list_zonegroup_names(const DoutPrefixProvider* dpp,
+ optional_yield y, const std::string& marker,
+ std::span<std::string> entries,
+ ListResult<std::string>& result) override;
+
+ // Zone
+ virtual int write_default_zone_id(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ std::string_view realm_id,
+ std::string_view zone_id) override;
+ virtual int read_default_zone_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id,
+ std::string& zone_id) override;
+ virtual int delete_default_zone_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id) override;
+
+ virtual int create_zone(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ const RGWZoneParams& info,
+ std::unique_ptr<ZoneWriter>* writer) override;
+ virtual int read_zone_by_id(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view zone_id,
+ RGWZoneParams& info,
+ std::unique_ptr<ZoneWriter>* writer) override;
+ virtual int read_zone_by_name(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view zone_name,
+ RGWZoneParams& info,
+ std::unique_ptr<ZoneWriter>* writer) override;
+ virtual int read_default_zone(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id,
+ RGWZoneParams& info,
+ std::unique_ptr<ZoneWriter>* writer) override;
+ virtual int list_zone_names(const DoutPrefixProvider* dpp,
+ optional_yield y, const std::string& marker,
+ std::span<std::string> entries,
+ ListResult<std::string>& result) override;
+
+ // PeriodConfig
+ virtual int read_period_config(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ std::string_view realm_id,
+ RGWPeriodConfig& info) override;
+ virtual int write_period_config(const DoutPrefixProvider* dpp,
+ optional_yield y, bool exclusive,
+ std::string_view realm_id,
+ const RGWPeriodConfig& info) override;
+
+ private:
+ const RGWZoneGroup zonegroup;
+ const RGWZoneParams zone;
+ const RGWPeriodConfig period_config;
+}; // ImmutableConfigStore
+
+
+/// ImmutableConfigStore factory function
+auto create_immutable_config_store(const DoutPrefixProvider* dpp,
+ const RGWZoneGroup& zonegroup,
+ const RGWZoneParams& zone,
+ const RGWPeriodConfig& period_config)
+ -> std::unique_ptr<ConfigStore>;
+
+} // namespace rgw::sal
--- /dev/null
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2022 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.
+ *
+ */
+
+#include <system_error>
+#include "include/buffer.h"
+#include "common/errno.h"
+#include "common/ceph_json.h"
+#include "rgw_zone.h"
+#include "store/immutable_config/store.h"
+#include "store.h"
+
+namespace rgw::sal {
+
+namespace {
+
+struct DecodedConfig {
+ RGWZoneGroup zonegroup;
+ RGWZoneParams zone;
+ RGWPeriodConfig period_config;
+
+ void decode_json(JSONObj *obj)
+ {
+ JSONDecoder::decode_json("zonegroup", zonegroup, obj);
+ JSONDecoder::decode_json("zone", zone, obj);
+ JSONDecoder::decode_json("period_config", period_config, obj);
+ }
+};
+
+static void parse_config(const DoutPrefixProvider* dpp, const char* filename)
+{
+ bufferlist bl;
+ std::string errmsg;
+ int r = bl.read_file(filename, &errmsg);
+ if (r < 0) {
+ ldpp_dout(dpp, 0) << "failed to read json config file '" << filename
+ << "': " << errmsg << dendl;
+ throw std::system_error(-r, std::system_category());
+ }
+
+ JSONParser p;
+ if (!p.parse(bl.c_str(), bl.length())) {
+ ldpp_dout(dpp, 0) << "failed to parse json config file" << dendl;
+ throw std::system_error(make_error_code(std::errc::invalid_argument));
+ }
+
+ DecodedConfig config;
+ try {
+ decode_json_obj(config, &p);
+ } catch (const JSONDecoder::err& e) {
+ ldpp_dout(dpp, 0) << "failed to decode JSON input: " << e.what() << dendl;
+ throw std::system_error(make_error_code(std::errc::invalid_argument));
+ }
+}
+
+void sanity_check_config(const DoutPrefixProvider* dpp, DecodedConfig& config)
+{
+ if (config.zonegroup.id.empty()) {
+ config.zonegroup.id = "default";
+ }
+ if (config.zonegroup.name.empty()) {
+ config.zonegroup.name = "default";
+ }
+ if (config.zonegroup.api_name.empty()) {
+ config.zonegroup.api_name = config.zonegroup.name;
+ }
+
+ if (config.zone.id.empty()) {
+ config.zone.id = "default";
+ }
+ if (config.zone.name.empty()) {
+ config.zone.name = "default";
+ }
+
+ // add default placement if it doesn't exist
+ rgw_pool pool;
+ RGWZonePlacementInfo placement;
+ placement.storage_classes.set_storage_class(
+ RGW_STORAGE_CLASS_STANDARD, &pool, nullptr);
+ config.zone.placement_pools.emplace("default-placement",
+ std::move(placement));
+
+ std::set<rgw_pool> pools;
+ int r = rgw::init_zone_pool_names(dpp, null_yield, pools, config.zone);
+ if (r < 0) {
+ ldpp_dout(dpp, 0) << "failed to set default zone pool names" << dendl;
+ throw std::system_error(-r, std::system_category());
+ }
+
+ // verify that config.zonegroup only contains config.zone
+ if (config.zonegroup.zones.size() > 1) {
+ ldpp_dout(dpp, 0) << "zonegroup cannot contain multiple zones" << dendl;
+ throw std::system_error(make_error_code(std::errc::invalid_argument));
+ }
+
+ if (config.zonegroup.zones.size() == 1) {
+ auto z = config.zonegroup.zones.begin();
+ if (z->first != config.zone.id) {
+ ldpp_dout(dpp, 0) << "zonegroup contains unknown zone id="
+ << z->first << dendl;
+ throw std::system_error(make_error_code(std::errc::invalid_argument));
+ }
+ if (z->second.id != config.zone.id) {
+ ldpp_dout(dpp, 0) << "zonegroup contains unknown zone id="
+ << z->second.id << dendl;
+ throw std::system_error(make_error_code(std::errc::invalid_argument));
+ }
+ if (z->second.name != config.zone.name) {
+ ldpp_dout(dpp, 0) << "zonegroup contains unknown zone name="
+ << z->second.name << dendl;
+ throw std::system_error(make_error_code(std::errc::invalid_argument));
+ }
+ if (config.zonegroup.master_zone != config.zone.id) {
+ ldpp_dout(dpp, 0) << "zonegroup contains unknown master_zone="
+ << config.zonegroup.master_zone << dendl;
+ throw std::system_error(make_error_code(std::errc::invalid_argument));
+ }
+ } else {
+ // add the zone to the group
+ const bool is_master = true;
+ const bool read_only = false;
+ std::list<std::string> endpoints;
+ std::list<std::string> sync_from;
+ std::list<std::string> sync_from_rm;
+ rgw::zone_features::set enable_features;
+ rgw::zone_features::set disable_features;
+
+ enable_features.insert(rgw::zone_features::supported.begin(),
+ rgw::zone_features::supported.end());
+
+ int r = rgw::add_zone_to_group(dpp, config.zonegroup, config.zone,
+ &is_master, &read_only, endpoints,
+ nullptr, nullptr, sync_from, sync_from_rm,
+ nullptr, std::nullopt,
+ enable_features, disable_features);
+ if (r < 0) {
+ ldpp_dout(dpp, 0) << "failed to add zone to zonegroup: "
+ << cpp_strerror(r) << dendl;
+ throw std::system_error(-r, std::system_category());
+ }
+
+ config.zonegroup.enabled_features = std::move(enable_features);
+ }
+
+ // insert the default placement target if it doesn't exist
+ auto target = RGWZoneGroupPlacementTarget{.name = "default-placement"};
+ config.zonegroup.placement_targets.emplace(target.name, target);
+ if (config.zonegroup.default_placement.name.empty()) {
+ config.zonegroup.default_placement.name = target.name;
+ }
+}
+
+} // anonymous namespace
+
+auto create_json_config_store(const DoutPrefixProvider* dpp,
+ const std::string& filename)
+ -> std::unique_ptr<ConfigStore>
+{
+ DecodedConfig config;
+ parse_config(dpp, filename.c_str());
+ sanity_check_config(dpp, config);
+ return create_immutable_config_store(dpp, config.zonegroup, config.zone,
+ config.period_config);
+}
+
+} // namespace rgw::sal
--- /dev/null
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2022 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.
+ *
+ */
+
+#pragma once
+
+#include "store/immutable_config/store.h"
+
+namespace rgw::sal {
+
+/// Create an immutable ConfigStore by parsing the zonegroup and zone from the
+/// given json filename.
+auto create_json_config_store(const DoutPrefixProvider* dpp,
+ const std::string& filename)
+ -> std::unique_ptr<ConfigStore>;
+
+} // namespace rgw::sal