]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/admin: user list accepts --account-id or -name
authorCasey Bodley <cbodley@redhat.com>
Wed, 6 Mar 2024 22:13:48 +0000 (17:13 -0500)
committerCasey Bodley <cbodley@redhat.com>
Wed, 10 Apr 2024 17:09:17 +0000 (13:09 -0400)
Signed-off-by: Casey Bodley <cbodley@redhat.com>
src/rgw/rgw_account.cc
src/rgw/rgw_account.h
src/rgw/rgw_admin.cc

index 8afd42191f50af674cb3b379b5e1dd1b41fa581f..44aa9a3d4c7afde37b69df8e959876249645f3b6 100644 (file)
@@ -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<int32_t>::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
index fca52a73b183387e046777aced63042d4672089c..f942d674b0ec5fa8fb8c11085f6e3af2a8cd0639 100644 (file)
@@ -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
index 374a67f314f96d6aef751810f7832c1e7d0ab9e5..49335c4e817f3632b9cc74f213aa359bf41fff07 100644 (file)
@@ -9248,6 +9248,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";
     }