]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: edit replication policy 57930/head
authorNizamudeen A <nia@redhat.com>
Fri, 7 Jun 2024 13:22:19 +0000 (18:52 +0530)
committerNizamudeen A <nia@redhat.com>
Fri, 21 Jun 2024 11:16:23 +0000 (16:46 +0530)
Fixes: https://tracker.ceph.com/issues/66240
Signed-off-by: Nizamudeen A <nia@redhat.com>
src/pybind/mgr/dashboard/controllers/rgw.py
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-bucket.service.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-bucket.service.ts
src/pybind/mgr/dashboard/openapi.yaml

index a87ebf12494fea343b262801246378eb470488bb..785b6309fbf70e0db60c1af01fe45bf3fe880cbe 100644 (file)
@@ -401,16 +401,21 @@ class RgwBucket(RgwRESTController):
 
     def _set_replication(self, bucket_name: str, replication: bool, owner, daemon_name):
         multisite = RgwMultisite()
+        # return immediately if the multisite is not configured
+        if not multisite.get_multisite_status():
+            return None
+
         rgw_client = RgwClient.instance(owner, daemon_name)
         zonegroup_name = RgwClient.admin_instance(daemon_name=daemon_name).get_default_zonegroup()
 
         policy_exists = multisite.policy_group_exists(_SYNC_GROUP_ID, zonegroup_name)
         if replication and not policy_exists:
             multisite.create_dashboard_admin_sync_group(zonegroup_name=zonegroup_name)
+
         return rgw_client.set_bucket_replication(bucket_name, replication)
 
-    def _get_replication(self, bucket_name: str):
-        rgw_client = RgwClient.admin_instance()
+    def _get_replication(self, bucket_name: str, owner, daemon_name):
+        rgw_client = RgwClient.instance(owner, daemon_name)
         return rgw_client.get_bucket_replication(bucket_name)
 
     @staticmethod
@@ -467,7 +472,7 @@ class RgwBucket(RgwRESTController):
         result['mfa_delete'] = versioning['MfaDelete']
         result['bucket_policy'] = self._get_policy(bucket_name, daemon_name, result['owner'])
         result['acl'] = self._get_acl(bucket_name, daemon_name, result['owner'])
-        result['replication'] = self._get_replication(bucket_name)
+        result['replication'] = self._get_replication(bucket_name, result['owner'], daemon_name)
 
         # Append the locking configuration.
         locking = self._get_locking(result['owner'], daemon_name, bucket_name)
@@ -520,8 +525,10 @@ class RgwBucket(RgwRESTController):
             mfa_delete=None, mfa_token_serial=None, mfa_token_pin=None,
             lock_mode=None, lock_retention_period_days=None,
             lock_retention_period_years=None, tags=None, bucket_policy=None,
-            canned_acl=None, daemon_name=None):
+            canned_acl=None, replication=None, daemon_name=None):
         encryption_state = str_to_bool(encryption_state)
+        if replication is not None:
+            replication = str_to_bool(replication)
         # When linking a non-tenant-user owned bucket to a tenanted user, we
         # need to prefix bucket name with '/'. e.g. photos -> /photos
         if '$' in uid and '/' not in bucket:
@@ -566,6 +573,8 @@ class RgwBucket(RgwRESTController):
             self._set_policy(bucket_name, bucket_policy, daemon_name, uid)
         if canned_acl:
             self._set_acl(bucket_name, canned_acl, uid, daemon_name)
+        if replication is not None:
+            self._set_replication(bucket_name, replication, uid, daemon_name)
         return self._append_bid(result)
 
     def delete(self, bucket, purge_objects='true', daemon_name=None):
index 1a709f8644f00dc48cfe84b0ba8acfeded61fcf7..c88b6f2cd0b5d17c18f284686a60bef149e24e07 100644 (file)
@@ -24,8 +24,9 @@ export class RgwBucketDetailsComponent implements OnChanges {
         bucket['lock_retention_period_days'] = this.rgwBucketService.getLockDays(bucket);
         this.selection = bucket;
         this.aclPermissions = this.parseXmlAcl(this.selection.acl, this.selection.owner);
-        if (this.selection.replication?.['Rule']?.['Status'])
+        if (this.selection.replication?.['Rule']?.['Status']) {
           this.replicationStatus = this.selection.replication?.['Rule']?.['Status'];
+        }
       });
     }
   }
