radosgw-admin role-policy delete --role-name=S3Access1 --policy-name=Policy1
+Update a role
+-------------
+
+To update a role's max-session-duration, execute the following::
+
+ radosgw-admin role update --role-name={role-name} --max-session-duration={max-session-duration}
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``role-name``
+
+:Description: Name of the role.
+:Type: String
+
+``max-session-duration``
+
+:Description: Maximum session duration for a role.
+:Type: String
+
+For example::
+
+ radosgw-admin role update --role-name=S3Access1 --max-session-duration=43200
+
+Note: This command currently can only be used to update max-session-duration.
+
REST APIs for Manipulating a Role
=================================
</ResponseMetadata>
</UntagRoleResponse>
+Update Role
+-----------
+
+Example::
+ POST "<hostname>?Action=UpdateRole&RoleName=S3Access&MaxSessionDuration=43200"
+
+.. code-block:: XML
+
+ <UpdateRoleResponse>
+ <UpdateRoleResult>
+ <ResponseMetadata>
+ <RequestId>tx000000000000000000007-00611f337e-1027-default</RequestId>
+ </ResponseMetadata>
+ </UpdateRoleResult>
+ </UpdateRoleResponse>
+
+Note: This API currently can only be used to update max-session-duration.
Sample code for tagging, listing tags and untagging a role
----------------------------------------------------------
cout << " role-policy list list policies attached to a role\n";
cout << " role-policy get get the specified inline policy document embedded with the given role\n";
cout << " role-policy delete remove policy attached to a role\n";
+ cout << " role update update max_session_duration of a role\n";
cout << " reshard add schedule a resharding of a bucket\n";
cout << " reshard list list all bucket resharding or scheduled to be resharded\n";
cout << " reshard status read bucket resharding status\n";
ROLE_POLICY_LIST,
ROLE_POLICY_GET,
ROLE_POLICY_DELETE,
+ ROLE_UPDATE,
RESHARD_ADD,
RESHARD_LIST,
RESHARD_STATUS,
{ "role-policy get", OPT::ROLE_POLICY_GET },
{ "role policy delete", OPT::ROLE_POLICY_DELETE },
{ "role-policy delete", OPT::ROLE_POLICY_DELETE },
+ { "role update", OPT::ROLE_UPDATE },
{ "reshard bucket", OPT::BUCKET_RESHARD },
{ "reshard add", OPT::RESHARD_ADD },
{ "reshard list", OPT::RESHARD_LIST },
std::string zonegroup_name, zonegroup_id, zonegroup_new_name;
std::optional<string> opt_zonegroup_name, opt_zonegroup_id;
std::string api_name;
- std::string role_name, path, assume_role_doc, policy_name, perm_policy_doc, path_prefix;
+ std::string role_name, path, assume_role_doc, policy_name, perm_policy_doc, path_prefix, max_session_duration;
std::string redirect_zone;
bool redirect_zone_set = false;
list<string> endpoints;
perm_policy_doc = val;
} else if (ceph_argparse_witharg(args, i, &val, "--path-prefix", (char*)NULL)) {
path_prefix = val;
+ } else if (ceph_argparse_witharg(args, i, &val, "--max-session-duration", (char*)NULL)) {
+ max_session_duration = val;
} else if (ceph_argparse_witharg(args, i, &val, "--totp-serial", (char*)NULL)) {
totp_serial = val;
} else if (ceph_argparse_witharg(args, i, &val, "--totp-pin", (char*)NULL)) {
&& opt_cmd != OPT::ROLE_POLICY_LIST
&& opt_cmd != OPT::ROLE_POLICY_GET
&& opt_cmd != OPT::ROLE_POLICY_DELETE
+ && opt_cmd != OPT::ROLE_UPDATE
&& opt_cmd != OPT::RESHARD_ADD
&& opt_cmd != OPT::RESHARD_CANCEL
&& opt_cmd != OPT::RESHARD_STATUS) {
<< role_name << std::endl;
return 0;
}
+ case OPT::ROLE_UPDATE:
+ {
+ if (role_name.empty()) {
+ cerr << "ERROR: role name is empty" << std::endl;
+ return -EINVAL;
+ }
+
+ std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name, tenant);
+ ret = role->get(dpp(), null_yield);
+ if (ret < 0) {
+ return -ret;
+ }
+ if (!role->validate_max_session_duration(dpp())) {
+ ret = -EINVAL;
+ return ret;
+ }
+ role->update_max_session_duration(max_session_duration);
+ ret = role->update(dpp(), null_yield);
+ if (ret < 0) {
+ return -ret;
+ }
+ cout << "Max session duration updated successfully for role: " << role_name << std::endl;
+ return 0;
+ }
default:
output_user_info = false;
}
op_type == RGW_OP_PUBSUB_TOPIC_DELETE ||
op_type == RGW_OP_TAG_ROLE ||
op_type == RGW_OP_LIST_ROLE_TAGS ||
- op_type == RGW_OP_UNTAG_ROLE) {
+ op_type == RGW_OP_UNTAG_ROLE ||
+ op_type == RGW_OP_UPDATE_ROLE) {
return true;
}
return false;
{ "iam:TagRole", iamTagRole},
{ "iam:ListRoleTags", iamListRoleTags},
{ "iam:UntagRole", iamUntagRole},
+ { "iam:UpdateRole", iamUpdateRole},
{ "sts:AssumeRole", stsAssumeRole},
{ "sts:AssumeRoleWithWebIdentity", stsAssumeRoleWithWebIdentity},
{ "sts:GetSessionToken", stsGetSessionToken},
case iamUntagRole:
return "iam:UntagRole";
+ case iamUpdateRole:
+ return "iam:UpdateRole";
+
case stsAssumeRole:
return "sts:AssumeRole";
static constexpr std::uint64_t iamTagRole = s3All + 18;
static constexpr std::uint64_t iamListRoleTags = s3All + 19;
static constexpr std::uint64_t iamUntagRole = s3All + 20;
-static constexpr std::uint64_t iamAll = s3All + 21;
+static constexpr std::uint64_t iamUpdateRole = s3All + 21;
+static constexpr std::uint64_t iamAll = s3All + 22;
static constexpr std::uint64_t stsAssumeRole = iamAll + 1;
static constexpr std::uint64_t stsAssumeRoleWithWebIdentity = iamAll + 2;
RGW_OP_TAG_ROLE,
RGW_OP_LIST_ROLE_TAGS,
RGW_OP_UNTAG_ROLE,
+ RGW_OP_UPDATE_ROLE,
RGW_OP_PUT_BUCKET_POLICY,
RGW_OP_GET_BUCKET_POLICY,
RGW_OP_DELETE_BUCKET_POLICY,
return new RGWListRoleTags;
if (action.compare("UntagRole") == 0)
return new RGWUntagRole(this->bl_post_body);
+ if (action.compare("UpdateRole") == 0)
+ return new RGWUpdateRole(this->bl_post_body);
}
return nullptr;
s->formatter->close_section();
s->formatter->close_section();
}
+}
+
+int RGWUpdateRole::get_params()
+{
+ role_name = s->info.args.get("RoleName");
+ max_session_duration = s->info.args.get("MaxSessionDuration");
+
+ if (role_name.empty()) {
+ ldpp_dout(this, 20) << "ERROR: Role name is empty"<< dendl;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void RGWUpdateRole::execute(optional_yield y)
+{
+ op_ret = get_params();
+ if (op_ret < 0) {
+ return;
+ }
+
+ if (!store->is_meta_master()) {
+ RGWXMLDecoder::XMLParser parser;
+ if (!parser.init()) {
+ ldpp_dout(this, 0) << "ERROR: failed to initialize xml parser" << dendl;
+ op_ret = -EINVAL;
+ return;
+ }
+
+ bufferlist data;
+ s->info.args.remove("RoleName");
+ s->info.args.remove("MaxSessionDuration");
+ s->info.args.remove("Action");
+ s->info.args.remove("Version");
+
+ RGWUserInfo info = s->user->get_info();
+ const auto& it = info.access_keys.begin();
+ RGWAccessKey key;
+ if (it != info.access_keys.end()) {
+ key.id = it->first;
+ RGWAccessKey cred = it->second;
+ key.key = cred.key;
+ }
+ op_ret = store->forward_iam_request_to_master(s, key, nullptr, bl_post_body, &parser, s->info, y);
+ if (op_ret < 0) {
+ ldpp_dout(this, 20) << "ERROR: forward_iam_request_to_master failed with error code: " << op_ret << dendl;
+ return;
+ }
+ }
+
+ if (!_role->validate_max_session_duration(this)) {
+ op_ret = -EINVAL;
+ return;
+ }
+
+ _role->update_max_session_duration(max_session_duration);
+ op_ret = _role->update(this, y);
+
+ s->formatter->open_object_section("UpdateRoleResponse");
+ s->formatter->open_object_section("UpdateRoleResult");
+ s->formatter->open_object_section("ResponseMetadata");
+ s->formatter->dump_string("RequestId", s->trans_id);
+ s->formatter->close_section();
+ s->formatter->close_section();
}
\ No newline at end of file
RGWOpType get_type() override { return RGW_OP_UNTAG_ROLE; }
uint64_t get_op() override { return rgw::IAM::iamUntagRole; }
};
+
+class RGWUpdateRole : public RGWRoleWrite {
+ bufferlist bl_post_body;
+public:
+ RGWUpdateRole(const bufferlist& bl_post_body) : bl_post_body(bl_post_body) {};
+ void execute(optional_yield y) override;
+ int get_params();
+ const char* name() const override { return "update_role"; }
+ RGWOpType get_type() override { return RGW_OP_UPDATE_ROLE; }
+ uint64_t get_op() override { return rgw::IAM::iamUpdateRole; }
+};
\ No newline at end of file
info.decode_json(obj);
}
+bool RGWRole::validate_max_session_duration(const DoutPrefixProvider* dpp)
+{
+ if (info.max_session_duration < SESSION_DURATION_MIN ||
+ info.max_session_duration > SESSION_DURATION_MAX) {
+ ldpp_dout(dpp, 0) << "ERROR: Invalid session duration, should be between 3600 and 43200 seconds " << dendl;
+ return false;
+ }
+ return true;
+}
+
bool RGWRole::validate_input(const DoutPrefixProvider* dpp)
{
if (info.name.length() > MAX_ROLE_NAME_LEN) {
return false;
}
- if (info.max_session_duration < SESSION_DURATION_MIN ||
- info.max_session_duration > SESSION_DURATION_MAX) {
- ldpp_dout(dpp, 0) << "ERROR: Invalid session duration, should be between 3600 and 43200 seconds " << dendl;
+ if (!validate_max_session_duration(dpp)) {
return false;
}
return true;
}
}
+void RGWRole::update_max_session_duration(const std::string& max_session_duration_str)
+{
+ if (max_session_duration_str.empty()) {
+ info.max_session_duration = SESSION_DURATION_MIN;
+ } else {
+ info.max_session_duration = std::stoull(max_session_duration_str);
+ }
+}
+
const string& RGWRole::get_names_oid_prefix()
{
return role_name_oid_prefix;
virtual int read_id(const DoutPrefixProvider *dpp, const std::string& role_name, const std::string& tenant, std::string& role_id, optional_yield y) = 0;
virtual int read_name(const DoutPrefixProvider *dpp, optional_yield y) = 0;
virtual int read_info(const DoutPrefixProvider *dpp, optional_yield y) = 0;
+ bool validate_max_session_duration(const DoutPrefixProvider* dpp);
bool validate_input(const DoutPrefixProvider* dpp);
void extract_name_tenant(const std::string& str);
int set_tags(const DoutPrefixProvider* dpp, const std::multimap<std::string,std::string>& tags_map);
boost::optional<std::multimap<std::string,std::string>> get_tags();
void erase_tags(const std::vector<std::string>& tagKeys);
+ void update_max_session_duration(const std::string& max_session_duration_str);
void dump(Formatter *f) const;
void decode_json(JSONObj *obj);
role-policy list list policies attached to a role
role-policy get get the specified inline policy document embedded with the given role
role-policy delete remove policy attached to a role
+ role update update max_session_duration of a role
reshard add schedule a resharding of a bucket
reshard list list all bucket resharding or scheduled to be resharded
reshard status read bucket resharding status