]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: add list user admin OP API
authorsongshuangyang <songshuangyang@baidu.com>
Tue, 13 Nov 2018 09:32:41 +0000 (17:32 +0800)
committersongshuangyang <songshuangyang@baidu.com>
Mon, 19 Nov 2018 06:09:10 +0000 (14:09 +0800)
The radosgw-admin tool support the `user list` subcommand to list radosgw users, but there is no user listing function for the admin OP API. It needs to support this API.

Signed-off-by: Oshyn Song <dualyangsong@gmail.com>
src/rgw/rgw_common.cc
src/rgw/rgw_rest_user.cc
src/rgw/rgw_user.cc
src/rgw/rgw_user.h

index 6fdea97419b68ea840efd24658eaf6c3830e4d5b..626a392ccac987dec1a123b7f02b64a1ee98bdc9 100644 (file)
@@ -948,6 +948,7 @@ void RGWHTTPArgs::append(const string& name, const string& val)
               (name.compare("index") == 0) ||
               (name.compare("policy") == 0) ||
               (name.compare("quota") == 0) ||
+              (name.compare("list") == 0) ||
               (name.compare("object") == 0)) {
 
     if (!admin_subresource_added) {
index d8f4339d1a457ea4c30144c926d12dda68b7d1a4..3bf0d4d866d3569d443c1d4c576f5c1bb44ff09f 100644 (file)
 
 #define dout_subsys ceph_subsys_rgw
 
+class RGWOp_User_List : public RGWRESTOp {
+
+public:
+  RGWOp_User_List() {}
+
+  int check_caps(RGWUserCaps& caps) override {
+    return caps.check_cap("users", RGW_CAP_READ);
+  }
+
+  void execute() override;
+
+  const char* name() const override { return "list_user"; }
+};
+
+void RGWOp_User_List::execute()
+{
+  RGWUserAdminOpState op_state;
+
+  uint32_t max_entries;
+  std::string marker;
+  RESTArgs::get_uint32(s, "max-entries", 1000, &max_entries);
+  RESTArgs::get_string(s, "marker", marker, &marker);
+
+  op_state.max_entries = max_entries;
+  op_state.marker = marker;
+  http_ret = RGWUserAdminOp_User::list(store, op_state, flusher);
+}
+
 class RGWOp_User_Info : public RGWRESTOp {
 
 public:
@@ -923,6 +951,9 @@ RGWOp *RGWHandler_User::op_get()
   if (s->info.args.sub_resource_exists("quota"))
     return new RGWOp_Quota_Info;
 
+  if (s->info.args.sub_resource_exists("list"))
+    return new RGWOp_User_List;
+
   return new RGWOp_User_Info;
 }
 
index bf5b75a0fb4aaae1dc20458fc86276367b7043e0..657e6d65e71b9fe9edc1465ac2e3c4b0135c9d4e 100644 (file)
@@ -2322,6 +2322,77 @@ int RGWUser::info(RGWUserInfo& fetched_info, std::string *err_msg)
   return 0;
 }
 
+int RGWUser::list(RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher)
+{
+  Formatter *formatter = flusher.get_formatter();
+  void *handle = nullptr;
+  std::string metadata_key = "user";
+  if (op_state.max_entries > 1000) {
+    op_state.max_entries = 1000;
+  }
+
+  int ret = store->meta_mgr->list_keys_init(metadata_key, op_state.marker, &handle);
+  if (ret < 0) {
+    return ret;
+  }
+
+  bool truncated = false;
+  uint64_t count = 0;
+  uint64_t left = 0;
+  flusher.start(0);
+
+  // open the result object section
+  formatter->open_object_section("result");
+
+  // open the user id list array section
+  formatter->open_array_section("keys");
+  do {
+    std::list<std::string> keys;
+    left = op_state.max_entries - count;
+    ret = store->meta_mgr->list_keys_next(handle, left, keys, &truncated);
+    if (ret < 0 && ret != -ENOENT) {
+      return ret;
+    } if (ret != -ENOENT) {
+      for (std::list<std::string>::iterator iter = keys.begin(); iter != keys.end(); ++iter) {
+      formatter->dump_string("key", *iter);
+        ++count;
+      }
+    }
+  } while (truncated && left > 0);
+  // close user id list section
+  formatter->close_section();
+
+  formatter->dump_bool("truncated", truncated);
+  formatter->dump_int("count", count);
+  if (truncated) {
+    formatter->dump_string("marker", store->meta_mgr->get_marker(handle));
+  }
+
+  // close result object section
+  formatter->close_section();
+
+  store->meta_mgr->list_keys_complete(handle);
+
+  flusher.flush();
+  return 0;
+}
+
+int RGWUserAdminOp_User::list(RGWRados *store, RGWUserAdminOpState& op_state,
+                  RGWFormatterFlusher& flusher)
+{
+  RGWUser user;
+
+  int ret = user.init_storage(store);
+  if (ret < 0)
+    return ret;
+
+  ret = user.list(op_state, flusher);
+  if (ret < 0)
+    return ret;
+
+  return 0;
+}
+
 int RGWUserAdminOp_User::info(RGWRados *store, RGWUserAdminOpState& op_state,
                   RGWFormatterFlusher& flusher)
 {
index c7d90111181c9e4443c483fae5507f378c1cc8f9..3831f10a9ff10d94e8e4af0fa28231f87abed21e 100644 (file)
@@ -226,6 +226,10 @@ struct RGWUserAdminOpState {
   RGWQuotaInfo bucket_quota;
   RGWQuotaInfo user_quota;
 
+  // req parameters for listing user
+  std::string marker;
+  uint32_t max_entries;
+
   void set_access_key(const std::string& access_key) {
     if (access_key.empty())
       return;
@@ -534,6 +538,8 @@ struct RGWUserAdminOpState {
     found_by_email = false;
     found_by_key = false;
     mfa_ids_specified = false;
+    max_entries = 1000;
+    marker = "";
   }
 };
 
@@ -699,6 +705,9 @@ public:
   /* info from an already populated RGWUser */
   int info (RGWUserInfo& fetched_info, std::string *err_msg = NULL);
 
+  /* list the existing users */
+  int list(RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);
+
   friend class RGWAccessKeyPool;
   friend class RGWSubUserPool;
   friend class RGWUserCapPool;
@@ -709,6 +718,9 @@ public:
 class RGWUserAdminOp_User
 {
 public:
+  static int list(RGWRados *store,
+                  RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);
+
   static int info(RGWRados *store,
                   RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);