index 87dbee26dc2e6b40ba359b56250dcf01a8270131..563237036f650f9e73edbb0391240c593b1004dd 100644 (file)
               <div class="mt-1"
                    *ngIf="!editing">
                 <cd-alert-panel type="info"
-                                *ngIf="!multisiteStatus.status.available && !multisiteStatus.isDefaultZg"
-                                class="me-1"
-                                id="multisite-configured-info"
-                                i18n>
-                  Multi-site needs to be configured on the current realm or you need to be on
-                  the default zonegroup to enable replication.
-                </cd-alert-panel>
-                <cd-alert-panel type="info"
-                                *ngIf="bucketForm.getValue('replication')"
                                 class="me-1"
                                 id="replication-info"
                                 i18n>
index 189f5b02c85c815003ec8bbe90952b2ac1fa1cb5..a290beab8f4cbc2bd69de43a9413b9d81c62104c 100644 (file)
@@ -334,7 +334,8 @@ export class RgwBucketFormComponent extends CdForm implements OnInit, AfterViewC
           values['lock_retention_period_days'],
           xmlStrTags,
           bucketPolicy,
-          cannedAcl
+          cannedAcl,
+          values['replication']
         )
         .subscribe(
           () => {
index f930af6cba3cf7b871c45585fd3441c8aa66727d..533d04628ee315544d4efdc1eb4b5669858b2bc4 100644 (file)
@@ -89,11 +89,12 @@ describe('RgwBucketService', () => {
         '10',
         null,
         null,
-        'private'
+        'private',
+        'true'
       )
       .subscribe();
     const req = httpTesting.expectOne(
-      `api/rgw/bucket/foo?${RgwHelper.DAEMON_QUERY_PARAM}&bucket_id=bar&uid=baz&versioning_state=Enabled&encryption_state=true&encryption_type=aws%253Akms&key_id=qwerty1&mfa_delete=Enabled&mfa_token_serial=1&mfa_token_pin=223344&lock_mode=GOVERNANCE&lock_retention_period_days=10&tags=null&bucket_policy=null&canned_acl=private`
+      `api/rgw/bucket/foo?${RgwHelper.DAEMON_QUERY_PARAM}&bucket_id=bar&uid=baz&versioning_state=Enabled&encryption_state=true&encryption_type=aws%253Akms&key_id=qwerty1&mfa_delete=Enabled&mfa_token_serial=1&mfa_token_pin=223344&lock_mode=GOVERNANCE&lock_retention_period_days=10&tags=null&bucket_policy=null&canned_acl=private&replication=true`
     );
     expect(req.request.method).toBe('PUT');
   });
index 8c9a9bacf4d4400050a42bf3d1890043ff41c026..2bf85e70512e5f43dc696e6a9d1ce38762a0f1df 100644 (file)
@@ -108,7 +108,8 @@ export class RgwBucketService extends ApiClient {
     lockRetentionPeriodDays: string,
     tags: string,
     bucketPolicy: string,
-    cannedAcl: string
+    cannedAcl: string,
+    replication: string
   ) {
     return this.rgwDaemonService.request((params: HttpParams) => {
       params = params.appendAll({
@@ -125,7 +126,8 @@ export class RgwBucketService extends ApiClient {
         lock_retention_period_days: lockRetentionPeriodDays,
         tags: tags,
         bucket_policy: bucketPolicy,
-        canned_acl: cannedAcl
+        canned_acl: cannedAcl,
+        replication: replication
       });
       return this.http.put(`${this.url}/${bucket}`, null, { params: params });
     });
index d98613b53d62746ee44789f05dc2e21789e915a4..70e691d3b525d853748860ac8b9245fbe5e42b20 100644 (file)
@@ -10936,6 +10936,8 @@ paths:
                   type: string
                 mfa_token_serial:
                   type: string
+                replication:
+                  type: string
                 tags:
                   type: string
                 uid: