Skip to content

Commit

Permalink
mgr/dashboard: disable delete on multisite
Browse files Browse the repository at this point in the history
Fixes: https://tracker.ceph.com/issues/59441
Signed-off-by: Pedro Gonzalez Gomez <pegonzal@redhat.com>
  • Loading branch information
Pegonzal committed May 16, 2023
1 parent 785f3ec commit 4b270e8
Show file tree
Hide file tree
Showing 11 changed files with 232 additions and 90 deletions.
4 changes: 2 additions & 2 deletions src/pybind/mgr/dashboard/controllers/rgw.py
Original file line number Diff line number Diff line change
Expand Up @@ -888,10 +888,10 @@ def get_all_zones_info(self):
except NoRgwDaemonsException as e:
raise DashboardException(e, http_status_code=404, component='rgw')

def delete(self, zonegroup_name, zone_name, delete_pools, daemon_name=None):
def delete(self, zone_name, delete_pools, zonegroup_name, daemon_name=None):
try:
instance = RgwClient.admin_instance(daemon_name)
result = instance.delete_zone(zonegroup_name, zone_name, delete_pools)
result = instance.delete_zone(zone_name, delete_pools, zonegroup_name)
return result
except NoRgwDaemonsException as e:
raise DashboardException(e, http_status_code=404, component='rgw')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,40 @@
<form name="zoneForm"
[formGroup]="zoneForm"
novalidate>
<div class="custom-control ms-4 mt-4">
<div class="modal-body ms-4">
<label i18n>
Do you want to delete all pools associated with it?</label>
<label class="mb-4"
i18n>
This will delete the following pools and any data stored in these pools:</label>
<ng-container *ngIf="zoneData$ | async as data">
<div id="scroll">
<ng-container *ngFor="let pool of data.placement_pools">
<strong>{{pool?.val.data_extra_pool}}</strong>
<strong>{{pool?.val.index_pool}}</strong>
<strong>{{pool?.val.storage_classes.STANDARD.data_pool}}</strong>
</ng-container>
This will delete your <strong>{{zone?.name}}</strong> Zone.
</label>
<ng-container *ngIf="includedPools.length">
<label class="mt-3"
i18n>
Do you want to delete the associated pools with the <strong>{{zone?.name}}</strong> Zone?</label>
<label class="mb-4"
i18n>
This will delete the following pools and any data stored in these pools:</label>
<strong *ngFor="let pool of includedPools"
class="block">{{ pool }}</strong>
<div class="form-group">
<div class="custom-control custom-checkbox mt-2">
<input type="checkbox"
class="custom-control-input"
name="deletePools"
id="deletePools"
formControlName="deletePools"
(change)="showDangerText()">
<label class="custom-control-label"
for="deletePools"
i18n>Yes, I want to delete the pools.</label>
</div>
<div *ngIf="displayText"
class="me-4">
<cd-alert-panel type="danger"
i18n>
This will delete all the data in the pools!
</cd-alert-panel>
</div>
</div>
</ng-container>
<div class="form-group">
<div class="custom-control custom-checkbox mt-2">
<input type="checkbox"
class="custom-control-input"
name="deletePools"
id="deletePools"
formControlName="deletePools"
(change)="showDangerText()">
<label class="custom-control-label"
for="deletePools"
i18n>Yes, I want to delete the pools.</label>
</div>
<div *ngIf="displayText"
class="me-4">
<cd-alert-panel type="danger"
i18n>
This will delete all the data in the pools!
</cd-alert-panel>
</div>
</div>
</div>

<div class="modal-footer">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
strong {
.block {
display: block;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { AfterViewInit, Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { PoolService } from '~/app/shared/api/pool.service';
import { RgwZoneService } from '~/app/shared/api/rgw-zone.service';
import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
import { NotificationType } from '~/app/shared/enum/notification-type.enum';
Expand All @@ -12,23 +13,31 @@ import { NotificationService } from '~/app/shared/services/notification.service'
templateUrl: './rgw-multisite-zone-deletion-form.component.html',
styleUrls: ['./rgw-multisite-zone-deletion-form.component.scss']
})
export class RgwMultisiteZoneDeletionFormComponent implements OnInit {
export class RgwMultisiteZoneDeletionFormComponent implements OnInit, AfterViewInit {
zoneData$: any;
poolList$: any;
zone: any;
zoneForm: CdFormGroup;
displayText: boolean = false;
includedPools: Array<string> = [];

constructor(
public activeModal: NgbActiveModal,
public actionLabels: ActionLabelsI18n,
public notificationService: NotificationService,
private rgwZoneService: RgwZoneService
private rgwZoneService: RgwZoneService,
private poolService: PoolService
) {
this.createForm();
}

ngOnInit(): void {
this.zoneData$ = this.rgwZoneService.get(this.zone);
this.poolList$ = this.poolService.getList();
}

ngAfterViewInit(): void {
this.updateIncludedPools();
}

createForm() {
Expand All @@ -39,7 +48,7 @@ export class RgwMultisiteZoneDeletionFormComponent implements OnInit {

submit() {
this.rgwZoneService
.delete(this.zone.parent, this.zone.name, this.zoneForm.value.deletePools)
.delete(this.zone.name, this.zoneForm.value.deletePools, this.zone.parent)
.subscribe(
() => {
this.notificationService.show(
Expand All @@ -57,4 +66,33 @@ export class RgwMultisiteZoneDeletionFormComponent implements OnInit {
showDangerText() {
this.displayText = !this.displayText;
}

updateIncludedPools(): void {
if (!this.zoneData$ || !this.poolList$) {
return;
}

this.zoneData$.subscribe((data: any) => {
this.poolList$.subscribe((poolList: any) => {
for (let pool of poolList) {
for (let zonePool of Object.values(data)) {
if (
typeof zonePool === 'string' &&
zonePool.includes(pool.pool_name) &&
!this.includedPools.includes(pool.pool_name)
) {
this.includedPools.push(pool.pool_name);
} else if (
Array.isArray(zonePool) &&
zonePool[0].val.storage_classes.STANDARD.data_pool &&
zonePool.includes(pool.pool_name) &&
!this.includedPools.includes(zonePool[0].val.storage_classes.STANDARD.data_pool)
) {
this.includedPools.push(zonePool[0].val.storage_classes.STANDARD.data_pool);
}
}
}
});
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,57 @@
<form name="zonegroupForm"
[formGroup]="zonegroupForm"
novalidate>
<div class="modal-body ms-4 mt-4">
<div class="modal-body ms-4">
<label i18n>
Are you sure that you want to delete the selected zonegroup and its zones?</label>
<label i18n>
This will delete the following zones and pools and any data stored in these pools:</label>
This will delete your <strong>{{zonegroup?.name}}</strong> Zonegroup.
</label>
<ng-container *ngIf="zonegroupData$ | async as data">
<strong class="mt-3 mb-2 h5">Zones:</strong>
<div id="scroll">
<strong *ngFor="let zone of data.zones">{{zone?.name}}</strong>
</div>
<strong class="mt-3 mb-2 h5">Pools:</strong>
<div id="scroll"
class="mb-2">
<ng-container *ngFor="let pool of data.placement_targets">
<strong *ngIf="pool.name !== 'default-placement'">{{pool?.name}}</strong>
<ng-container *ngIf="data.zones.length > 0">
<label class="mt-3"
i18n>
Do you want to delete the associated zones and pools with the <strong>{{zonegroup?.name}}</strong> Zonegroup?</label>
<ng-container *ngIf="includedPools.length > 0 else noPools">
<label i18n>
This will delete the following zones, pools and any data stored in these pools:</label>
</ng-container>
<strong class="mt-3 mb-2 h5 block">Zones:</strong>
<div id="scroll">
<strong *ngFor="let zone of data.zones"
class="block">{{zone?.name}}</strong>
</div>
<ng-container *ngIf="includedPools.length > 0">
<strong class="mt-3 mb-2 h5 block">Pools:</strong>
<div id="scroll"
class="mb-2">
<strong *ngFor="let pool of includedPools"
class="block">{{ pool }}</strong>
</div>
</ng-container>
</div>

<div class="form-group">
<div class="custom-control custom-checkbox mt-2">
<input type="checkbox"
class="custom-control-input"
name="deletePools"
id="deletePools"
formControlName="deletePools"
(change)="showDangerText()">
<ng-container *ngIf="includedPools.length > 0 else noPoolsConfirmation">
<label class="custom-control-label"
for="deletePools"
i18n>Yes, I want to delete the zones and their pools.</label>
</ng-container>
</div>
<div *ngIf="displayText"
class="me-4">
<cd-alert-panel type="danger"
i18n>
This will delete all the data in the pools!
</cd-alert-panel>
</div>
</div>
</ng-container>
</ng-container>
<div class="form-group">
<div class="custom-control custom-checkbox mt-2">
<input type="checkbox"
class="custom-control-input"
name="deletePools"
id="deletePools"
formControlName="deletePools"
(change)="showDangerText()">
<label class="custom-control-label"
for="deletePools"
i18n>Yes, I want to delete the zones and their pools.</label>
</div>
<div *ngIf="displayText"
class="me-4">
<cd-alert-panel type="danger"
i18n>
This will delete all the data in the pools!
</cd-alert-panel>
</div>
</div>
</div>

<div class="modal-footer">
Expand All @@ -56,3 +69,14 @@
</ng-container>

</cd-modal>

<ng-template #noPools>
<label i18n>
This will delete the following zones:</label>
</ng-template>

<ng-template #noPoolsConfirmation>
<label class="custom-control-label"
for="deletePools"
i18n>Yes, I want to delete the zones.</label>
</ng-template>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
strong {
.block {
display: block;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Component, OnInit } from '@angular/core';
import { AfterViewInit, Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { PoolService } from '~/app/shared/api/pool.service';
import { RgwZoneService } from '~/app/shared/api/rgw-zone.service';
import { RgwZonegroupService } from '~/app/shared/api/rgw-zonegroup.service';
import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
import { NotificationType } from '~/app/shared/enum/notification-type.enum';
Expand All @@ -12,23 +14,34 @@ import { NotificationService } from '~/app/shared/services/notification.service'
templateUrl: './rgw-multisite-zonegroup-deletion-form.component.html',
styleUrls: ['./rgw-multisite-zonegroup-deletion-form.component.scss']
})
export class RgwMultisiteZonegroupDeletionFormComponent implements OnInit {
export class RgwMultisiteZonegroupDeletionFormComponent implements OnInit, AfterViewInit {
zonegroupData$: any;
poolList$: any;
zonesPools: Array<any> = [];
zonegroup: any;
zonesList: Array<any> = [];
zonegroupForm: CdFormGroup;
displayText: boolean = false;
includedPools: Array<string> = [];

constructor(
public activeModal: NgbActiveModal,
public actionLabels: ActionLabelsI18n,
public notificationService: NotificationService,
private rgwZonegroupService: RgwZonegroupService
private rgwZonegroupService: RgwZonegroupService,
private poolService: PoolService,
private rgwZoneService: RgwZoneService
) {
this.createForm();
}

ngOnInit(): void {
this.zonegroupData$ = this.rgwZonegroupService.get(this.zonegroup);
this.poolList$ = this.poolService.getList();
}

ngAfterViewInit(): void {
this.updateIncludedPools();
}

createForm() {
Expand All @@ -50,6 +63,41 @@ export class RgwMultisiteZonegroupDeletionFormComponent implements OnInit {
}

showDangerText() {
this.displayText = !this.displayText;
if (this.includedPools.length > 0) {
this.displayText = !this.displayText;
}
}

updateIncludedPools(): void {
if (!this.zonegroupData$ || !this.poolList$) {
return;
}

this.zonegroupData$.subscribe((zgData: any) => {
for (let zone of zgData.zones) {
this.rgwZoneService.get(zone).subscribe((zonesPools: any) => {
this.poolList$.subscribe((poolList: any) => {
for (let zonePool of Object.values(zonesPools)) {
for (let pool of poolList) {
if (
typeof zonePool === 'string' &&
zonePool.includes(pool.pool_name) &&
!this.includedPools.includes(pool.pool_name)
) {
this.includedPools.push(pool.pool_name);
} else if (
Array.isArray(zonePool) &&
zonePool[0].val.storage_classes.STANDARD.data_pool &&
zonePool.includes(pool.pool_name) &&
!this.includedPools.includes(zonePool[0].val.storage_classes.STANDARD.data_pool)
) {
this.includedPools.push(zonePool[0].val.storage_classes.STANDARD.data_pool);
}
}
}
});
});
}
});
}
}

0 comments on commit 4b270e8

Please sign in to comment.