driver/rados/rgw_trim_mdlog.cc
driver/rados/rgw_user.cc
driver/rados/oidc.cc
+ driver/rados/oidcs.cc
driver/rados/role.cc
driver/rados/roles.cc
driver/rados/sync_fairness.cc
static constexpr std::string_view groups_oid_prefix = "groups.";
static constexpr std::string_view roles_oid_prefix = "roles.";
static constexpr std::string_view topics_oid_prefix = "topics.";
+static constexpr std::string_view oidcs_oid_prefix = "oidcs.";
static const std::string account_oid_prefix = "account.";
static constexpr std::string_view name_oid_prefix = "name.";
return {zone.account_pool, get_topics_key(account_id)};
}
+static std::string get_oidcs_key(std::string_view account_id) {
+ return string_cat_reserve(oidcs_oid_prefix, account_id);
+}
+rgw_raw_obj get_oidcs_obj(const RGWZoneParams& zone,
+ std::string_view account_id) {
+ return {zone.account_pool, get_oidcs_key(account_id)};
+}
+
static std::string get_account_key(std::string_view account_id) {
return string_cat_reserve(account_oid_prefix, account_id);
}
rgw_raw_obj get_topics_obj(const RGWZoneParams& zone,
std::string_view account_id);
+/// Return the rados object that tracks the given account's OIDC providers. This
+/// can be used with the cls_user interface in namespace rgwrados::oidcs.
+rgw_raw_obj get_oidcs_obj(
+ const RGWZoneParams& zone,
+ std::string_view account_id);
+
/// Read account info by id
int read(const DoutPrefixProvider* dpp,
#include "oidc.h"
+#include <limits>
+
+#include "account.h"
+#include "oidcs.h"
#include "common/errno.h"
+#include "rgw_account.h"
#include "rgw_common.h"
#include "rgw_metadata.h"
#include "rgw_metadata_lister.h"
return r;
}
+ if (rgw::account::validate_id(info.tenant)) {
+ // link the OIDC provider to its account
+ const auto& oidcs = account::get_oidcs_obj(zone, info.tenant);
+ r = oidcs::add(
+ dpp, y, rados, oidcs, info, false,
+ std::numeric_limits<uint32_t>::max());
+ if (r < 0) {
+ ldpp_dout(dpp, 0) << "WARNING: could not link OIDC provider to account "
+ << info.tenant << ": " << cpp_strerror(r) << dendl;
+ } // not fatal
+ }
// record in the mdlog on success
if (mdlog) {
return r;
}
+ if (rgw::account::validate_id(tenant)) {
+ // unlink the OIDC provider from its account
+ const auto& oidcs = account::get_oidcs_obj(zone, std::string(tenant));
+ r = oidcs::remove(dpp, y, rados, oidcs, url);
+ if (r < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: could not unlink OIDC provider from account "
+ << tenant << ": " << cpp_strerror(r) << dendl;
+ } // not fatal
+ }
// record in the mdlog on success
if (mdlog) {
std::string_view tenant,
std::vector<RGWOIDCProviderInfo>& providers)
{
+ // Use optimized account index if tenant is an account
+ if (rgw::account::validate_id(tenant)) {
+ return list_account_oidcs(dpp, y, sysobj, rados, zone, tenant, providers);
+ }
+
// Prefix format: "{tenant}oidc_url." to match original implementation
std::string prefix = string_cat_reserve(tenant, oidc_url_oid_prefix);
auto& pool = zone.oidc_pool;
return 0;
}
+int
+list_oidc_urls(
+ const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const RGWZoneParams& zone,
+ std::string_view account_id,
+ std::string_view marker,
+ uint32_t max_items,
+ std::vector<std::string>& urls,
+ std::string& next_marker)
+{
+ const rgw_raw_obj obj = account::get_oidcs_obj(zone, account_id);
+ return oidcs::list(dpp, y, rados, obj, marker, max_items, urls, next_marker);
+}
+
+int
+list_account_oidcs(
+ const DoutPrefixProvider* dpp,
+ optional_yield y,
+ RGWSI_SysObj& sysobj,
+ librados::Rados& rados,
+ const RGWZoneParams& zone,
+ std::string_view account_id,
+ std::vector<RGWOIDCProviderInfo>& providers)
+{
+ // Use the account index to get OIDC provider URLs
+ std::vector<std::string> urls;
+ std::string marker;
+ std::string next_marker;
+
+ do {
+ urls.clear();
+ int r = list_oidc_urls(dpp, y, rados, zone, account_id, marker,
+ 1000, urls, next_marker);
+ if (r < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: failed to list OIDC provider URLs for account "
+ << account_id << ": " << cpp_strerror(r) << dendl;
+ return r;
+ }
+
+ for (const auto& url : urls) {
+ RGWOIDCProviderInfo info;
+ r = read(dpp, y, sysobj, zone, account_id, url, info);
+ if (r == -ENOENT) {
+ // OIDC provider was deleted, skip it
+ ldpp_dout(dpp, 10) << "OIDC provider " << url << " not found, skipping" << dendl;
+ continue;
+ }
+ if (r < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: failed to read OIDC provider " << url
+ << ": " << cpp_strerror(r) << dendl;
+ return r;
+ }
+ providers.push_back(std::move(info));
+ }
+
+ marker = next_marker;
+ } while (!next_marker.empty());
+
+ return 0;
+}
+
class MetadataObject : public RGWMetadataObject {
RGWOIDCProviderInfo info;
std::string_view tenant,
std::vector<RGWOIDCProviderInfo>& providers);
+/// List OIDC provider URLs for an account (paginated).
+int list_oidc_urls(
+ const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const RGWZoneParams& zone,
+ std::string_view account_id,
+ std::string_view marker,
+ uint32_t max_items,
+ std::vector<std::string>& urls,
+ std::string& next_marker);
+
+/// List all OIDC providers for an account using optimized account index.
+int list_account_oidcs(
+ const DoutPrefixProvider* dpp,
+ optional_yield y,
+ RGWSI_SysObj& sysobj,
+ librados::Rados& rados,
+ const RGWZoneParams& zone,
+ std::string_view account_id,
+ std::vector<RGWOIDCProviderInfo>& providers);
+
/// OIDC provider metadata handler factory.
auto create_metadata_handler(
librados::Rados& rados,
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
+// vim: ts=8 sw=2 sts=2 expandtab ft=cpp
+
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright contributors to the Ceph project
+ *
+ * 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 "oidcs.h"
+
+#include "include/rados/librados.hpp"
+#include "cls/user/cls_user_client.h"
+#include "rgw_common.h"
+#include "rgw_oidc_provider.h"
+#include "rgw_sal.h"
+
+namespace rgwrados::oidcs {
+
+int
+add(
+ const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ const RGWOIDCProviderInfo& info,
+ bool exclusive,
+ uint32_t limit)
+{
+ cls_user_account_resource resource;
+ resource.name = url_remove_prefix(info.provider_url);
+
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ librados::ObjectWriteOperation op;
+ ::cls_user_account_resource_add(op, resource, exclusive, limit);
+ return ref.operate(dpp, std::move(op), y);
+}
+
+int
+remove(
+ const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ std::string_view provider_url)
+{
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ librados::ObjectWriteOperation op;
+ ::cls_user_account_resource_rm(op, provider_url);
+ return ref.operate(dpp, std::move(op), y);
+}
+
+int
+list(
+ const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ std::string_view marker,
+ uint32_t max_items,
+ std::vector<std::string>& provider_urls,
+ std::string& next_marker)
+{
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ librados::ObjectReadOperation op;
+ const std::string path_prefix; // unused
+ std::vector<cls_user_account_resource> entries;
+ bool truncated = false;
+ int ret = 0;
+ ::cls_user_account_resource_list(
+ op, marker, path_prefix, max_items,
+ entries, &truncated, &next_marker, &ret);
+
+ r = ref.operate(dpp, std::move(op), nullptr, y);
+ if (r == -ENOENT) {
+ next_marker.clear();
+ return 0;
+ }
+ if (r < 0) {
+ return r;
+ }
+ if (ret < 0) {
+ return ret;
+ }
+
+ for (auto& resource : entries) {
+ provider_urls.push_back(std::move(resource.name));
+ }
+
+ return 0;
+}
+
+} // namespace rgwrados::oidcs
+
+
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
+// vim: ts=8 sw=2 sts=2 expandtab ft=cpp
+
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright contributors to the Ceph project
+ *
+ * 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 <cstdint>
+#include <string>
+#include <vector>
+#include "include/rados/librados_fwd.hpp"
+#include "rgw_sal_fwd.h"
+
+class DoutPrefixProvider;
+class optional_yield;
+struct rgw_raw_obj;
+struct RGWOIDCProviderInfo;
+
+
+namespace rgwrados::oidcs {
+
+/// Add the given OIDC provider to the list.
+int add(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ const RGWOIDCProviderInfo& info,
+ bool exclusive, uint32_t limit);
+
+/// Remove the given OIDC provider from the list.
+int remove(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ std::string_view provider_url);
+
+/// Return a paginated listing of OIDC provider URLs.
+int list(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ std::string_view marker,
+ uint32_t max_items,
+ std::vector<std::string>& provider_urls,
+ std::string& next_marker);
+
+} // namespace rgwrados::oidcs
+
+