/* * Copyright (C) 2025-present ScyllaDB * */ /* * SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0 */ #include #include #include #include #include "utils/s3/creds.hh" #include "object_storage_endpoint_param.hh" using namespace std::string_literals; db::object_storage_endpoint_param::object_storage_endpoint_param(s3_storage s) : _data(std::move(s)) {} db::object_storage_endpoint_param::object_storage_endpoint_param(std::string endpoint, s3::endpoint_config config) : object_storage_endpoint_param(s3_storage{std::move(endpoint), std::move(config)}) {} db::object_storage_endpoint_param::object_storage_endpoint_param(gs_storage s) : _data(std::move(s)) {} db::object_storage_endpoint_param::object_storage_endpoint_param() = default; db::object_storage_endpoint_param::object_storage_endpoint_param(const object_storage_endpoint_param&) = default; std::string db::object_storage_endpoint_param::s3_storage::to_json_string() const { return fmt::format("{{ \"port\": {}, \"use_https\": {}, \"aws_region\": \"{}\", \"iam_role_arn\": \"{}\" }}", config.port, config.use_https, config.region, config.role_arn ); } std::string db::object_storage_endpoint_param::s3_storage::key() const { return endpoint; } std::string db::object_storage_endpoint_param::gs_storage::to_json_string() const { return fmt::format("{{ \"type\": \"gs\", \"credentials_file\": \"{}\" }}", credentials_file ); } std::string db::object_storage_endpoint_param::gs_storage::key() const { return endpoint; } bool db::object_storage_endpoint_param::is_s3_storage() const { return std::holds_alternative(_data); } bool db::object_storage_endpoint_param::is_gs_storage() const { return std::holds_alternative(_data); } bool db::object_storage_endpoint_param::is_storage_of_type(std::string_view type) const { if (type == s3_type) { return is_s3_storage(); } if (type == gs_type) { return is_gs_storage(); } return false; } const db::object_storage_endpoint_param::s3_storage& db::object_storage_endpoint_param::get_s3_storage() const { return std::get(_data); } const db::object_storage_endpoint_param::gs_storage& db::object_storage_endpoint_param::get_gs_storage() const { return std::get(_data); } std::strong_ordering db::object_storage_endpoint_param::operator<=>(const object_storage_endpoint_param&) const = default; bool db::object_storage_endpoint_param::operator==(const object_storage_endpoint_param&) const = default; std::string db::object_storage_endpoint_param::to_json_string() const { return std::visit([](auto& o) { return o.to_json_string(); }, _data); } std::string db::object_storage_endpoint_param::key() const { return std::visit([](auto& o) { return o.key(); }, _data); } const std::string& db::object_storage_endpoint_param::type() const { if (is_s3_storage()) { return s3_type; } else if (is_gs_storage()) { return gs_type; } throw std::runtime_error("Should not reach"); } db::object_storage_endpoint_param db::object_storage_endpoint_param::decode(const YAML::Node& node) { auto name = node["name"]; auto aws_region = node["aws_region"]; auto iam_role_arn = node["iam_role_arn"]; auto type = node["type"]; auto get_opt = [](auto& node, const std::string& key, auto def) { auto tmp = node[key]; return tmp ? tmp.template as>() : def; }; // aws s3 endpoint. if (!type || type.as() == s3_type || aws_region || iam_role_arn) { s3_storage ep; ep.endpoint = name.as(); ep.config.port = node["port"].as(); ep.config.use_https = node["https"].as(false); ep.config.region = aws_region ? aws_region.as() : std::getenv("AWS_DEFAULT_REGION"); ep.config.role_arn = iam_role_arn ? iam_role_arn.as() : ""; return object_storage_endpoint_param{std::move(ep)}; } // GCS endpoint if (type.as() == gs_type) { gs_storage ep; ep.endpoint = name.as(); ep.credentials_file = get_opt(node, "credentials_file", ""s); return object_storage_endpoint_param(std::move(ep)); } // TODO: other types throw std::invalid_argument(fmt::format("Could not decode object_storage_endpoint_param: {}", boost::lexical_cast(node))); } const std::string db::object_storage_endpoint_param::s3_type = "s3"; const std::string db::object_storage_endpoint_param::gs_type = "gs"; auto fmt::formatter::format(const db::object_storage_endpoint_param& e, fmt::format_context& ctx) const -> decltype(ctx.out()) { return fmt::format_to(ctx.out(), "object_storage_endpoint_param{}", e.to_json_string()); }