import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
import {
+ AllZonesResponse,
StorageClass,
TIER_TYPE,
TIER_TYPE_DISPLAY,
import { FinishedTask } from '~/app/shared/models/finished-task';
import { Icons } from '~/app/shared/enum/icons.enum';
import { RgwZonegroupService } from '~/app/shared/api/rgw-zonegroup.service';
+import { RgwZoneService } from '~/app/shared/api/rgw-zone.service';
import { DeleteConfirmationModalComponent } from '~/app/shared/components/delete-confirmation-modal/delete-confirmation-modal.component';
import { ModalCdsService } from '~/app/shared/services/modal-cds.service';
import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
import { Permission } from '~/app/shared/models/permissions';
import { BucketTieringUtils } from '../utils/rgw-bucket-tiering';
import { Router } from '@angular/router';
-import { Observable, Subscriber } from 'rxjs';
import { TableComponent } from '~/app/shared/datatable/table/table.component';
+import { finalize, switchMap } from 'rxjs/operators';
const BASE_URL = 'rgw/storage-class';
@Component({
constructor(
private rgwZonegroupService: RgwZonegroupService,
+ private rgwZoneService: RgwZoneService,
public actionLabels: ActionLabelsI18n,
private cdsModalService: ModalCdsService,
private taskWrapper: TaskWrapperService,
const tierObj = BucketTieringUtils.filterAndMapTierTargets(data);
const tierConfig = tierObj.map((tier) => ({
...tier,
- tier_type: this.mapTierTypeDisplay(tier.tier_type)
+ tier_type: this.mapTierTypeDisplay(tier.tier_type),
+ storageClass: tier.storage_class,
+ placementTarget: tier.placement_target,
+ tierType: this.mapTierTypeDisplay(tier.tier_type)
}));
this.transformTierData(tierConfig);
}
removeStorageClassModal() {
- const storage_class = this.selection.first().storage_class;
- const placement_target = this.selection.first().placement_target;
+ const selectedItem = this.selection.first();
+ const { storageClass, placementTarget, tierType } = selectedItem;
+ const isLocalStorageClass =
+ tierType?.toLowerCase() === TIER_TYPE.LOCAL || tierType === TIER_TYPE_DISPLAY.LOCAL;
+
this.cdsModalService.show(DeleteConfirmationModalComponent, {
itemDescription: $localize`Storage class`,
- itemNames: [storage_class],
+ itemNames: [storageClass],
actionDescription: 'remove',
submitActionObservable: () => {
- return new Observable((observer: Subscriber<any>) => {
- this.taskWrapper
- .wrapTaskAroundCall({
- task: new FinishedTask('rgw/zonegroup/storage-class', {
- placement_target: placement_target,
- storage_class: storage_class
- }),
- call: this.rgwStorageClassService.removeStorageClass(placement_target, storage_class)
- })
- .subscribe({
- error: (error: any) => {
- observer.error(error);
- },
- complete: () => {
- observer.complete();
- this.table.refreshBtn();
- }
- });
- });
+ // For local storage classes, delete from both zone and zonegroup
+ const deleteObservable$ = isLocalStorageClass
+ ? this.rgwZoneService.getAllZonesInfo().pipe(
+ switchMap((data: AllZonesResponse) => {
+ const zoneInfo = BucketTieringUtils.getZoneInfoHelper(data.zones, selectedItem);
+ return this.rgwStorageClassService.removeStorageClass(
+ placementTarget,
+ storageClass,
+ zoneInfo.zone_name || ''
+ );
+ })
+ )
+ : this.rgwStorageClassService.removeStorageClass(placementTarget, storageClass);
+
+ return this.taskWrapper
+ .wrapTaskAroundCall({
+ task: new FinishedTask('rgw/zonegroup/storage-class', {
+ placementTarget,
+ storageClass
+ }),
+ call: deleteObservable$
+ })
+ .pipe(finalize(() => this.table.refreshBtn()));
}
});
}
if tier_type in CLOUD_S3_TIER_TYPES:
self.ensure_realm_and_sync_period()
- def delete_placement_targets(self, placement_id: str, storage_class: str):
+ def delete_placement_targets(self, placement_id: str, storage_class: str,
+ zone_name: str = ''):
+ # Delete from zone first if zone_name is provided
+ if zone_name:
+ rgw_zone_delete_cmd = ['zone', 'placement', 'rm', '--rgw-zone', zone_name,
+ '--placement-id', placement_id,
+ '--storage-class', storage_class]
+
+ try:
+ exit_code, _, err = mgr.send_rgwadmin_command(rgw_zone_delete_cmd)
+ if exit_code > 0:
+ raise DashboardException(
+ e=err,
+ msg=(f'Unable to delete placement {placement_id} '
+ f'with storage-class {storage_class} from zone {zone_name}'),
+ http_status_code=500,
+ component='rgw'
+ )
+ except SubprocessError as error:
+ raise DashboardException(error, http_status_code=500, component='rgw')
+
+ # Delete from zonegroup
rgw_zonegroup_delete_cmd = ['zonegroup', 'placement', 'rm',
'--placement-id', placement_id,
'--storage-class', storage_class]