]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Storage Class - Update 64527/head
authorDnyaneshwari <dnyaneshwari@li-9c9fbecc-2d5c-11b2-a85c-e2a7cc8a424f.ibm.com>
Wed, 16 Jul 2025 10:02:22 +0000 (15:32 +0530)
committerDnyaneshwari <dnyaneshwari@li-9c9fbecc-2d5c-11b2-a85c-e2a7cc8a424f.ibm.com>
Mon, 21 Jul 2025 13:20:39 +0000 (18:50 +0530)
Fixes: https://tracker.ceph.com/issues/72156
Signed-off-by: Dnyaneshwari Talwekar <dtalwekar@redhat.com>
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-storage-class.model.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-details/rgw-storage-class-details.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-form/rgw-storage-class-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-form/rgw-storage-class-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-form/rgw-storage-class-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-list/rgw-storage-class-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/utils/rgw-bucket-tiering.ts
src/pybind/mgr/dashboard/services/rgw_client.py

index 15a9a972416f277c3b3abc1f6301512568dd5dd2..d23f79678953a3f1fbf46d45276dc6a87b360320 100644 (file)
@@ -22,7 +22,7 @@ export interface TierTarget {
     read_through_restore_days: number;
     restore_storage_class: string;
     s3?: S3Details;
-    's3-glacier': S3Glacier;
+    's3-glacier'?: S3Glacier;
   };
 }
 
