]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: support specify user default placement and 31185/head
authoryuliyang <yuliyang@cmss.chinamobile.com>
Fri, 6 Dec 2019 01:47:03 +0000 (09:47 +0800)
committeryuliyang <yuliyang@cmss.chinamobile.com>
Fri, 6 Dec 2019 01:47:03 +0000 (09:47 +0800)
 placement_tags when create or modify user

fix https://tracker.ceph.com/issues/43164

Signed-off-by: yuliyang <yuliyang@cmss.chinamobile.com>
doc/radosgw/placement.rst
src/rgw/rgw_admin.cc
src/rgw/rgw_rest_user.cc
src/rgw/rgw_user.cc
src/rgw/rgw_user.h

index 208ecad979c8e8c5b3e9c1dfadd80f085d67b266..56b8fc6850c2f1469f2cd41c37c8deb141379173 100644 (file)
@@ -186,14 +186,15 @@ to create buckets with that placement target unless their user info contains
 at least one matching tag in its ``placement_tags`` field. This can be useful
 to restrict access to certain types of storage.
 
-The ``radosgw-admin`` command cannot modify these fields directly, so the json
-format must be edited manually:
+The ``radosgw-admin`` command can modify these fields directly with:
 
 ::
 
-  $ radosgw-admin metadata get user:<user-id> > user.json
-  $ vi user.json
-  $ radosgw-admin metadata put user:<user-id> < user.json
+  $ radosgw-admin user modify \
+        --uid <user-id> \
+        --placement-id <default-placement-id> \
+        --storage-class <default-storage-class> \
+        --tags <tag1,tag2>
 
 .. _s3_bucket_placement:
 
index 7cb99a0544de945dc1b2157dbbe768e034d8d911..2443f115c6252f3cfa4f8130eb9c222a39e96c49 100644 (file)
@@ -4979,6 +4979,21 @@ int main(int argc, const char **argv)
   else if (opt_cmd == OPT_USER_SUSPEND)
     user_op.set_suspension(true);
 
+  if (!placement_id.empty() || !storage_class.empty()) {
+    rgw_placement_rule target_rule;
+    target_rule.name = placement_id;
+    target_rule.storage_class = storage_class;
+    if (!store->svc()->zone->get_zone_params().valid_placement(target_rule)) {
+      cerr << "NOTICE: invalid dest placement: " << target_rule.to_str() << std::endl;
+      return EINVAL;
+    }
+    user_op.set_default_placement(target_rule);
+  }
+
+  if (!tags.empty()) {
+    user_op.set_placement_tags(tags);
+  }
+
   // RGWUser to use for user operations
   RGWUser user;
   int ret = 0;
index c768789934d7843605dd5db3b3ba23941cb82a2b..b8414812fedc073a9dd64fdf6bb69280d6fbcc5c 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "services/svc_zone.h"
 #include "services/svc_sys_obj.h"
+#include "rgw_zone.h"
 
 #define dout_subsys ceph_subsys_rgw
 
@@ -115,6 +116,8 @@ void RGWOp_User_Create::execute()
   std::string caps;
   std::string tenant_name;
   std::string op_mask_str;
+  std::string default_placement_str;
+  std::string placement_tags_str;
 
   bool gen_key;
   bool suspended;
@@ -142,6 +145,8 @@ void RGWOp_User_Create::execute()
   RESTArgs::get_bool(s, "system", false, &system);
   RESTArgs::get_bool(s, "exclusive", false, &exclusive);
   RESTArgs::get_string(s, "op-mask", op_mask_str, &op_mask_str);
