]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/iam: only RGWDeleteRole returns ERR_DELETE_CONFLICT
authorCasey Bodley <cbodley@redhat.com>
Sat, 17 Feb 2024 22:53:21 +0000 (17:53 -0500)
committerCasey Bodley <cbodley@redhat.com>
Wed, 10 Apr 2024 17:09:16 +0000 (13:09 -0400)
metadata sync calls RadosRole::delete_obj() after the role is deleted on
the metadata master zone. the role was verified to be empty there, so
metadata sync needs to delete the role anyway

only the iam DeleteRole api should require policies to be removed first

Signed-off-by: Casey Bodley <cbodley@redhat.com>
src/rgw/driver/rados/rgw_sal_rados.cc
src/rgw/rgw_rest_role.cc

index 92244196295c46bc17645e4ac5726ca8ead101cf..8171e25689fb68c4896bfb1ed876c83277ce237b 100644 (file)
@@ -4430,11 +4430,6 @@ int RadosRole::delete_obj(const DoutPrefixProvider *dpp, optional_yield y)
     return ret;
   }
 
-  if (!info.perm_policy_map.empty() ||
-      !info.managed_policies.arns.empty()) {
-    return -ERR_DELETE_CONFLICT;
-  }
-
   // Delete id & insert MD Log
   RGWSI_MBSObj_RemoveParams params;
   std::unique_ptr<RGWSI_MetaBackend::Context> ctx(store->svc()->role->svc.meta_be->alloc_ctx());
index 79c5c4bbac0007fe5a84df2ef459d5b6549c2c9e..893608d7acb30ad6bb76f48391354e57b54b6ee1 100644 (file)
@@ -352,11 +352,8 @@ int RGWDeleteRole::init_processing(optional_yield y)
 
 void RGWDeleteRole::execute(optional_yield y)
 {
-  bool is_master = true;
-
   const rgw::SiteConfig& site = *s->penv.site;
   if (!site.is_meta_master()) {
-    is_master = false;
     RGWXMLDecoder::XMLParser parser;
     if (!parser.init()) {
       ldpp_dout(this, 0) << "ERROR: failed to initialize xml parser" << dendl;
@@ -376,16 +373,28 @@ void RGWDeleteRole::execute(optional_yield y)
     }
   }
 
-  op_ret = role->delete_obj(s, y);
+  op_ret = retry_raced_role_write(this, y, role.get(),
+      [this, y, &site] {
+        if (site.is_meta_master()) {
+          // only check on the master zone. if a forwarded DeleteRole request
+          // succeeds on the master zone, it needs to succeed here too
+          const auto& info = role->get_info();
+          if (!info.perm_policy_map.empty() ||
+              !info.managed_policies.arns.empty()) {
+            s->err.message = "The role cannot be deleted until all role policies are removed";
+            return -ERR_DELETE_CONFLICT;
+          }
+        }
+        return role->delete_obj(s, y);
+      });
 
   if (op_ret == -ENOENT) {
     //Role has been deleted since metadata from master has synced up
-    if (!is_master) {
+    if (!site.is_meta_master()) {
       op_ret = 0;
     } else {
       op_ret = -ERR_NO_ROLE_FOUND;
     }
-    return;
   }
   if (!op_ret) {
     s->formatter->open_object_section("DeleteRoleResponse");
@@ -725,12 +734,16 @@ void RGWDeleteRolePolicy::execute(optional_yield y)
   }
 
   op_ret = retry_raced_role_write(this, y, role.get(),
-      [this, y] {
+      [this, y, &site] {
         int r = role->delete_policy(this, policy_name);
         if (r == -ENOENT) {
+          if (!site.is_meta_master()) {
+            return 0; // delete succeeded on the master
+          }
           s->err.message = "The requested PolicyName was not found";
           return -ERR_NO_SUCH_ENTITY;
-        } else if (r == 0) {
+        }
+        if (r == 0) {
           r = role->update(this, y);
         }
         return r;
@@ -1157,10 +1170,13 @@ void RGWDetachRolePolicy_IAM::execute(optional_yield y)
   }
 
   op_ret = retry_raced_role_write(this, y, role.get(),
-      [this, y] {
+      [this, y, &site] {
         auto &policies = role->get_info().managed_policies;
         auto p = policies.arns.find(policy_arn);
         if (p == policies.arns.end()) {
+          if (!site.is_meta_master()) {
+            return 0; // delete succeeded on the master
+          }
           s->err.message = "The requested PolicyArn is not attached to the role";
           return -ERR_NO_SUCH_ENTITY;
         }