Merge pull request #68465 from rhcs-dashboard/IBMCEPH-10149-rgw-non-version-bucket

mgr/dashboard : fix-non-versioning-bucket-issue

Reviewed-by: Afreen Misbah <afreen@ibm.com>
Reviewed-by: Dnyaneshwari Talwekar <dtalweka@redhat.com>
This commit is contained in:
Afreen Misbah 2026-04-21 22:54:17 +05:30 committed by GitHub
commit 70c8ca4db9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 57 additions and 11 deletions

View File

@ -204,7 +204,7 @@ class RgwBucketTest(RgwTestCase):
self.assertEqual(data['bucket'], 'teuth-test-bucket')
self.assertEqual(data['owner'], 'admin')
self.assertEqual(data['placement_rule'], 'default-placement')
self.assertEqual(data['versioning'], 'Suspended')
self.assertEqual(data['versioning'], 'Off')
# Update bucket: change owner, enable versioning.
self._put(
@ -312,7 +312,7 @@ class RgwBucketTest(RgwTestCase):
# Get the bucket.
data = _verify_tenant_bucket('teuth-test-bucket', 'testx', 'teuth-test-user')
self.assertEqual(data['placement_rule'], 'default-placement')
self.assertEqual(data['versioning'], 'Suspended')
self.assertEqual(data['versioning'], 'Off')
# Update bucket: different user with different tenant, enable versioning.
self._put(

View File

@ -1,4 +1,5 @@
export enum RgwBucketVersioning {
ENABLED = 'Enabled',
SUSPENDED = 'Suspended'
SUSPENDED = 'Suspended',
OFF = 'Off'
}

View File

@ -68,6 +68,7 @@ export class RgwBucketFormComponent extends CdForm implements OnInit, AfterViewC
placementTargets: object[] = [];
isVersioningAlreadyEnabled = false;
isMfaDeleteAlreadyEnabled = false;
initialVersioningStatus: string | null = null;
icons = Icons;
kmsConfigured = false;
s3Configured = false;
@ -267,6 +268,9 @@ export class RgwBucketFormComponent extends CdForm implements OnInit, AfterViewC
if (data['getBid']) {
const bidResp = data['getBid'];
if (this.editing) {
this.initialVersioningStatus = bidResp['versioning'] ?? null;
}
// Get the default values (incl. the values from disabled fields).
const defaults = _.clone(this.bucketForm.getRawValue());
@ -527,8 +531,14 @@ export class RgwBucketFormComponent extends CdForm implements OnInit, AfterViewC
mfaTokenPinControl.updateValueAndValidity();
}
getVersioningStatus() {
return this.isVersioningEnabled ? RgwBucketVersioning.ENABLED : RgwBucketVersioning.SUSPENDED;
getVersioningStatus(): string {
if (this.isVersioningEnabled) {
return RgwBucketVersioning.ENABLED;
}
if (this.editing && this.initialVersioningStatus === RgwBucketVersioning.OFF) {
return '';
}
return RgwBucketVersioning.SUSPENDED;
}
getMfaDeleteStatus() {

View File

@ -95,7 +95,35 @@ describe('RgwBucketService', () => {
)
.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&replication=true&lifecycle=null`
`api/rgw/bucket/foo?${RgwHelper.DAEMON_QUERY_PARAM}&bucket_id=bar&uid=baz&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&lifecycle=null&versioning_state=Enabled`
);
expect(req.request.method).toBe('PUT');
});
it('should call update without versioning_state when empty', () => {
service
.update(
'foo',
'bar',
'baz',
'',
true,
'aws:kms',
'qwerty1',
'Enabled',
'1',
'223344',
'GOVERNANCE',
'10',
null,
null,
'private',
'true',
null
)
.subscribe();
const req = httpTesting.expectOne(
`api/rgw/bucket/foo?${RgwHelper.DAEMON_QUERY_PARAM}&bucket_id=bar&uid=baz&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&lifecycle=null`
);
expect(req.request.method).toBe('PUT');
});

View File

@ -170,10 +170,9 @@ export class RgwBucketService extends ApiClient {
lifecycle: string
) {
return this.rgwDaemonService.request((params: HttpParams) => {
params = params.appendAll({
const paramsObject: Record<string, string> = {
bucket_id: bucketId,
uid: uid,
versioning_state: versioningState,
encryption_state: String(encryptionState),
encryption_type: encryptionType,
key_id: keyId,
@ -187,7 +186,11 @@ export class RgwBucketService extends ApiClient {
canned_acl: cannedAcl,
replication: replication,
lifecycle: lifecycle
});
};
if (versioningState) {
paramsObject['versioning_state'] = versioningState;
}
params = params.appendAll(paramsObject);
return this.http.put(`${this.url}/${bucket}`, null, { params: params });
});
}

View File

@ -599,8 +599,12 @@ class RgwClient(RestClient):
"""
# pylint: disable=unused-argument
result = request()
if 'Status' not in result:
result['Status'] = 'Suspended'
if not isinstance(result, dict):
result = {}
# RGW omits Status when versioning has never been configured (CLI/radosgw-admin
# reports "off"). That must not be shown as "Suspended", which means versioning was enabled
if not result.get('Status'):
result['Status'] = 'Off'
if 'MfaDelete' not in result:
result['MfaDelete'] = 'Disabled'
return result