From aa3bb8adddac675ea3c6dcd0bd4e9143743124b8 Mon Sep 17 00:00:00 2001 From: Dnyaneshwari Date: Wed, 20 Aug 2025 10:16:21 +0530 Subject: [PATCH] mgr/dashboard: Tiering form - Placement Target in Advanced Section Fixes: https://tracker.ceph.com/issues/72545 Signed-off-by: Dnyaneshwari Talwekar --- .../rgw-multisite-migrate.component.html | 4 +- .../rgw-multisite-zone-form.component.html | 2 +- ...gw-multisite-zonegroup-form.component.html | 2 +- .../rgw-storage-class-details.component.html | 71 +---- .../rgw-storage-class-form.component.html | 273 +++++++++--------- .../rgw-storage-class-form.component.ts | 47 +-- .../rgw-storage-class-list.component.ts | 7 +- 7 files changed, 182 insertions(+), 224 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-migrate/rgw-multisite-migrate.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-migrate/rgw-multisite-migrate.component.html index 1277af79362..e9d1c7e6926 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-migrate/rgw-multisite-migrate.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-migrate/rgw-multisite-migrate.component.html @@ -58,7 +58,7 @@
@@ -97,7 +97,7 @@
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-zone-form/rgw-multisite-zone-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-zone-form/rgw-multisite-zone-form.component.html index c6a001be3fb..f2b8cf2d5b5 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-zone-form/rgw-multisite-zone-form.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-zone-form/rgw-multisite-zone-form.component.html @@ -97,7 +97,7 @@
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-zonegroup-form/rgw-multisite-zonegroup-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-zonegroup-form/rgw-multisite-zonegroup-form.component.html index 7a64e31d36d..b0b360772f8 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-zonegroup-form/rgw-multisite-zonegroup-form.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-zonegroup-form/rgw-multisite-zonegroup-form.component.html @@ -91,7 +91,7 @@
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-details/rgw-storage-class-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-details/rgw-storage-class-details.component.html index 701ae11f27f..1a988d3407b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-details/rgw-storage-class-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-details/rgw-storage-class-details.component.html @@ -7,34 +7,7 @@ data-testid="rgw-storage-details" > - @if( isTierMatch( TIER_TYPE_DISPLAY.LOCAL )){ - - - Zone Group - - - {{ zoneGroupText }} - - - - {{ selection?.zonegroup_name }} - - } @if(isTierMatch( TIER_TYPE_DISPLAY.LOCAL )){ - - - Placement Target - - - Placement Target defines the destination and rules for moving objects between - storage tiers. - - - - {{ selection?.placement_target }} - - } @if(isTierMatch( TIER_TYPE_DISPLAY.CLOUD_TIER, TIER_TYPE_DISPLAY.GLACIER)){ + @if(isTierMatch( TIER_TYPE_DISPLAY.CLOUD_TIER, TIER_TYPE_DISPLAY.GLACIER)){ @@ -75,32 +48,8 @@
- - - Secret key - - {{ targetSecretKeyText }} - - - -
- - - -
- - + } + @if(isTierMatch( TIER_TYPE_DISPLAY.CLOUD_TIER, TIER_TYPE_DISPLAY.GLACIER)){ @@ -213,7 +162,7 @@ {{ selection?.multipart_sync_threshold | dimlessBinary }} - } @if(selection?.acl_mappings.length > 0) { + } @if(selection?.acl_mappings?.length > 0) { ACLs @@ -234,6 +183,18 @@ } + + + Placement Target + + + Placement Target defines the destination and rules for moving objects between + storage tiers. + + + + {{ selection?.placement_target }} + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-form/rgw-storage-class-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-form/rgw-storage-class-form.component.html index 138bc4131ec..aa65fc210d0 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-form/rgw-storage-class-form.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-form/rgw-storage-class-form.component.html @@ -31,20 +31,45 @@ - This field is required. + @if (storageClassForm.showError('storageClassType', formDir, 'required')) { + This field is required. + }
+ +
+ + Storage Class name + + + + @if (storageClassForm.showError('storage_class', formDir, 'required')) { + This field is required. + } + +
+
- - This field is required. + @if (storageClassForm.showError('zonegroup', formDir, 'required')) { + This field is required. + }
-
- - - - - - - This field is required. - -
-
- -
- Name - - - - This field is required. -
@if( isTierMatch( TIER_TYPE.CLOUD_TIER, TIER_TYPE.GLACIER )){
@@ -154,33 +118,47 @@ /> - This field is required. + @if (storageClassForm.showError('region', formDir, 'required')) { + This field is required. + }
Target Endpoint + + @if (storageClassForm.showError('target_endpoint', formDir, 'required')) { + This field is required. + } @else if (storageClassForm.showError('target_endpoint', formDir, 'invalidURL')) { + Please enter a valid URL. + } +
@@ -203,14 +181,12 @@ [invalid]="storageClassForm.showError('access_key', formDir, 'required')" /> - + - This field is required. + @if (storageClassForm.showError('access_key', formDir, 'required')) { + This field is required. + }
@@ -236,12 +212,10 @@ - This field is required. + @if (storageClassForm.showError('secret_key', formDir, 'required')) { + This field is required. + } @@ -263,12 +237,10 @@ /> - This field is required. + @if (storageClassForm.showError('target_path', formDir, 'required')) { + This field is required. + }
@@ -312,18 +284,12 @@ [invalidText]="readThroughError" > - The entered value must be a positive integer. - ReadThrough Restore Days must be positive. + @if (storageClassForm.showError('read_through_restore_days', formDir, 'pattern')) { + + ReadThrough Restore Days must be positive. + + }
@@ -370,12 +336,10 @@ i18n>Expedited - This field is required. + @if (storageClassForm.showError('glacier_restore_tier_type', formDir, 'required')) { + This field is required. + }
@@ -396,23 +360,17 @@ > - The entered value must be a positive integer. - Glacier Restore Days must be positive. + @if (storageClassForm.showError('glacier_restore_days', formDir, 'pattern')) { + + The entered value must be a positive integer. + + }
- } @if( isTierMatch( TIER_TYPE.CLOUD_TIER, TIER_TYPE.GLACIER )){ + }
@@ -426,6 +384,7 @@ id="advanced-fieldset" (selected)="showAdvanced = !showAdvanced" > + @if( isTierMatch( TIER_TYPE.CLOUD_TIER, TIER_TYPE.GLACIER )){
@@ -570,12 +529,48 @@ }
+ } +
+
+ + + + @for (placementTarget of placementTargets; track placementTarget) { + + } + + + @if (storageClassForm.showError('placement_target', formDir, 'required')) { + This field is required. + } + +
+
- } @if( isTierMatch( TIER_TYPE.CLOUD_TIER, TIER_TYPE.GLACIER )){ + @if( isTierMatch( TIER_TYPE.CLOUD_TIER, TIER_TYPE.GLACIER )){ RGW service would be restarted after creating the storage class. diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-form/rgw-storage-class-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-form/rgw-storage-class-form.component.ts index 4a81ef203c3..15a9bb7b4c2 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-form/rgw-storage-class-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-form/rgw-storage-class-form.component.ts @@ -184,26 +184,29 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit { secret_key: response?.secret, target_path: response?.target_path, retain_head_object: this.tierTargetInfo?.val?.retain_head_object || false, - multipart_sync_threshold: response?.multipart_sync_threshold || '', - multipart_min_part_size: response?.multipart_min_part_size || '', allow_read_through: this.tierTargetInfo?.val?.allow_read_through || false, restore_storage_class: this.tierTargetInfo?.val?.restore_storage_class, read_through_restore_days: this.tierTargetInfo?.val?.read_through_restore_days, acl_mappings: this.tierTargetInfo?.val?.s3?.acl_mappings || [] }); - this.acls?.clear(); - if (aclMappings.length > 0) { - aclMappings.forEach((acl) => { - this.acls?.push( - this.formBuilder.group({ - source_id: [acl.val?.source_id || ''], - dest_id: [acl.val?.dest_id || ''], - type: [acl.val?.type || AclTypeConst.ID, Validators.required] - }) - ); - }); - } else { - this.addAcls(); + if ( + this.storageClassForm.get('storageClassType')?.value === TIER_TYPE.CLOUD_TIER || + this.storageClassForm.get('storageClassType')?.value === TIER_TYPE.GLACIER + ) { + this.acls?.clear(); + if (aclMappings.length > 0) { + aclMappings.forEach((acl) => { + this.acls?.push( + this.formBuilder.group({ + source_id: [acl.val?.source_id || ''], + dest_id: [acl.val?.dest_id || ''], + type: [acl.val?.type || AclTypeConst.ID, Validators.required] + }) + ); + }); + } else { + this.addAcls(); + } } if (this.tierTargetInfo?.val?.tier_type == TIER_TYPE.GLACIER) { let glacierResponse = this.tierTargetInfo?.val['s3-glacier']; @@ -221,7 +224,6 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit { this.onAllowReadThroughChange(value); }); } - createForm() { const self = this; @@ -288,7 +290,13 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit { ), allow_read_through: new FormControl(false), storageClassType: new FormControl(TIER_TYPE.LOCAL, Validators.required), - acls: new FormArray([this.createAcls()]) + acls: new FormArray([]) + }); + this.storageClassForm.get('storageClassType')?.valueChanges.subscribe((type: string) => { + if (type === TIER_TYPE.CLOUD_TIER) { + const aclsArray = this.storageClassForm.get('acls') as FormArray; + aclsArray.push(this.createAcls()); + } }); } @@ -541,7 +549,6 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit { buildRequest() { if (this.storageClassForm.errors) return null; - const rawFormValue = _.cloneDeep(this.storageClassForm.value); const zoneGroup = this.storageClassForm.get('zonegroup').value; const storageClass = this.storageClassForm.get('storage_class').value; @@ -560,8 +567,8 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit { this.removedAclSourceIds.forEach((sourceId: string, index: number) => { tier_config_rm[`acls[${index}].source_id`] = sourceId; }); - if (this.aclList.length > rawFormValue.acls.length) { - this.aclList.forEach((acl: ACL, index: number) => { + if (this.aclList?.length > rawFormValue.acls?.length) { + this.aclList?.forEach((acl: ACL, index: number) => { const sourceId = acl?.val?.source_id; const ifExist = removeAclList.find((acl: ACLVal) => acl?.source_id === sourceId); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-list/rgw-storage-class-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-list/rgw-storage-class-list.component.ts index fbe7dd9d48d..9cd8abf13aa 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-list/rgw-storage-class-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-list/rgw-storage-class-list.component.ts @@ -60,7 +60,7 @@ export class RgwStorageClassListComponent extends ListWithDetails implements OnI isHidden: true }, { - name: $localize`Storage Class`, + name: $localize`Storage Class name`, prop: 'storage_class', flexGrow: 2 }, @@ -74,11 +74,6 @@ export class RgwStorageClassListComponent extends ListWithDetails implements OnI prop: 'zonegroup_name', flexGrow: 2 }, - { - name: $localize`Placement Target`, - prop: 'placement_target', - flexGrow: 2 - }, { name: $localize`Target Region`, prop: 'region', -- 2.39.5