mgr/dashboard: Locking improvements in bucket create form

Fixes https://tracker.ceph.com/issues/64658
- Addition of help texts
- Addition of info/warnings related to modes and versioning
- change of Locking section layout
- renaming locking to 'Object Locking'
- changes default retention period to 10
- edit bucket only shows lock when its enabled

Signed-off-by: Afreen <afreen23.git@gmail.com>
This commit is contained in:
Afreen 2024-03-01 12:56:25 +05:30
parent 55ac8d6d0b
commit 014d4468fc
8 changed files with 115 additions and 29 deletions

View File

@ -213,30 +213,34 @@
</div>
</fieldset>
<!-- Locking -->
<fieldset>
<!-- Object Locking -->
<fieldset *ngIf="!editing || (editing && bucketForm.getValue('lock_enabled'))">
<legend class="cd-header"
i18n>Locking</legend>
<!-- Locking enabled -->
i18n>
Object Locking
<cd-help-text class="bc-legend-help">
Store objects using a write-once-read-many (WORM) model to help you prevent objects from being deleted or overwritten for a fixed amount of time or indefinitely.
Object Locking works only in versioned buckets.
</cd-help-text>
</legend>
<!-- Object Locking enable -->
<div class="form-group row">
<div class="cd-col-form-offset">
<div class="custom-control custom-checkbox">
<input class="custom-control-input"
id="lock_enabled"
formControlName="lock_enabled"
type="checkbox">
<label class="custom-control-label"
for="lock_enabled"
i18n>Enabled</label>
<cd-helper>
<span i18n>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</span>
</cd-helper>
</div>
<label class="cd-col-form-label pt-0"
for="lock_enabled"
i18n>
Enable
</label>
<div class="cd-col-form-input">
<input class="form-check-input"
id="lock_enabled"
formControlName="lock_enabled"
type="checkbox"/>
<cd-help-text>
<span i18n>Enables locking for the objects in the bucket. Locking can only be enabled while creating a bucket.</span>
</cd-help-text>
</div>
</div>
<!-- Locking mode -->
<!-- Object Locking mode -->
<div *ngIf="bucketForm.getValue('lock_enabled')"
class="form-group row">
<label class="cd-col-form-label"
@ -248,27 +252,42 @@
name="lock_mode"
id="lock_mode">
<option i18n
value="COMPLIANCE">Compliance</option>
value="COMPLIANCE" >
Compliance
</option>
<option i18n
value="GOVERNANCE">Governance</option>
value="GOVERNANCE">
Governance
</option>
</select>
<cd-help-text>
<span *ngIf="bucketForm.getValue('lock_mode') === 'COMPLIANCE'"
i18n>
In COMPLIANCE an object version cannot be overwritten or deleted for the duration of the period.
</span>
<span *ngIf="bucketForm.getValue('lock_mode') === 'GOVERNANCE'"
i18n>
In GOVERNANCE mode, users cannot overwrite or delete an object version or alter its lock settings unless they have special permissions.
</span>
</cd-help-text>
</div>
</div>
<!-- Retention period (days) -->
<div *ngIf="bucketForm.getValue('lock_enabled')"
class="form-group row">
<label class="cd-col-form-label"
for="lock_retention_period_days">
<ng-container i18n>Days</ng-container>
<cd-helper i18n>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</cd-helper>
</label>
<div class="cd-col-form-input">
<input class="form-control"
type="number"
id="lock_retention_period_days"
formControlName="lock_retention_period_days"
min="0">
min="1">
<cd-help-text>
<span i18n>The number of days that you want to specify for the default retention period that will be applied to new objects placed in this bucket.</span>
</cd-help-text>
<span class="invalid-feedback"
*ngIf="bucketForm.showError('lock_retention_period_days', frm, 'pattern')"
i18n>The entered value must be a positive integer.</span>
@ -277,6 +296,24 @@
i18n>Retention Days must be a positive integer.</span>
</div>
</div>
<!-- Alerts -->
<div class="form-group row">
<div class="cd-col-form-label"></div>
<div class="cd-col-form-input">
<cd-alert-panel
type="info"
*ngIf="bucketForm.getValue('lock_enabled')"
class="me-1"
i18n-title>
Bucket Versioning can't be disabled when Object Locking is enabled.
</cd-alert-panel>
<cd-alert-panel
type="warning"
*ngIf="bucketForm.getValue('lock_enabled')">
Enabling Object Locking will allow the configuration of GOVERNANCE or COMPLIANCE modes, which will help ensure that an object version cannot be overwritten or deleted for the specified period.
</cd-alert-panel>
</div>
</div>
</fieldset>
<fieldset>

