]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/iam: add iam user metadata (path, create_date, tags)
authorCasey Bodley <cbodley@redhat.com>
Sun, 17 Dec 2023 20:03:53 +0000 (15:03 -0500)
committerCasey Bodley <cbodley@redhat.com>
Fri, 12 Apr 2024 19:34:27 +0000 (15:34 -0400)
Signed-off-by: Casey Bodley <cbodley@redhat.com>
(cherry picked from commit de9feeb32ca71c67b29e753c3164cd778c08c280)

src/rgw/driver/rados/rgw_rest_user.cc
src/rgw/driver/rados/rgw_user.cc
src/rgw/driver/rados/rgw_user.h
src/rgw/rgw_admin.cc
src/rgw/rgw_common.cc
src/rgw/rgw_common.h
src/rgw/rgw_xml.cc
src/rgw/rgw_xml.h

index 9f3ae2d03aa76fc049ea5b4c8a6b569326a3e643..34112c9472792e6cf392b49a71dc377eda088c9b 100644 (file)
@@ -22,6 +22,7 @@ using namespace std;
 
 int fetch_access_keys_from_master(const DoutPrefixProvider* dpp, req_state* s,
                                   std::map<std::string, RGWAccessKey>& keys,
+                                  ceph::real_time& create_date,
                                   optional_yield y)
 {
   bufferlist data;
@@ -36,6 +37,7 @@ int fetch_access_keys_from_master(const DoutPrefixProvider* dpp, req_state* s,
   RGWUserInfo ui;
   ui.decode_json(&jp);
   keys = std::move(ui.access_keys);
+  create_date = ui.create_date;
   return 0;
 }
 
@@ -188,6 +190,7 @@ void RGWOp_User_Create::execute(optional_yield y)
   RESTArgs::get_string(s, "default-placement", default_placement_str, &default_placement_str);
   RESTArgs::get_string(s, "placement-tags", placement_tags_str, &placement_tags_str);
   RESTArgs::get_string(s, "account-id", "", &op_state.account_id);
+  RESTArgs::get_string(s, "path", "", &op_state.path);
 
   if (!s->user->get_info().system && system) {
     ldpp_dout(this, 0) << "cannot set system flag by non-system user" << dendl;
@@ -264,7 +267,9 @@ void RGWOp_User_Create::execute(optional_yield y)
   }
 
   if (!s->penv.site->is_meta_master()) {
-    op_ret = fetch_access_keys_from_master(this, s, op_state.op_access_keys, y);
+    op_state.create_date.emplace();
+    op_ret = fetch_access_keys_from_master(this, s, op_state.op_access_keys,
+                                           *op_state.create_date, y);
     if (op_ret < 0) {
       return;
     }
@@ -333,6 +338,7 @@ void RGWOp_User_Modify::execute(optional_yield y)
   RESTArgs::get_string(s, "default-placement", default_placement_str, &default_placement_str);
   RESTArgs::get_string(s, "placement-tags", placement_tags_str, &placement_tags_str);
   RESTArgs::get_string(s, "account-id", "", &op_state.account_id);
+  RESTArgs::get_string(s, "path", "", &op_state.path);
 
   if (!s->user->get_info().system && system) {
     ldpp_dout(this, 0) << "cannot set system flag by non-system user" << dendl;
@@ -414,7 +420,9 @@ void RGWOp_User_Modify::execute(optional_yield y)
   }
   
   if (!s->penv.site->is_meta_master()) {
-    op_ret = fetch_access_keys_from_master(this, s, op_state.op_access_keys, y);
+    op_state.create_date.emplace();
+    op_ret = fetch_access_keys_from_master(this, s, op_state.op_access_keys,
+                                           *op_state.create_date, y);
     if (op_ret < 0) {
       return;
     }
index e27cd81fb9d0bac7e6053207f83f3a2e6fda4a5a..348d876bfe2a41ff77529019a49cdb2c175d5390 100644 (file)
@@ -1784,6 +1784,18 @@ int RGWUser::execute_add(const DoutPrefixProvider *dpp, RGWUserAdminOpState& op_
     user_info.type = TYPE_ROOT;
   }
 
+  if (!op_state.path.empty()) {
+    user_info.path = op_state.path;
+  } else {
+    user_info.path = "/";
+  }
+
+  if (op_state.create_date) {
+    user_info.create_date = *op_state.create_date;
+  } else {
+    user_info.create_date = ceph::real_clock::now();
+  }
+
   // update the request
   op_state.set_user_info(user_info);
   op_state.set_populated();
@@ -2106,6 +2118,14 @@ int RGWUser::execute_modify(const DoutPrefixProvider *dpp, RGWUserAdminOpState&
     user_info.type = op_state.account_root ? TYPE_ROOT : TYPE_RGW;
   }
 
+  if (!op_state.path.empty()) {
+    user_info.path = op_state.path;
+  }
+
+  if (op_state.create_date) {
+    user_info.create_date = *op_state.create_date;
+  }
+
   op_state.set_user_info(user_info);
 
   // if we're supposed to modify keys, do so
index 463857899db5fe10be819383d604668569bc303c..c8c3c6dade5a2f5022d92cba88a6f14e219682cf 100644 (file)
@@ -124,6 +124,8 @@ struct RGWUserAdminOpState {
   uint32_t op_mask{0};
   std::map<int, std::string> temp_url_keys;
   std::string account_id;
+  std::string path;
+  std::optional<ceph::real_time> create_date;
 
   // subuser attributes
   std::string subuser;
index 76d360c33d7f0cbdbacdf6affe60a862f464bf2e..0fcc79bed980409ca221e51df42acecc2943e778 100644 (file)
@@ -6550,6 +6550,7 @@ int main(int argc, const char **argv)
   if (!tags.empty()) {
     user_op.set_placement_tags(tags);
   }
+  user_op.path = path;
 
   user_op.account_id = account_id;
   bucket_op.account_id = account_id;
index 5de470d9281f9aedde0d9a180c6a0f547cf72f4c..752bdb1bb96d455dfde90d225e2cad55fa159aed 100644 (file)
@@ -2592,6 +2592,10 @@ void RGWUserInfo::generate_test_instances(list<RGWUserInfo*>& o)
   i->user_id = "user_id";
   i->display_name =  "display_name";
   i->user_email = "user@email";
+  i->account_id = "RGW12345678901234567";
+  i->path = "/";
+  i->create_date = ceph::real_time{std::chrono::hours(1)};
+  i->tags.emplace("key", "value");
   RGWAccessKey k1, k2;
   k1.id = "id1";
   k1.key = "key1";
@@ -2825,6 +2829,9 @@ void RGWUserInfo::dump(Formatter *f) const
   encode_json("type", user_source_type, f);
   encode_json("mfa_ids", mfa_ids, f);
   encode_json("account_id", account_id, f);
+  encode_json("path", path, f);
+  encode_json("create_date", create_date, f);
+  encode_json("tags", tags, f);
 }
 
 void RGWUserInfo::decode_json(JSONObj *obj)
@@ -2879,6 +2886,9 @@ void RGWUserInfo::decode_json(JSONObj *obj)
   }
   JSONDecoder::decode_json("mfa_ids", mfa_ids, obj);
   JSONDecoder::decode_json("account_id", account_id, obj);
+  JSONDecoder::decode_json("path", path, obj);
+  JSONDecoder::decode_json("create_date", create_date, obj);
+  JSONDecoder::decode_json("tags", tags, obj);
 }
 
 
index 61005bf4f2bff4b9154050efdb088a5dab5c4c4c..35d097ef1c0d9ccca24c1d8e4c0e610fd67ce809 100644 (file)
@@ -583,6 +583,9 @@ struct RGWUserInfo
   uint32_t type;
   std::set<std::string> mfa_ids;
   rgw_account_id account_id;
+  std::string path = "/";
+  ceph::real_time create_date;
+  std::multimap<std::string, std::string> tags;
 
   RGWUserInfo()
     : suspended(0),
@@ -651,6 +654,9 @@ struct RGWUserInfo
      }
      encode(user_id.ns, bl);
      encode(account_id, bl);