+  RESTArgs::get_string(s, "default-placement", default_placement_str, &default_placement_str);
+  RESTArgs::get_string(s, "placement-tags", placement_tags_str, &placement_tags_str);
 
   if (!s->user->system && system) {
     ldout(s->cct, 0) << "cannot set system flag by non-system user" << dendl;
@@ -197,6 +202,23 @@ void RGWOp_User_Create::execute()
   if (gen_key)
     op_state.set_generate_key();
 
+  if (!default_placement_str.empty()) {
+    rgw_placement_rule target_rule;
+    target_rule.from_str(default_placement_str);
+    if (!store->svc()->zone->get_zone_params().valid_placement(target_rule)) {
+      ldout(s->cct, 0) << "NOTICE: invalid dest placement: " << target_rule.to_str() << dendl;
+      http_ret = -EINVAL;
+      return;
+    }
+    op_state.set_default_placement(target_rule);
+  }
+
+  if (!placement_tags_str.empty()) {
+    list<string> placement_tags_list;
+    get_str_list(placement_tags_str, ",", placement_tags_list);
+    op_state.set_placement_tags(placement_tags_list);
+  }
+
   if (!store->svc()->zone->is_meta_master()) {
     bufferlist data;
     op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
@@ -232,6 +254,8 @@ void RGWOp_User_Modify::execute()
   std::string key_type_str;
   std::string caps;
   std::string op_mask_str;
+  std::string default_placement_str;
+  std::string placement_tags_str;
 
   bool gen_key;
   bool suspended;
@@ -257,6 +281,8 @@ void RGWOp_User_Modify::execute()
 
   RESTArgs::get_bool(s, "system", false, &system);
   RESTArgs::get_string(s, "op-mask", op_mask_str, &op_mask_str);
+  RESTArgs::get_string(s, "default-placement", default_placement_str, &default_placement_str);
+  RESTArgs::get_string(s, "placement-tags", placement_tags_str, &placement_tags_str);
 
   if (!s->user->system && system) {
     ldout(s->cct, 0) << "cannot set system flag by non-system user" << dendl;
@@ -316,6 +342,23 @@ void RGWOp_User_Modify::execute()
     }
     op_state.set_op_mask(op_mask);
   }
+
+  if (!default_placement_str.empty()) {
+    rgw_placement_rule target_rule;
+    target_rule.from_str(default_placement_str);
+    if (!store->svc()->zone->get_zone_params().valid_placement(target_rule)) {
+      ldout(s->cct, 0) << "NOTICE: invalid dest placement: " << target_rule.to_str() << dendl;
+      http_ret = -EINVAL;
+      return;
+    }
+    op_state.set_default_placement(target_rule);
+  }
+
+  if (!placement_tags_str.empty()) {
+    list<string> placement_tags_list;
+    get_str_list(placement_tags_str, ",", placement_tags_list);
+    op_state.set_placement_tags(placement_tags_list);
+  }
   
   if (!store->svc()->zone->is_meta_master()) {
     bufferlist data;
index 6876d2320c54a5acb8848cfb8b56b9e55645f3a8..793ccc170ad305edcb0ba7f9e900544e6df1bb07 100644 (file)
@@ -1796,6 +1796,14 @@ int RGWUser::execute_add(RGWUserAdminOpState& op_state, std::string *err_msg)
     rgw_apply_default_user_quota(user_info.user_quota, cct->_conf);
   }
 
+  if (op_state.default_placement_specified) {
+    user_info.default_placement = op_state.default_placement;
+  }
+
+  if (op_state.placement_tags_specified) {
+    user_info.placement_tags = op_state.placement_tags;
+  }
+
   // update the request
   op_state.set_user_info(user_info);
   op_state.set_populated();
@@ -2076,6 +2084,15 @@ int RGWUser::execute_modify(RGWUserAdminOpState& op_state, std::string *err_msg)
   if (op_state.mfa_ids_specified) {
     user_info.mfa_ids = op_state.mfa_ids;
   }
+
+  if (op_state.default_placement_specified) {
+    user_info.default_placement = op_state.default_placement;
+  }
+
+  if (op_state.placement_tags_specified) {
+    user_info.placement_tags = op_state.placement_tags;
+  }
+
   op_state.set_user_info(user_info);
 
   // if we're supposed to modify keys, do so
index 489408a4e134d7852575305719ddd7360ee258fa..3e84230434c0cd70257f9eef63bb2244c6d597de 100644 (file)
@@ -220,6 +220,11 @@ struct RGWUserAdminOpState {
   // req parameters for listing user
   std::string marker;
   uint32_t max_entries;
+  rgw_placement_rule default_placement; // user default placement
+  bool default_placement_specified;
+
+  list<string> placement_tags;  // user default placement_tags
+  bool placement_tags_specified;
 
   void set_access_key(const std::string& access_key) {
     if (access_key.empty())
@@ -402,6 +407,16 @@ struct RGWUserAdminOpState {
     mfa_ids_specified = true;
   }
 
+  void set_default_placement(const rgw_placement_rule& _placement) {
+    default_placement = _placement;
+    default_placement_specified = true;
+  }
+
+  void set_placement_tags(const list<string>& _tags) {
+    placement_tags = _tags;
+    placement_tags_specified = true;
+  }
+
   bool is_populated() { return populated; }
   bool is_initialized() { return initialized; }
   bool has_existing_user() { return existing_user; }
@@ -541,6 +556,8 @@ struct RGWUserAdminOpState {
     found_by_email = false;
     found_by_key = false;
     mfa_ids_specified = false;
+    default_placement_specified = false;
+    placement_tags_specified = false;
     max_entries = 1000;
     marker = "";
   }