View File

@ -272,10 +272,20 @@ describe('RgwBucketFormComponent', () => {
expect(control.disabled).toBeTruthy();
});
it('should have the "lockDays" error', () => {
it('should not have the "lockDays" error for 10 days', () => {
formHelper.setValue('lock_enabled', true);
const control = component.bucketForm.get('lock_retention_period_days');
control.updateValueAndValidity();
expect(control.value).toBe(10);
expect(control.invalid).toBeFalsy();
formHelper.expectValid(control);
});
it('should have the "lockDays" error for 0 days', () => {
formHelper.setValue('lock_enabled', true);
formHelper.setValue('lock_retention_period_days', 0);
const control = component.bucketForm.get('lock_retention_period_days');
control.updateValueAndValidity();
expect(control.value).toBe(0);
expect(control.invalid).toBeTruthy();
formHelper.expectError(control, 'lockDays');

View File

@ -150,7 +150,7 @@ export class RgwBucketFormComponent extends CdForm implements OnInit, AfterViewC
]
],
lock_mode: ['COMPLIANCE'],
lock_retention_period_days: [0, [CdValidators.number(false), lockDaysValidator]],
lock_retention_period_days: [10, [CdValidators.number(false), lockDaysValidator]],
bucket_policy: ['{}', CdValidators.json()],
grantee: [Grantee.Owner, [Validators.required]],
aclPermission: [[aclPermission.FullControl], [Validators.required]]

View File

@ -54,6 +54,7 @@ import { CardRowComponent } from './card-row/card-row.component';
import { CodeBlockComponent } from './code-block/code-block.component';
import { VerticalNavigationComponent } from './vertical-navigation/vertical-navigation.component';
import { CardGroupComponent } from './card-group/card-group.component';
import { HelpTextComponent } from './help-text/help-text.component';
@NgModule({
imports: [
@ -111,7 +112,8 @@ import { CardGroupComponent } from './card-group/card-group.component';
CardRowComponent,
CodeBlockComponent,
VerticalNavigationComponent,
CardGroupComponent
CardGroupComponent,
HelpTextComponent
],
providers: [],
exports: [
@ -146,7 +148,8 @@ import { CardGroupComponent } from './card-group/card-group.component';
CardRowComponent,
CodeBlockComponent,
VerticalNavigationComponent,
CardGroupComponent
CardGroupComponent,
HelpTextComponent
]
})
export class ComponentsModule {}

View File

@ -0,0 +1,3 @@
<div class="form-text text-muted">
<ng-content></ng-content>
</div>

View File

@ -0,0 +1,3 @@
::ng-deep legend .text-muted {
font-size: small;
}

View File

@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HelpTextComponent } from './help-text.component';
describe('HelpTextComponent', () => {
let component: HelpTextComponent;
let fixture: ComponentFixture<HelpTextComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [HelpTextComponent]
}).compileComponents();
fixture = TestBed.createComponent(HelpTextComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,8 @@
import { Component } from '@angular/core';
@Component({
selector: 'cd-help-text',
templateUrl: './help-text.component.html',
styleUrls: ['./help-text.component.scss']
})
export class HelpTextComponent {}