]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Locking improvements in bucket create form 56560/head
authorAfreen <afreen23.git@gmail.com>
Fri, 1 Mar 2024 07:26:25 +0000 (12:56 +0530)
committerAfreen <afreen23.git@gmail.com>
Thu, 28 Mar 2024 16:00:42 +0000 (21:30 +0530)
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>
(cherry picked from commit 014d4468fce5aadfbc63bd9651c0c66db0bf7f49)

 Conflicts:
src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.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.spec.ts
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/components/components.module.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/help-text/help-text.component.html [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/components/help-text/help-text.component.scss [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/components/help-text/help-text.component.spec.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/components/help-text/help-text.component.ts [new file with mode: 0644]

index fd085a74d2d09ab882f743d8f38b149cbcf8c427..41b7f11629779a9ffd9d47f987f209b70bc3292c 100644 (file)
           </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"
                       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>
                     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>
index 704d7918465df24c8b9c4fbb928a625c72ffaca8..44318eda88e165b9a26b21b73e12c94b141726a2 100644 (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');
index a50545714d11f344f21facc97d45c12c48e4abd3..e92cf952c655b82c5bf847bd6700a3ab198f5a73 100644 (file)
@@ -151,7 +151,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]]
index 5b533f1cddb305c5677e0b082d8929548ece199e..d5180f5db9dac3798207ee17b07a14d31c212507 100644 (file)
@@ -53,6 +53,7 @@ import { CardComponent } from './card/card.component';
 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 { HelpTextComponent } from './help-text/help-text.component';
 
 @NgModule({
   imports: [
@@ -109,7 +110,8 @@ import { VerticalNavigationComponent } from './vertical-navigation/vertical-navi
     CardComponent,
     CardRowComponent,
     CodeBlockComponent,
-    VerticalNavigationComponent
+    VerticalNavigationComponent,
+    HelpTextComponent
   ],
   providers: [],
   exports: [
@@ -143,7 +145,8 @@ import { VerticalNavigationComponent } from './vertical-navigation/vertical-navi
     CardComponent,
     CardRowComponent,
     CodeBlockComponent,
-    VerticalNavigationComponent
+    VerticalNavigationComponent,
+    HelpTextComponent
   ]
 })
 export class ComponentsModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/help-text/help-text.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/help-text/help-text.component.html
new file mode 100644 (file)
index 0000000..e8d0d6e
--- /dev/null
@@ -0,0 +1,3 @@
+  <div class="form-text text-muted">
+    <ng-content></ng-content>
+  </div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/help-text/help-text.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/help-text/help-text.component.scss
new file mode 100644 (file)
index 0000000..f7be01c
--- /dev/null
@@ -0,0 +1,3 @@
+::ng-deep legend .text-muted {
+  font-size: small;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/help-text/help-text.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/help-text/help-text.component.spec.ts
new file mode 100644 (file)
index 0000000..10a8641
--- /dev/null
@@ -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();
+  });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/help-text/help-text.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/help-text/help-text.component.ts
new file mode 100644 (file)
index 0000000..60fed74
--- /dev/null
@@ -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 {}