@@ -81,8 +81,8 @@ export interface RequestModel {
 }
 
 export interface PlacementTarget {
-  tags?: string[];
   placement_id: string;
+  tags?: string[];
   tier_type?: TIER_TYPE;
   tier_config?: {
     endpoint: string;
@@ -128,6 +128,24 @@ export interface TextLabels {
   restoreStorageClassText: string;
 }
 
+export const CLOUD_TIER_REQUIRED_FIELDS = [
+  'region',
+  'target_endpoint',
+  'access_key',
+  'secret_key',
+  'target_path'
+];
+
+export const GLACIER_REQUIRED_FIELDS = [
+  'region',
+  'target_endpoint',
+  'access_key',
+  'secret_key',
+  'target_path',
+  'glacier_restore_tier_type',
+  'restore_storage_class'
+];
+
 export const TIER_TYPE = {
   LOCAL: 'local',
   CLOUD_TIER: 'cloud-s3',
@@ -198,7 +216,7 @@ export const EXPEDITED_TIER_TYPE_TEXT = $localize`Expedited glacier restore tier
 
 export const RESTORE_DAYS_TEXT = $localize`Refers to number of days to the object will be restored on glacier/tape endpoint.`;
 
-export const READTHROUGH_RESTORE_DAYS_TEXT = $localize`The duration for which objects restored via read-through are retained.`;
+export const READTHROUGH_RESTORE_DAYS_TEXT = $localize`The days for which objects restored via read-through are retained.`;
 
 export const RESTORE_STORAGE_CLASS_TEXT = $localize`The storage class to which object data is to be restored.`;
 
index baa283145fdc5e89b008b2d850ac59c5403ecb9d..dc8886ef5aa6b0173cf2bdfb993ec161699ef91f 100644 (file)
                 </span>
               </cd-helper>
             </td>
-            <td>{{ selection?.multipart_min_part_size }}</td>
+            <td>{{ selection?.multipart_min_part_size | dimlessBinary }}</td>
           </tr>
         }
         @if(isTierMatch( TIER_TYPE_DISPLAY.CLOUD_TIER, TIER_TYPE_DISPLAY.GLACIER)){
                 </span>
               </cd-helper>
             </td>
-            <td>{{ selection?.multipart_sync_threshold }}</td>
+            <td>{{ selection?.multipart_sync_threshold | dimlessBinary }}</td>
           </tr>
         }
         </tbody>
index 31cf2635c9529f96c33a6ba6d53fa9f1243d4516..57076071a5cb920a09630b32091a172f8ffc9cb7 100644 (file)
@@ -17,7 +17,7 @@
           i18n-label
           for="storageClassType"
           formControlName="storageClassType"
-          [helperText]="textLabels.storageClassText"
+          [helperText]="helpTextLabels.storageClassText"
           id="storageClassType"
           [invalid]="storageClassForm.showError('storageClassType', formDir, 'required')"
           [invalidText]="storageError"
               i18n
               [invalid]="storageClassForm.showError('region', formDir, 'required')"
               [invalidText]="regionError"
-              [helperText]="textLabels.targetRegionText"
+              [helperText]="helpTextLabels.targetRegionText"
               >Target Region
               <input
                 cdsText
           <div cdsCol>
             <!-- Target Endpoint -->
             <cds-text-label
-              labelInputID="endpoint"
-              i18n
-              [invalid]="storageClassForm.showError('endpoint', formDir, 'required')"
+            labelInputID="target_endpoint"
+            i18n
+            [invalid]="storageClassForm.showError('target_endpoint', formDir, 'invalidURL') || storageClassForm.showError('target_endpoint', formDir, 'required')"
+            [invalidText]="endpointError"
+            [helperText]="helpTextLabels.targetEndpointText"
+            >Target Endpoint
+            <input
+              cdsText
+              type="text"
+              placeholder="e.g, http://ceph-node-00.com:80"
+              i18n-placeholder
+              id="target_endpoint"
+              formControlName="target_endpoint"
+              [invalid]="storageClassForm.showError('target_endpoint', formDir, 'invalidURL') || storageClassForm.showError('target_endpoint', formDir, 'required')"
               [invalidText]="endpointError"
-              [helperText]="textLabels.targetEndpointText"
-              >Target Endpoint
-              <input
-                cdsText
-                type="text"
-                placeholder="e.g, http://ceph-node-00.com:80"
-                i18n-placeholder
-                id="endpoint"
-                formControlName="endpoint"
-                [invalid]="storageClassForm.showError('endpoint', formDir, 'required')"
-              />
-            </cds-text-label>
+            />
+          </cds-text-label>
             <ng-template #endpointError>
               <span
                 class="invalid-feedback"
-                *ngIf="storageClassForm.showError('endpoint', formDir, 'required')"
+                *ngIf="storageClassForm.showError('target_endpoint', formDir, 'required')"
                 i18n
                 >This field is required.</span
               >
+              <span class="invalid-feedback"
+                    *ngIf="storageClassForm.showError('target_endpoint', formDir, 'invalidURL')"
+                    i18n>Please enter a valid URL.</span>
             </ng-template>
           </div>
         </div>
               labelInputID="access_key"
               [invalid]="storageClassForm.showError('access_key', formDir, 'required')"
               [invalidText]="accessError"
-              [helperText]="textLabels.targetAccessKeyText"
+              [helperText]="helpTextLabels.targetAccessKeyText"
               i18n
               >Target Access Key
               <input
                class="d-flex">
             <cds-password-label
               labelInputID="secret_key"
-              [helperText]="textLabels.targetSecretKeyText"
+              [helperText]="helpTextLabels.targetSecretKeyText"
               [invalid]="storageClassForm.showError('secret_key', formDir, 'required')"
               [invalidText]="secretError"
               i18n
             i18n
             [invalid]="storageClassForm.showError('target_path', formDir, 'required')"
             [invalidText]="targetError"
-            [helperText]="textLabels.targetPathText"
+            [helperText]="helpTextLabels.targetPathText"
             >Target Path
             <input
               cdsText
             i18n
             (change)="onAllowReadThroughChange($event)"
             >Allow Read Through
-            <cd-help-text>{{ textLabels?.allowReadThroughText }}</cd-help-text>
+            <cd-help-text>{{ helpTextLabels?.allowReadThroughText }}</cd-help-text>
           </cds-checkbox>
         </div>
         <div class="form-item">
             cdOptionalField="Head Object (Stub File)"
             i18n
             >Head Object (Stub File)
-            <cd-help-text>{{ textLabels?.retainHeadObjectText }}</cd-help-text>
+            <cd-help-text>{{ helpTextLabels?.retainHeadObjectText }}</cd-help-text>
           </cds-checkbox>
         </div>
         <div class="form-item form-item-append"
               id="read_through_restore_days"
               min="1"
               label="ReadThrough Restore Days"
-              [helperText]="textLabels.readthroughrestoreDaysText"
+              [helperText]="helpTextLabels.readthroughrestoreDaysText"
               i18n-helperText
               i18n-label
               i18n
               formControlName="restore_storage_class"
               label="Restore Storage Class"
               id="restore_storage_class"
-              [helperText]="textLabels.restoreStorageClassText"
+              [helperText]="helpTextLabels.restoreStorageClassText"
               i18n-label
             >
               <option value=""
                 storageClassForm.controls.glacier_restore_tier_type.dirty
               "
               [invalidText]="glacierError"
-              [helperText]="textLabels.tiertypeText"
+              [helperText]="helpTextLabels.tiertypeText"
               i18n-label
             >
               <option value=""
               [id]="'glacier_restore_days'"
               [formControlName]="'glacier_restore_days'"
               [label]="'Glacier Restore Days'"
-              [helperText]="textLabels.restoreDaysText"
+              [helperText]="helpTextLabels.restoreDaysText"
               [min]="1"
               i18n-helperText
               i18n-label
                     <cds-text-label
                       labelInputID="multipart_sync_threshold"
                       i18n
-                      [helperText]="textLabels.multipartSyncThresholdText"
+                      [helperText]="helpTextLabels.multipartSyncThresholdText"
                       cdOptionalField="Multipart Sync Threshold"
                       >Multipart Sync Threshold
                       <input
                     <cds-text-label
                       labelInputID="multipart_min_part_size"
                       i18n
-                      [helperText]="textLabels.multipartMinPartText"
+                      [helperText]="helpTextLabels.multipartMinPartText"
                       cdOptionalField="Multipart Minimum Part Size"
                       >Multipart Minimum Part Size
                       <input
index c7e7a6b5c5adb07ff6583a83fba6786b76b006ea..1e0f852672dbd11e74a2bc731419b59bde37814f 100644 (file)
@@ -112,7 +112,7 @@ describe('RgwStorageClassFormComponent', () => {
     component.storageClassForm.get('storage_class').setValue(storageClassName);
     component.storageClassForm.get('zonegroup').setValue('zonegroup1');
     component.storageClassForm.get('placement_target').setValue('placement1');
-    component.storageClassForm.get('endpoint').setValue('http://ams03.com');
+    component.storageClassForm.get('target_endpoint').setValue('http://ceph-node-00:8090');
     component.storageClassForm.get('access_key').setValue('accesskey');
     component.storageClassForm.get('secret_key').setValue('secretkey');
     component.storageClassForm.get('target_path').setValue('/target');
@@ -128,7 +128,7 @@ describe('RgwStorageClassFormComponent', () => {
 
   it('should set required validators for CLOUD_TIER fields', () => {
     (component as any).updateValidatorsBasedOnStorageClass(TIER_TYPE_DISPLAY.CLOUD_TIER);
-    const requiredFields = ['region', 'endpoint', 'access_key', 'secret_key', 'target_path'];
+    const requiredFields = ['region', 'target_endpoint', 'access_key', 'secret_key', 'target_path'];
     requiredFields.forEach((field) => {
       const control = component.storageClassForm.get(field);
       control.setValue('');
@@ -146,7 +146,7 @@ describe('RgwStorageClassFormComponent', () => {
     (component as any).updateValidatorsBasedOnStorageClass(TIER_TYPE_DISPLAY.GLACIER);
     const requiredFields = [
       'region',
-      'endpoint',
+      'target_endpoint',
       'access_key',
       'secret_key',
       'target_path',
@@ -166,7 +166,7 @@ describe('RgwStorageClassFormComponent', () => {
 
     const allFields = [
       'region',
-      'endpoint',
+      'target_endpoint',
       'access_key',
       'secret_key',
       'target_path',
index 2e813005ae59af122cd96edc9a58c29d4b067ed1..8f66deb5d8fa41dfa151cb0e98341ab6d0150063 100644 (file)
@@ -41,11 +41,14 @@ import {
   STORAGE_CLASS_CONSTANTS,
   STANDARD_TIER_TYPE_TEXT,
   EXPEDITED_TIER_TYPE_TEXT,
-  TextLabels
+  TextLabels,
+  CLOUD_TIER_REQUIRED_FIELDS,
+  GLACIER_REQUIRED_FIELDS
 } from '../models/rgw-storage-class.model';
 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
 import { NotificationService } from '~/app/shared/services/notification.service';
 import { CdValidators } from '~/app/shared/forms/cd-validators';
+import { FormatterService } from '~/app/shared/services/formatter.service';
 
 @Component({
   selector: 'cd-rgw-storage-class-form',
@@ -71,7 +74,7 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit {
   TIER_TYPE = TIER_TYPE;
   TIER_TYPE_DISPLAY = TIER_TYPE_DISPLAY;
   storageClassOptions: StorageClassOption[];
-  textLabels: TextLabels;
+  helpTextLabels: TextLabels;
 
   constructor(
     public actionLabels: ActionLabelsI18n,
@@ -80,7 +83,8 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit {
     private rgwStorageService: RgwStorageClassService,
     private rgwZoneGroupService: RgwZonegroupService,
     private router: Router,
-    private route: ActivatedRoute
+    private route: ActivatedRoute,
+    public formatter: FormatterService
   ) {
     super();
     this.resource = $localize`Tiering Storage Class`;
@@ -89,7 +93,7 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit {
   }
 
   ngOnInit() {
-    this.textLabels = {
+    this.helpTextLabels = {
       targetPathText: TARGET_PATH_TEXT,
       targetEndpointText: TARGET_ENDPOINT_TEXT,
       targetRegionText: TARGET_REGION_TEXT,
@@ -114,7 +118,7 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit {
     ];
     this.createForm();
     this.storageClassTypeText();
-    this.TierTypeText();
+    this.updateTierTypeHelpText();
     this.loadingReady();
     this.loadZoneGroup();
     if (this.editing) {
@@ -132,12 +136,18 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit {
           this.storageClassForm.get('zonegroup').disable();
           this.storageClassForm.get('placement_target').disable();
           this.storageClassForm.get('storage_class').disable();
+          if (
+            this.tierTargetInfo?.val?.tier_type === TIER_TYPE.CLOUD_TIER ||
+            this.tierTargetInfo?.val?.tier_type === TIER_TYPE.GLACIER
+          ) {
+            this.storageClassForm.get('storageClassType').disable();
+          }
           this.storageClassForm.patchValue({
             zonegroup: this.storageClassInfo?.zonegroup_name,
             region: response?.region,
             placement_target: this.storageClassInfo?.placement_target,
             storageClassType: this.tierTargetInfo?.val?.tier_type ?? TIER_TYPE.LOCAL,
-            endpoint: response?.endpoint,
+            target_endpoint: response?.endpoint,
             storage_class: this.storageClassInfo?.storage_class,
             access_key: response?.access_key,
             secret_key: response?.secret,
@@ -167,60 +177,52 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit {
   }
 
   private updateValidatorsBasedOnStorageClass(value: string) {
-    const controlsToUpdate = [
-      'region',
-      'endpoint',
-      'access_key',
-      'secret_key',
-      'target_path',
-      'glacier_restore_tier_type',
-      'restore_storage_class'
-    ];
-
-    controlsToUpdate.forEach((field) => {
+    GLACIER_REQUIRED_FIELDS.forEach((field) => {
       const control = this.storageClassForm.get(field);
 
       if (
-        (value === TIER_TYPE.CLOUD_TIER &&
-          ['region', 'endpoint', 'access_key', 'secret_key', 'target_path'].includes(field)) ||
-        (value === TIER_TYPE.GLACIER &&
-          [
-            'glacier_restore_tier_type',
-            'restore_storage_class',
-            'region',
-            'endpoint',
-            'access_key',
-            'secret_key',
-            'target_path'
-          ].includes(field))
+        (value === TIER_TYPE.CLOUD_TIER && CLOUD_TIER_REQUIRED_FIELDS.includes(field)) ||
+        (value === TIER_TYPE.GLACIER && GLACIER_REQUIRED_FIELDS.includes(field))
       ) {
         control.setValidators([Validators.required]);
       } else {
         control.clearValidators();
       }
-
       control.updateValueAndValidity();
     });
+
+    if (this.editing) {
+      const defaultValues = {
+        allow_read_through: false,
+        read_through_restore_days: STORAGE_CLASS_CONSTANTS.DEFAULT_READTHROUGH_RESTORE_DAYS,
+        restore_storage_class: STORAGE_CLASS_CONSTANTS.DEFAULT_STORAGE_CLASS,
+        multipart_min_part_size: STORAGE_CLASS_CONSTANTS.DEFAULT_MULTIPART_MIN_PART_SIZE,
+        multipart_sync_threshold: STORAGE_CLASS_CONSTANTS.DEFAULT_MULTIPART_SYNC_THRESHOLD
+      };
+      Object.keys(defaultValues).forEach((key) => {
+        this.storageClassForm.get(key).setValue(defaultValues[key]);
+      });
+    }
   }
 
   storageClassTypeText() {
     this.storageClassForm?.get('storageClassType')?.valueChanges.subscribe((value) => {
       if (value === TIER_TYPE.LOCAL) {
-        this.textLabels.storageClassText = LOCAL_STORAGE_CLASS_TEXT;
+        this.helpTextLabels.storageClassText = LOCAL_STORAGE_CLASS_TEXT;
       } else if (value === TIER_TYPE.CLOUD_TIER) {
-        this.textLabels.storageClassText = CLOUDS3_STORAGE_CLASS_TEXT;
+        this.helpTextLabels.storageClassText = CLOUDS3_STORAGE_CLASS_TEXT;
       } else if (value === TIER_TYPE.GLACIER) {
-        this.textLabels.storageClassText = GLACIER_STORAGE_CLASS_TEXT;
+        this.helpTextLabels.storageClassText = GLACIER_STORAGE_CLASS_TEXT;
       }
     });
   }
 
-  TierTypeText() {
+  updateTierTypeHelpText() {
     this.storageClassForm?.get('glacier_restore_tier_type')?.valueChanges.subscribe((value) => {
       if (value === STORAGE_CLASS_CONSTANTS.DEFAULT_STORAGE_CLASS) {
-        this.textLabels.tiertypeText = STANDARD_TIER_TYPE_TEXT;
+        this.helpTextLabels.tiertypeText = STANDARD_TIER_TYPE_TEXT;
       } else {
-        this.textLabels.tiertypeText = EXPEDITED_TIER_TYPE_TEXT;
+        this.helpTextLabels.tiertypeText = EXPEDITED_TIER_TYPE_TEXT;
       }
     });
   }
@@ -249,9 +251,9 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit {
       placement_target: new FormControl('', {
         validators: [Validators.required]
       }),
-      endpoint: new FormControl(null, [
-        CdValidators.composeIf({ storageClassType: TIER_TYPE.CLOUD_TIER }, [Validators.required])
-      ]),
+      target_endpoint: new FormControl(null, {
+        validators: [CdValidators.url, Validators.required]
+      }),
       access_key: new FormControl(null, [
         CdValidators.composeIf({ storageClassType: TIER_TYPE.CLOUD_TIER }, [Validators.required])
       ]),
@@ -384,7 +386,7 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit {
   }
 
   getTierTargetByStorageClass(placementTargetInfo: PlacementTarget, storageClass: string) {
-    const tierTarget = placementTargetInfo.tier_targets.find(
+    const tierTarget = placementTargetInfo?.tier_targets?.find(
       (target: TierTarget) => target.val.storage_class === storageClass
     );
     return tierTarget;
@@ -417,13 +419,21 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit {
     const placementId = this.storageClassForm.get('placement_target').value;
     const storageClassType = this.storageClassForm.get('storageClassType').value;
     const retain_head_object = this.storageClassForm.get('retain_head_object').value;
+    const multipart_min_part_size = this.formatter.toBytes(
+      this.storageClassForm.get('multipart_min_part_size').value
+    );
+    const multipart_sync_threshold = this.formatter.toBytes(
+      this.storageClassForm.get('multipart_sync_threshold').value
+    );
     return this.buildPlacementTargets(
       storageClassType,
       zoneGroup,
       placementId,
       storageClass,
       retain_head_object,
-      rawFormValue
+      rawFormValue,
+      multipart_sync_threshold,
+      multipart_min_part_size
     );
   }
 
@@ -433,7 +443,9 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit {
     placementId: string,
     storageClass: string,
     retain_head_object: boolean,
-    rawFormValue: any
+    rawFormValue: any,
+    multipart_sync_threshold: number,
+    multipart_min_part_size: number
   ): RequestModel {
     const baseTarget = {
       placement_id: placementId,
@@ -448,15 +460,15 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit {
     }
 
     const tierConfig = {
-      endpoint: rawFormValue.endpoint,
+      endpoint: rawFormValue.target_endpoint,
       access_key: rawFormValue.access_key,
       secret: rawFormValue.secret_key,
       target_path: rawFormValue.target_path,
       retain_head_object,
       allow_read_through: rawFormValue.allow_read_through,
       region: rawFormValue.region,
-      multipart_sync_threshold: rawFormValue.multipart_sync_threshold,
-      multipart_min_part_size: rawFormValue.multipart_min_part_size,
+      multipart_sync_threshold: multipart_sync_threshold,
+      multipart_min_part_size: multipart_min_part_size,
       restore_storage_class: rawFormValue.restore_storage_class,
       ...(rawFormValue.allow_read_through
         ? { read_through_restore_days: rawFormValue.read_through_restore_days }
index f8ddae11909c353a74820baefa1f8bd84fe812f6..fbe7dd9d48d0a35723e430ec94b4938b57ed8f33 100644 (file)
@@ -124,27 +124,11 @@ export class RgwStorageClassListComponent extends ListWithDetails implements OnI
         (data: ZoneGroupDetails) => {
           this.storageClassList = [];
           const tierObj = BucketTieringUtils.filterAndMapTierTargets(data);
-          const tierConfig = tierObj.map((item) => {
-            let tierTypeDisplay;
+          const tierConfig = tierObj.map((tier) => ({
+            ...tier,
+            tier_type: this.mapTierTypeDisplay(tier.tier_type)
+          }));
 
-            switch (item.tier_type?.toLowerCase()) {
-              case TIER_TYPE.CLOUD_TIER:
-                tierTypeDisplay = TIER_TYPE_DISPLAY.CLOUD_TIER;
-                break;
-              case TIER_TYPE.LOCAL:
-                tierTypeDisplay = TIER_TYPE_DISPLAY.LOCAL;
-                break;
-              case TIER_TYPE.GLACIER:
-                tierTypeDisplay = TIER_TYPE_DISPLAY.GLACIER;
-                break;
-              default:
-                tierTypeDisplay = item.tier_type;
-            }
-            return {
-              ...item,
-              tier_type: tierTypeDisplay
-            };
-          });
           this.transformTierData(tierConfig);
           this.storageClassList.push(...tierConfig);
           resolve();
@@ -156,6 +140,19 @@ export class RgwStorageClassListComponent extends ListWithDetails implements OnI
     });
   }
 
+  private mapTierTypeDisplay(tierType: string): string {
+    switch (tierType?.toLowerCase()) {
+      case TIER_TYPE.CLOUD_TIER:
+        return TIER_TYPE_DISPLAY.CLOUD_TIER;
+      case TIER_TYPE.LOCAL:
+        return TIER_TYPE_DISPLAY.LOCAL;
+      case TIER_TYPE.GLACIER:
+        return TIER_TYPE_DISPLAY.GLACIER;
+      default:
+        return tierType;
+    }
+  }
+
   transformTierData(tierConfig: any[]) {
     tierConfig.forEach((item, index) => {
       const zone_group = item?.zone_group;
index c075ed1d267b9ac368184b43d4826270d279d8d4..ba5bd46f9d040f6b92551e2f588e09c79a1b514d 100644 (file)
@@ -33,17 +33,12 @@ export class BucketTieringUtils {
   private static getTierTargets(tierTarget: TierTarget, zoneGroup: string, targetName: string) {
     const val = tierTarget.val;
     const tierType = val.tier_type;
-
     const commonProps = {
       zonegroup_name: zoneGroup,
       placement_target: targetName,
       storage_class: val.storage_class,
       tier_type: tierType
     };
-
-    if (!tierType || tierType === TIER_TYPE.LOCAL) {
-      return commonProps;
-    }
     const cloudProps = {
       ...commonProps,
       retain_head_object: val.retain_head_object,
@@ -53,6 +48,10 @@ export class BucketTieringUtils {
       ...val.s3
     };
 
+    if (!tierType || tierType === TIER_TYPE.LOCAL) {
+      return commonProps;
+    }
+
     if (tierType === TIER_TYPE.GLACIER) {
       return {
         ...cloudProps,
index 7ceb245e654cc78bac5000b59d4bf4d23c13c58b..6f9cf24699cf1fb0f125133528088a2e0ba5e054 100755 (executable)
@@ -2183,18 +2183,15 @@ class RgwMultisite:
                 '--placement-id', placement_target['placement_id']
             ]
             storage_class_name = placement_target.get('storage_class', None)
-            tier_type = placement_target.get('tier_type')
+            tier_type = placement_target.get('tier_type', None)
 
-            if (
-                placement_target.get('tier_type') == CLOUD_S3_TIER_TYPES
-                and storage_class_name != STANDARD_STORAGE_CLASS
-            ):
+            if tier_type in CLOUD_S3_TIER_TYPES and storage_class_name != STANDARD_STORAGE_CLASS:
                 tier_config = placement_target.get('tier_config', {})
                 if tier_config:
                     tier_config_items = self.modify_retain_head(tier_config)
                     tier_config_str = ','.join(tier_config_items)
                     cmd_add_placement_options += [
-                        '--tier-type', 'cloud-s3', '--tier-config', tier_config_str
+                        '--tier-type', tier_type, '--tier-config', tier_config_str
                     ]
 
             if placement_target.get('tags') and storage_class_name != STANDARD_STORAGE_CLASS: