From 0adefb9a3011e93ebf588899eed7b7bbcc5fec63 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Wed, 6 Mar 2024 17:13:48 -0500 Subject: [PATCH] rgw/admin: user list accepts --account-id or -name Signed-off-by: Casey Bodley (cherry picked from commit 664151ef3866aa95cd1f8a5cbf30856809a4f282) --- src/rgw/rgw_account.cc | 76 ++++++++++++++++++++++++++++++++++++++++++ src/rgw/rgw_account.h | 7 ++++ src/rgw/rgw_admin.cc | 19 +++++++++++ 3 files changed, 102 insertions(+) diff --git a/src/rgw/rgw_account.cc b/src/rgw/rgw_account.cc index 8afd42191f5..44aa9a3d4c7 100644 --- a/src/rgw/rgw_account.cc +++ b/src/rgw/rgw_account.cc @@ -450,4 +450,80 @@ int stats(const DoutPrefixProvider* dpp, return 0; } +int list_users(const DoutPrefixProvider* dpp, rgw::sal::Driver* driver, + AdminOpState& op_state, const std::string& path_prefix, + const std::string& marker, bool max_entries_specified, + int max_entries, std::string& err_msg, + RGWFormatterFlusher& flusher, optional_yield y) +{ + int ret = 0; + RGWAccountInfo info; + rgw::sal::Attrs attrs; // ignored + RGWObjVersionTracker objv; // ignored + + if (!op_state.account_id.empty()) { + // look up account by id + ret = driver->load_account_by_id(dpp, y, op_state.account_id, + info, attrs, objv); + } else if (!op_state.account_name.empty()) { + // look up account by tenant/name + ret = driver->load_account_by_name(dpp, y, op_state.tenant, + op_state.account_name, + info, attrs, objv); + } else { + err_msg = "requires account id or name"; + return -EINVAL; + } + if (ret < 0) { + err_msg = "failed to load account"; + return ret; + } + + rgw::sal::UserList listing; + listing.next_marker = marker; + + Formatter* formatter = flusher.get_formatter(); + flusher.start(0); + + int32_t remaining = std::numeric_limits::max(); + if (max_entries_specified) { + remaining = max_entries; + formatter->open_object_section("result"); + } + formatter->open_array_section("keys"); + + do { + constexpr int32_t max_chunk = 100; + int32_t count = std::min(max_chunk, remaining); + + ret = driver->list_account_users(dpp, y, info.id, info.tenant, + path_prefix, listing.next_marker, + count, listing); + if (ret == -ENOENT) { + ret = 0; + } else if (ret < 0) { + err_msg = "failed to list users"; + return ret; + } + + for (const auto& user : listing.users) { + encode_json("key", user.user_id, formatter); + } + flusher.flush(); + + remaining -= listing.users.size(); + } while (!listing.next_marker.empty() && remaining > 0); + + formatter->close_section(); // keys + + if (max_entries_specified) { + if (!listing.next_marker.empty()) { + encode_json("marker", listing.next_marker, formatter); + } + formatter->close_section(); // result + } + flusher.flush(); + return 0; +} + } // namespace rgw::account diff --git a/src/rgw/rgw_account.h b/src/rgw/rgw_account.h index fca52a73b18..f942d674b0e 100644 --- a/src/rgw/rgw_account.h +++ b/src/rgw/rgw_account.h @@ -80,4 +80,11 @@ int stats(const DoutPrefixProvider* dpp, rgw::sal::Driver* driver, bool reset_stats, std::string& err_msg, RGWFormatterFlusher& flusher, optional_yield y); +/// list account users +int list_users(const DoutPrefixProvider* dpp, rgw::sal::Driver* driver, + AdminOpState& op_state, const std::string& path_prefix, + const std::string& marker, bool max_entries_specified, + int max_entries, std::string& err_msg, + RGWFormatterFlusher& flusher, optional_yield y); + } // namespace rgw::account diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 9c4312d062f..082fade1d15 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -9241,6 +9241,25 @@ next: opt_cmd == OPT::ACCOUNT_LIST) { if (opt_cmd == OPT::USER_LIST) { metadata_key = "user"; + + if (!account_id.empty() || !account_name.empty()) { + // list users by account + rgw::account::AdminOpState op_state; + op_state.account_id = account_id; + op_state.tenant = tenant; + op_state.account_name = account_name; + + std::string err_msg; + int ret = rgw::account::list_users( + dpp(), driver, op_state, path_prefix, marker, + max_entries_specified, max_entries, err_msg, + stream_flusher, null_yield); + if (ret < 0) { + cerr << "ERROR: " << err_msg << std::endl; + return -ret; + } + return 0; + } } else if (opt_cmd == OPT::ACCOUNT_LIST) { metadata_key = "account"; } -- 2.39.5