From a773e12c342e3af8cd48578b1a5fd55089af90ca Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Sun, 17 Dec 2023 21:20:02 -0500 Subject: [PATCH] rgw/sal: add interfaces for account users Signed-off-by: Casey Bodley (cherry picked from commit 8971465a35616cc9b848b7943abd167a59abdda1) --- src/rgw/driver/rados/rgw_sal_rados.cc | 84 ++++++++++++++++++++++++++- src/rgw/driver/rados/rgw_sal_rados.h | 19 ++++++ src/rgw/rgw_sal.h | 30 ++++++++++ src/rgw/rgw_sal_dbstore.cc | 30 ++++++++++ src/rgw/rgw_sal_dbstore.h | 20 +++++++ src/rgw/rgw_sal_filter.cc | 37 ++++++++++++ src/rgw/rgw_sal_filter.h | 19 ++++++ src/rgw/rgw_sal_fwd.h | 3 +- 8 files changed, 240 insertions(+), 2 deletions(-) diff --git a/src/rgw/driver/rados/rgw_sal_rados.cc b/src/rgw/driver/rados/rgw_sal_rados.cc index 45df165033cb0..5b3ddfefec789 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.cc +++ b/src/rgw/driver/rados/rgw_sal_rados.cc @@ -70,6 +70,7 @@ #include "account.h" #include "buckets.h" +#include "users.h" #include "rgw_pubsub.h" #include "topic.h" @@ -1050,7 +1051,6 @@ int RadosStore::get_user_by_swift(const DoutPrefixProvider* dpp, const std::stri return 0; } - int RadosStore::load_account_by_id(const DoutPrefixProvider* dpp, optional_yield y, std::string_view id, @@ -1199,6 +1199,88 @@ int RadosStore::load_owner_by_email(const DoutPrefixProvider* dpp, return 0; } +int RadosStore::load_account_user_by_name(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + std::string_view tenant, + std::string_view username, + std::unique_ptr* user) +{ + rgw_user uid; + uid.tenant = tenant; + + librados::Rados& rados = *getRados()->get_rados_handle(); + const RGWZoneParams& zone = svc()->zone->get_zone_params(); + const rgw_raw_obj& obj = rgwrados::account::get_users_obj(zone, account_id); + int r = rgwrados::users::get(dpp, y, rados, obj, username, uid.id); + if (r < 0) { + ldpp_dout(dpp, 20) << "failed to find account username " << username + << ": " << cpp_strerror(r) << dendl; + return r; + } + + std::unique_ptr u = get_user(uid); + r = u->load_user(dpp, y); + if (r < 0) { + ldpp_dout(dpp, 20) << "failed to load account user " << uid + << ": " << cpp_strerror(r) << dendl; + return r; + } + *user = std::move(u); + return 0; +} + +int RadosStore::count_account_users(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + uint32_t& count) +{ + librados::Rados& rados = *getRados()->get_rados_handle(); + const RGWZoneParams& zone = svc()->zone->get_zone_params(); + const rgw_raw_obj& obj = rgwrados::account::get_users_obj(zone, account_id); + return rgwrados::account::resource_count(dpp, y, rados, obj, count); +} + +int RadosStore::list_account_users(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + std::string_view tenant, + std::string_view path_prefix, + std::string_view marker, + uint32_t max_items, + UserList& listing) +{ + // fetch the list of user ids from cls_user + librados::Rados& rados = *getRados()->get_rados_handle(); + const RGWZoneParams& zone = svc()->zone->get_zone_params(); + const rgw_raw_obj& obj = rgwrados::account::get_users_obj(zone, account_id); + std::vector ids; + int r = rgwrados::users::list(dpp, y, rados, obj, marker, path_prefix, + max_items, ids, listing.next_marker); + if (r < 0) { + return r; + } + + // load the user metadata for each + for (auto& id : ids) { + rgw_user uid; + uid.tenant = tenant; + uid.id = std::move(id); + + RGWUserInfo info; + r = ctl()->user->get_info_by_uid(dpp, uid, &info, y); + if (r == -ENOENT) { + continue; + } + if (r < 0) { + return r; + } + listing.users.push_back(std::move(info)); + } + + return 0; +} + std::unique_ptr RadosStore::get_object(const rgw_obj_key& k) { return std::make_unique(this, k); diff --git a/src/rgw/driver/rados/rgw_sal_rados.h b/src/rgw/driver/rados/rgw_sal_rados.h index e429018e48761..b152fadc3c8c6 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.h +++ b/src/rgw/driver/rados/rgw_sal_rados.h @@ -196,6 +196,25 @@ class RadosStore : public StoreDriver { std::string_view email, rgw_owner& owner) override; + int load_account_user_by_name(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + std::string_view tenant, + std::string_view username, + std::unique_ptr* user) override; + int count_account_users(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + uint32_t& count) override; + int list_account_users(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + std::string_view tenant, + std::string_view path_prefix, + std::string_view marker, + uint32_t max_items, + UserList& listing) override; + virtual std::unique_ptr get_object(const rgw_obj_key& k) override; std::unique_ptr get_bucket(const RGWBucketInfo& i) override; int load_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b, diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h index e05f321956bcc..b775a48f4eed8 100644 --- a/src/rgw/rgw_sal.h +++ b/src/rgw/rgw_sal.h @@ -243,6 +243,14 @@ struct BucketList { std::string next_marker; }; +/// A list of users +struct UserList { + /// The list of results, sorted by name + std::vector users; + /// The next marker to resume listing, or empty + std::string next_marker; +}; + /** A list of key-value attributes */ using Attrs = std::map; @@ -342,6 +350,28 @@ class Driver { std::string_view email, rgw_owner& owner) = 0; + /** Load an account's user by username. */ + virtual int load_account_user_by_name(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + std::string_view tenant, + std::string_view username, + std::unique_ptr* user) = 0; + /** Count the number of users belonging to the given account. */ + virtual int count_account_users(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + uint32_t& count) = 0; + /** Return a paginated listing of the account's users. */ + virtual int list_account_users(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + std::string_view tenant, + std::string_view path_prefix, + std::string_view marker, + uint32_t max_items, + UserList& listing) = 0; + /** Get a basic Object. This Object is not looked up, and is incomplete, since is * does not have a bucket. This should only be used when an Object is needed before * there is a Bucket, otherwise use the get_object() in the Bucket class. */ diff --git a/src/rgw/rgw_sal_dbstore.cc b/src/rgw/rgw_sal_dbstore.cc index 6aa9cfe15e958..972becb391aaa 100644 --- a/src/rgw/rgw_sal_dbstore.cc +++ b/src/rgw/rgw_sal_dbstore.cc @@ -1617,6 +1617,36 @@ namespace rgw::sal { return 0; } + int DBStore::load_account_user_by_name(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + std::string_view tenant, + std::string_view username, + std::unique_ptr* user) + { + return -ENOTSUP; + } + + int DBStore::count_account_users(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + uint32_t& count) + { + return -ENOTSUP; + } + + int DBStore::list_account_users(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + std::string_view tenant, + std::string_view path_prefix, + std::string_view marker, + uint32_t max_items, + UserList& listing) + { + return -ENOTSUP; + } + std::string DBStore::get_cluster_id(const DoutPrefixProvider* dpp, optional_yield y) { return "PLACEHOLDER"; // for instance unique identifier diff --git a/src/rgw/rgw_sal_dbstore.h b/src/rgw/rgw_sal_dbstore.h index 57a5cb18653b7..a278fd8c593b9 100644 --- a/src/rgw/rgw_sal_dbstore.h +++ b/src/rgw/rgw_sal_dbstore.h @@ -794,6 +794,26 @@ public: optional_yield y, std::string_view email, rgw_owner& owner) override; + + int load_account_user_by_name(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + std::string_view tenant, + std::string_view username, + std::unique_ptr* user) override; + int count_account_users(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + uint32_t& count) override; + int list_account_users(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + std::string_view tenant, + std::string_view path_prefix, + std::string_view marker, + uint32_t max_items, + UserList& listing) override; + virtual std::unique_ptr get_object(const rgw_obj_key& k) override; virtual std::string get_cluster_id(const DoutPrefixProvider* dpp, optional_yield y); std::unique_ptr get_bucket(const RGWBucketInfo& i) override; diff --git a/src/rgw/rgw_sal_filter.cc b/src/rgw/rgw_sal_filter.cc index 6a30e7e890fa3..eca1529b2beb1 100644 --- a/src/rgw/rgw_sal_filter.cc +++ b/src/rgw/rgw_sal_filter.cc @@ -243,6 +243,43 @@ int FilterDriver::load_owner_by_email(const DoutPrefixProvider* dpp, return next->load_owner_by_email(dpp, y, email, owner); } +int FilterDriver::load_account_user_by_name(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + std::string_view tenant, + std::string_view username, + std::unique_ptr* user) +{ + std::unique_ptr nu; + int ret = next->load_account_user_by_name(dpp, y, account_id, tenant, + username, &nu); + if (ret >= 0) { + *user = std::make_unique(std::move(nu)); + } + return ret; +} + +int FilterDriver::count_account_users(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + uint32_t& count) +{ + return next->count_account_users(dpp, y, account_id, count); +} + +int FilterDriver::list_account_users(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + std::string_view tenant, + std::string_view path_prefix, + std::string_view marker, + uint32_t max_items, + UserList& listing) +{ + return next->list_account_users(dpp, y, account_id, tenant, path_prefix, + marker, max_items, listing); +} + std::unique_ptr FilterDriver::get_object(const rgw_obj_key& k) { std::unique_ptr o = next->get_object(k); diff --git a/src/rgw/rgw_sal_filter.h b/src/rgw/rgw_sal_filter.h index 7863834fd32bf..09dbe8efb0cfa 100644 --- a/src/rgw/rgw_sal_filter.h +++ b/src/rgw/rgw_sal_filter.h @@ -206,6 +206,25 @@ public: optional_yield y, std::string_view email, rgw_owner& owner) override; + int load_account_user_by_name(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + std::string_view tenant, + std::string_view username, + std::unique_ptr* user) override; + int count_account_users(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + uint32_t& count) override; + int list_account_users(const DoutPrefixProvider* dpp, + optional_yield y, + std::string_view account_id, + std::string_view tenant, + std::string_view path_prefix, + std::string_view marker, + uint32_t max_items, + UserList& listing) override; + virtual std::unique_ptr get_object(const rgw_obj_key& k) override; std::unique_ptr get_bucket(const RGWBucketInfo& i) override; int load_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b, diff --git a/src/rgw/rgw_sal_fwd.h b/src/rgw/rgw_sal_fwd.h index 123d17a5162a0..1ba59dc821f43 100644 --- a/src/rgw/rgw_sal_fwd.h +++ b/src/rgw/rgw_sal_fwd.h @@ -33,8 +33,9 @@ namespace sal { class Driver; class User; + struct UserList; class Bucket; - class BucketList; + struct BucketList; class Object; class MultipartUpload; class Lifecycle; -- 2.39.5