From: yuliyang Date: Fri, 6 Dec 2019 01:47:03 +0000 (+0800) Subject: rgw: support specify user default placement and X-Git-Tag: v15.1.0~41^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=bdabd3d04283c84ba40765530a46d83c13848d47;p=ceph.git rgw: support specify user default placement and placement_tags when create or modify user fix https://tracker.ceph.com/issues/43164 Signed-off-by: yuliyang --- diff --git a/doc/radosgw/placement.rst b/doc/radosgw/placement.rst index 208ecad979c..56b8fc6850c 100644 --- a/doc/radosgw/placement.rst +++ b/doc/radosgw/placement.rst @@ -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.json - $ vi user.json - $ radosgw-admin metadata put user: < user.json + $ radosgw-admin user modify \ + --uid \ + --placement-id \ + --storage-class \ + --tags .. _s3_bucket_placement: diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 7cb99a0544d..2443f115c62 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -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; diff --git a/src/rgw/rgw_rest_user.cc b/src/rgw/rgw_rest_user.cc index c768789934d..b8414812fed 100644 --- a/src/rgw/rgw_rest_user.cc +++ b/src/rgw/rgw_rest_user.cc @@ -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 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 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; diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index 6876d2320c5..793ccc170ad 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -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 diff --git a/src/rgw/rgw_user.h b/src/rgw/rgw_user.h index 489408a4e13..3e84230434c 100644 --- a/src/rgw/rgw_user.h +++ b/src/rgw/rgw_user.h @@ -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 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& _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 = ""; }