+     encode(path, bl);
+     encode(create_date, bl);
+     encode(tags, bl);
      ENCODE_FINISH(bl);
   }
   void decode(bufferlist::const_iterator& bl) {
@@ -743,6 +749,11 @@ struct RGWUserInfo
     }
     if (struct_v >= 23) {
       decode(account_id, bl);
+      decode(path, bl);
+      decode(create_date, bl);
+      decode(tags, bl);
+    } else {
+      path = "/";
     }
     DECODE_FINISH(bl);
   }
index 1bcbcdad2457b491412a6212801e46830725b2e3..3ce031c2faaaf1ce43f390895be91c76cbb44365 100644 (file)
@@ -431,6 +431,20 @@ void decode_xml_obj(utime_t& val, XMLObj *obj)
   }
 }
 
+void decode_xml_obj(ceph::real_time& val, XMLObj *obj)
+{
+  const std::string s = obj->get_data();
+  uint64_t epoch;
+  uint64_t nsec;
+  int r = utime_t::parse_date(s, &epoch, &nsec);
+  if (r == 0) {
+    using namespace std::chrono;
+    val = real_time{seconds(epoch) + nanoseconds(nsec)};
+  } else {
+    throw RGWXMLDecoder::err("failed to decode real_time");
+  }
+}
+
 void encode_xml(const char *name, const string& val, Formatter *f)
 {
   f->dump_string(name, val);
index 5d3e727895232f8f28261bae26d120f76420689f..8e2a281b6498074e3f150f41cee305573e0c5751 100644 (file)
@@ -9,6 +9,7 @@
 #include <iosfwd>
 #include <include/types.h>
 #include <common/Formatter.h>
+#include "common/ceph_time.h"
 
 class XMLObj;
 class RGWXMLParser;
@@ -190,6 +191,7 @@ void decode_xml_obj(bool& val, XMLObj *obj);
 void decode_xml_obj(bufferlist& val, XMLObj *obj);
 class utime_t;
 void decode_xml_obj(utime_t& val, XMLObj *obj);
+void decode_xml_obj(ceph::real_time& val, XMLObj *obj);
 
 template<class T>
 void decode_xml_obj(std::optional<T>& val, XMLObj *obj)