]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/sal: add interfaces for account users
authorCasey Bodley <cbodley@redhat.com>
Mon, 18 Dec 2023 02:20:02 +0000 (21:20 -0500)
committerCasey Bodley <cbodley@redhat.com>
Fri, 12 Apr 2024 19:34:27 +0000 (15:34 -0400)
Signed-off-by: Casey Bodley <cbodley@redhat.com>
(cherry picked from commit 8971465a35616cc9b848b7943abd167a59abdda1)

src/rgw/driver/rados/rgw_sal_rados.cc
src/rgw/driver/rados/rgw_sal_rados.h
src/rgw/rgw_sal.h
src/rgw/rgw_sal_dbstore.cc
src/rgw/rgw_sal_dbstore.h
src/rgw/rgw_sal_filter.cc
src/rgw/rgw_sal_filter.h
src/rgw/rgw_sal_fwd.h

index 45df165033cb0efa7bb857215194035adfda9865..5b3ddfefec7899bf802f94e943cb5fb37406c736 100644 (file)
@@ -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>* 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<User> 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<std::string> 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<Object> RadosStore::get_object(const rgw_obj_key& k)
 {
   return std::make_unique<RadosObject>(this, k);
index e429018e48761b9cf6c118db12936bbd0814c1b7..b152fadc3c8c63a427e285a74edf1147739f5a4d 100644 (file)
@@ -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>* 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<Object> get_object(const rgw_obj_key& k) override;
     std::unique_ptr<Bucket> get_bucket(const RGWBucketInfo& i) override;
     int load_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b,
index e05f321956bcc1a3f56f8d4a403cb62c615b5394..b775a48f4eed87d9c674633a1584ac0c34efb124 100644 (file)
@@ -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<RGWUserInfo> users;
+  /// The next marker to resume listing, or empty
+  std::string next_marker;
+};
+
 /** A list of key-value attributes */
   using Attrs = std::map<std::string, ceph::buffer::list>;
 
@@ -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>* 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. */
index 6aa9cfe15e9583b9c7aae24abb5739463d01ce06..972becb391aaadf6abac05c7f69f7bd9dff43683 100644 (file)
@@ -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>* 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
index 57a5cb18653b785736c1193880cd8ca7a622991f..a278fd8c593b980e0d5da2b773701c69d09c2788 100644 (file)
@@ -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>* 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<Object> get_object(const rgw_obj_key& k) override;
       virtual std::string get_cluster_id(const DoutPrefixProvider* dpp, optional_yield y);
       std::unique_ptr<Bucket> get_bucket(const RGWBucketInfo& i) override;
index 6a30e7e890fa3054ddcbe9262e992866eee95231..eca1529b2beb1f9e8a19e565e595df2026edccbd 100644 (file)
@@ -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>* user)
+{
+  std::unique_ptr<User> nu;
+  int ret = next->load_account_user_by_name(dpp, y, account_id, tenant,
+                                            username, &nu);
+  if (ret >= 0) {
+    *user = std::make_unique<FilterUser>(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<Object> FilterDriver::get_object(const rgw_obj_key& k)
 {
   std::unique_ptr<Object> o = next->get_object(k);
index 7863834fd32bf402f8794615b6206f1178ba8959..09dbe8efb0cfabc47002dbdc16e5059697b4aa52 100644 (file)
@@ -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>* 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<Object> get_object(const rgw_obj_key& k) override;
   std::unique_ptr<Bucket> get_bucket(const RGWBucketInfo& i) override;
   int load_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b,
index 123d17a5162a09f2d5de39e17c6be77d0f9a6b9d..1ba59dc821f4344a317e9c25d1b8e915f9937e52 100644 (file)
@@ -33,8 +33,9 @@ namespace sal {
 
   class Driver;
   class User;
+  struct UserList;
   class Bucket;
-  class BucketList;
+  struct BucketList;
   class Object;
   class MultipartUpload;
   class Lifecycle;