From be23f5b2dd88c7d2bc2525825e30294f13f6585d Mon Sep 17 00:00:00 2001 From: Ali Maredia Date: Tue, 29 Nov 2022 17:31:25 -0500 Subject: [PATCH] rgw: set keys from from master zone on admin api user modify When users were being modified via the admin_api to generate keys on a secondary zone, the keys returned in the json output are not correct. This commit ensures the proper keys are set to be returned to the user via the json output. fixes: https://tracker.ceph.com/issues/57724 Signed-off-by: Ali Maredia --- src/rgw/rgw_rest_user.cc | 54 ++++++++++++++++++++++++++-------------- src/rgw/rgw_user.cc | 6 +++++ src/rgw/rgw_user.h | 2 ++ 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/rgw/rgw_rest_user.cc b/src/rgw/rgw_rest_user.cc index 4ffe508f18be..7962131729ae 100644 --- a/src/rgw/rgw_rest_user.cc +++ b/src/rgw/rgw_rest_user.cc @@ -19,6 +19,21 @@ using namespace std; +int fetch_access_keys_from_master(const DoutPrefixProvider *dpp, rgw::sal::Store* store, RGWUserAdminOpState &op_state, req_state *s, optional_yield y) { + bufferlist data; + JSONParser jp; + RGWUserInfo ui; + int op_ret = store->forward_request_to_master(s, s->user.get(), nullptr, data, &jp, s->info, y); + if (op_ret < 0) { + ldpp_dout(dpp, 0) << "forward_request_to_master returned ret=" << op_ret << dendl; + return op_ret; + } + ui.decode_json(&jp); + op_state.op_access_keys = std::move(ui.access_keys); + + return 0; +} + class RGWOp_User_List : public RGWRESTOp { public: @@ -224,20 +239,14 @@ void RGWOp_User_Create::execute(optional_yield y) } if(!(store->is_meta_master())) { - bufferlist data; - JSONParser jp; - RGWUserInfo ui; - op_ret = store->forward_request_to_master(s, s->user.get(), nullptr, data, &jp, s->info, y); - if (op_ret < 0) { - ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl; + op_ret = fetch_access_keys_from_master(this, store, op_state, s, y); + + if(op_ret < 0) { return; + } else { + // set_generate_key() is not set if keys have already been fetched from master zone + gen_key = false; } - ui.decode_json(&jp); - std::map keys = ui.access_keys; - auto keys_itr = keys.begin(); - RGWAccessKey first_key = keys_itr->second; - op_state.id = first_key.id; - op_state.key = first_key.key; } if (gen_key) { @@ -320,8 +329,6 @@ void RGWOp_User_Modify::execute(optional_yield y) } op_state.set_max_buckets(max_buckets); } - if (gen_key) - op_state.set_generate_key(); if (!key_type_str.empty()) { int32_t key_type = KEY_TYPE_UNDEFINED; @@ -377,12 +384,21 @@ void RGWOp_User_Modify::execute(optional_yield y) op_state.set_placement_tags(placement_tags_list); } - bufferlist data; - op_ret = store->forward_request_to_master(s, s->user.get(), nullptr, data, nullptr, s->info, y); - if (op_ret < 0) { - ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl; - return; + if(!(store->is_meta_master())) { + op_ret = fetch_access_keys_from_master(this, store, op_state, s, y); + + if(op_ret < 0) { + return; + } else { + // set_generate_key() is not set if keys have already been fetched from master zone + gen_key = false; + } + } + + if (gen_key) { + op_state.set_generate_key(); } + op_ret = RGWUserAdminOp_User::modify(s, store, op_state, flusher, y); } diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index 28eaed66bd02..ab814e07f3a4 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -1551,6 +1551,12 @@ int RGWUser::update(const DoutPrefixProvider *dpp, RGWUserAdminOpState& op_state return -EINVAL; } + // if op_state.op_access_keys is not empty most recent keys have been fetched from master zone + if(!op_state.op_access_keys.empty()) { + auto user_access_keys = op_state.get_access_keys(); + *(user_access_keys) = op_state.op_access_keys; + } + RGWUserInfo *pold_info = (is_populated() ? &old_info : nullptr); ret = user->store_user(dpp, y, false, pold_info); diff --git a/src/rgw/rgw_user.h b/src/rgw/rgw_user.h index 68bbcb552042..115fe4db3f47 100644 --- a/src/rgw/rgw_user.h +++ b/src/rgw/rgw_user.h @@ -128,6 +128,8 @@ struct RGWUserAdminOpState { // key_attributes std::string id; // access key std::string key; // secret key + // access keys fetched for a user in the middle of an op + std::map op_access_keys; int32_t key_type{-1}; bool access_key_exist = false; -- 2.47.3