Skip to content

Commit e2b2e03

Browse files
authored
Merge pull request ceph#55494 from ivoalmeida/snapshot-schedule-delete-activate
mgr/dashboard: added delete and activation actions Reviewed-by: afreen23 <NOT@FOUND> Reviewed-by: Ankush Behl <[email protected]> Reviewed-by: Nizamudeen A <[email protected]>
2 parents 6c275ab + e0bb711 commit e2b2e03

File tree

7 files changed

+357
-22
lines changed

7 files changed

+357
-22
lines changed

src/pybind/mgr/dashboard/controllers/cephfs.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,3 +1025,54 @@ def editRetentionPolicies(method, retention_policy):
10251025
editRetentionPolicies('snap_schedule_retention_add', retention_to_add)
10261026

10271027
return f'Retention policies for snapshot schedule on path {path} updated successfully'
1028+
1029+
@RESTController.Resource('DELETE')
1030+
def delete_snapshot(self, fs: str, path: str, schedule: str, start: str):
1031+
error_code, _, err = mgr.remote('snap_schedule',
1032+
'snap_schedule_rm',
1033+
path,
1034+
schedule,
1035+
start,
1036+
fs,
1037+
None,
1038+
None)
1039+
if error_code != 0:
1040+
raise DashboardException(
1041+
f'Failed to delete snapshot schedule for path {path}: {err}'
1042+
)
1043+
1044+
return f'Snapshot schedule for path {path} deleted successfully'
1045+
1046+
@RESTController.Resource('POST')
1047+
def deactivate(self, fs: str, path: str, schedule: str, start: str):
1048+
error_code, _, err = mgr.remote('snap_schedule',
1049+
'snap_schedule_deactivate',
1050+
path,
1051+
schedule,
1052+
start,
1053+
fs,
1054+
None,
1055+
None)
1056+
if error_code != 0:
1057+
raise DashboardException(
1058+
f'Failed to deactivate snapshot schedule for path {path}: {err}'
1059+
)
1060+
1061+
return f'Snapshot schedule for path {path} deactivated successfully'
1062+
1063+
@RESTController.Resource('POST')
1064+
def activate(self, fs: str, path: str, schedule: str, start: str):
1065+
error_code, _, err = mgr.remote('snap_schedule',
1066+
'snap_schedule_activate',
1067+
path,
1068+
schedule,
1069+
start,
1070+
fs,
1071+
None,
1072+
None)
1073+
if error_code != 0:
1074+
raise DashboardException(
1075+
f'Failed to activate snapshot schedule for path {path}: {err}'
1076+
)
1077+
1078+
return f'Snapshot schedule for path {path} activated successfully'

src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-snapshotschedule-list/cephfs-snapshotschedule-list.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
[permission]="permissions.cephfs"
7474
[selection]="selection"
7575
class="btn-group"
76-
[tableActions]="tableActions"
76+
[tableActions]="tableActions$ | async"
7777
>
7878
</cd-table-actions>
7979
</div>

src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-snapshotschedule-list/cephfs-snapshotschedule-list.component.ts

Lines changed: 103 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@ import { MgrModuleService } from '~/app/shared/api/mgr-module.service';
2626
import { NotificationService } from '~/app/shared/services/notification.service';
2727
import { BlockUI, NgBlockUI } from 'ng-block-ui';
2828
import { NotificationType } from '~/app/shared/enum/notification-type.enum';
29-
import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
29+
import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
3030
import { CephfsSnapshotscheduleFormComponent } from '../cephfs-snapshotschedule-form/cephfs-snapshotschedule-form.component';
31+
import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
32+
import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
33+
import { FinishedTask } from '~/app/shared/models/finished-task';
3134

3235
@Component({
3336
selector: 'cd-cephfs-snapshotschedule-list',
@@ -51,14 +54,34 @@ export class CephfsSnapshotscheduleListComponent
5154
snapScheduleModuleStatus$ = new BehaviorSubject<boolean>(false);
5255
moduleServiceListSub!: Subscription;
5356
columns: CdTableColumn[] = [];
54-
tableActions: CdTableAction[] = [];
57+
tableActions$ = new BehaviorSubject<CdTableAction[]>([]);
5558
context!: CdTableFetchDataContext;
5659
selection = new CdTableSelection();
5760
permissions!: Permissions;
5861
modalRef!: NgbModalRef;
5962
errorMessage: string = '';
6063
selectedName: string = '';
6164
icons = Icons;
65+
tableActions: CdTableAction[] = [
66+
{
67+
name: this.actionLabels.CREATE,
68+
permission: 'create',
69+
icon: Icons.add,
70+
click: () => this.openModal(false)
71+
},
72+
{
73+
name: this.actionLabels.EDIT,
74+
permission: 'update',
75+
icon: Icons.edit,
76+
click: () => this.openModal(true)
77+
},
78+
{
79+
name: this.actionLabels.DELETE,
80+
permission: 'delete',
81+
icon: Icons.trash,
82+
click: () => this.deleteSnapshotSchedule()
83+
}
84+
];
6285

6386
MODULE_NAME = 'snap_schedule';
6487
ENABLE_MODULE_TIMER = 2 * 1000;
@@ -69,7 +92,8 @@ export class CephfsSnapshotscheduleListComponent
6992
private modalService: ModalService,
7093
private mgrModuleService: MgrModuleService,
7194
private notificationService: NotificationService,
72-
private actionLables: ActionLabelsI18n
95+
private actionLabels: ActionLabelsI18n,
96+
private taskWrapper: TaskWrapperService
7397
) {
7498
super();
7599
this.permissions = this.authStorageService.getPermissions();
@@ -116,20 +140,7 @@ export class CephfsSnapshotscheduleListComponent
116140
{ prop: 'created', name: $localize`Created`, cellTransformation: CellTemplate.timeAgo }
117141
];
118142

119-
this.tableActions = [
120-
{
121-
name: this.actionLables.CREATE,
122-
permission: 'create',
123-
icon: Icons.add,
124-
click: () => this.openModal(false)
125-
},
126-
{
127-
name: this.actionLables.EDIT,
128-
permission: 'update',
129-
icon: Icons.edit,
130-
click: () => this.openModal(true)
131-
}
132-
];
143+
this.tableActions$.next(this.tableActions);
133144
}
134145

135146
ngOnDestroy(): void {
@@ -142,6 +153,19 @@ export class CephfsSnapshotscheduleListComponent
142153

143154
updateSelection(selection: CdTableSelection) {
144155
this.selection = selection;
156+
if (!this.selection.hasSelection) return;
157+
const isActive = this.selection.first()?.active;
158+
159+
this.tableActions$.next([
160+
...this.tableActions,
161+
{
162+
name: isActive ? this.actionLabels.DEACTIVATE : this.actionLabels.ACTIVATE,
163+
permission: 'update',
164+
icon: isActive ? Icons.warning : Icons.success,
165+
click: () =>
166+
isActive ? this.deactivateSnapshotSchedule() : this.activateSnapshotSchedule()
167+
}
168+
]);
145169
}
146170

147171
openModal(edit = false) {
@@ -204,4 +228,66 @@ export class CephfsSnapshotscheduleListComponent
204228
}
205229
);
206230
}
231+
232+
deactivateSnapshotSchedule() {
233+
const { path, start, fs, schedule } = this.selection.first();
234+
235+
this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
236+
itemDescription: $localize`snapshot schedule`,
237+
actionDescription: this.actionLabels.DEACTIVATE,
238+
submitActionObservable: () =>
239+
this.taskWrapper.wrapTaskAroundCall({
240+
task: new FinishedTask('cephfs/snapshot/schedule/deactivate', {
241+
path
242+
}),
243+
call: this.snapshotScheduleService.deactivate({
244+
path,
245+
schedule,
246+
start,
247+
fs
248+
})
249+
})
250+
});
251+
}
252+
253+
activateSnapshotSchedule() {
254+
const { path, start, fs, schedule } = this.selection.first();
255+
256+
this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
257+
itemDescription: $localize`snapshot schedule`,
258+
actionDescription: this.actionLabels.ACTIVATE,
259+
submitActionObservable: () =>
260+
this.taskWrapper.wrapTaskAroundCall({
261+
task: new FinishedTask('cephfs/snapshot/schedule/activate', {
262+
path
263+
}),
264+
call: this.snapshotScheduleService.activate({
265+
path,
266+
schedule,
267+
start,
268+
fs
269+
})
270+
})
271+
});
272+
}
273+
274+
deleteSnapshotSchedule() {
275+
const { path, start, fs, schedule } = this.selection.first();
276+
277+
this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
278+
itemDescription: $localize`snapshot schedule`,
279+
submitActionObservable: () =>
280+
this.taskWrapper.wrapTaskAroundCall({
281+
task: new FinishedTask('cephfs/snapshot/schedule/' + URLVerbs.DELETE, {
282+
path
283+
}),
284+
call: this.snapshotScheduleService.delete({
285+
path,
286+
schedule,
287+
start,
288+
fs
289+
})
290+
})
291+
});
292+
}
207293
}

src/pybind/mgr/dashboard/frontend/src/app/shared/api/cephfs-snapshot-schedule.service.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,38 @@ export class CephfsSnapshotScheduleService {
1919
return this.http.post(`${this.baseURL}/snapshot/schedule`, data, { observe: 'response' });
2020
}
2121

22-
update(data: Record<string, any>): Observable<any> {
22+
update({ fs, path, ...rest }: Record<string, any>): Observable<any> {
2323
return this.http.put(
24-
`${this.baseURL}/snapshot/schedule/${data.fs}/${encodeURIComponent(data.path)}`,
25-
data,
24+
`${this.baseURL}/snapshot/schedule/${fs}/${encodeURIComponent(path)}`,
25+
rest,
2626
{ observe: 'response' }
2727
);
2828
}
2929

30+
activate({ fs, path, ...rest }: Record<string, any>): Observable<any> {
31+
return this.http.post(
32+
`${this.baseURL}/snapshot/schedule/${fs}/${encodeURIComponent(path)}/activate`,
33+
rest,
34+
{ observe: 'response' }
35+
);
36+
}
37+
38+
deactivate({ fs, path, ...rest }: Record<string, any>): Observable<any> {
39+
return this.http.post(
40+
`${this.baseURL}/snapshot/schedule/${fs}/${encodeURIComponent(path)}/deactivate`,
41+
rest,
42+
{ observe: 'response' }
43+
);
44+
}
45+
46+
delete({ fs, path, schedule, start }: Record<string, any>): Observable<any> {
47+
return this.http.delete(
48+
`${this.baseURL}/snapshot/schedule/${fs}/${encodeURIComponent(
49+
path
50+
)}/delete_snapshot?schedule=${schedule}&start=${encodeURIComponent(start)}`
51+
);
52+
}
53+
3054
checkScheduleExists(
3155
path: string,
3256
fs: string,

src/pybind/mgr/dashboard/frontend/src/app/shared/constants/app.constants.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ export class ActionLabelsI18n {
141141
IMPORT: any;
142142
MIGRATE: string;
143143
START_UPGRADE: string;
144+
ACTIVATE: string;
145+
DEACTIVATE: string;
144146

145147
constructor() {
146148
/* Create a new item */
@@ -218,6 +220,9 @@ export class ActionLabelsI18n {
218220
this.DEMOTE = $localize`Demote`;
219221

220222
this.START_UPGRADE = $localize`Start Upgrade`;
223+
224+
this.ACTIVATE = $localize`Activate`;
225+
this.DEACTIVATE = $localize`Deactivate`;
221226
}
222227
}
223228

src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,17 @@ export class TaskMessageService {
6969
delete: new TaskMessageOperation($localize`Deleting`, $localize`delete`, $localize`Deleted`),
7070
add: new TaskMessageOperation($localize`Adding`, $localize`add`, $localize`Added`),
7171
remove: new TaskMessageOperation($localize`Removing`, $localize`remove`, $localize`Removed`),
72-
import: new TaskMessageOperation($localize`Importing`, $localize`import`, $localize`Imported`)
72+
import: new TaskMessageOperation($localize`Importing`, $localize`import`, $localize`Imported`),
73+
activate: new TaskMessageOperation(
74+
$localize`Importing`,
75+
$localize`activate`,
76+
$localize`Activated`
77+
),
78+
deactivate: new TaskMessageOperation(
79+
$localize`Importing`,
80+
$localize`deactivate`,
81+
$localize`Deactivated`
82+
)
7383
};
7484

7585
rbd = {
@@ -393,6 +403,18 @@ export class TaskMessageService {
393403
),
394404
'cephfs/snapshot/schedule/edit': this.newTaskMessage(this.commonOperations.update, (metadata) =>
395405
this.snapshotSchedule(metadata)
406+
),
407+
'cephfs/snapshot/schedule/delete': this.newTaskMessage(
408+
this.commonOperations.delete,
409+
(metadata) => this.snapshotSchedule(metadata)
410+
),
411+
'cephfs/snapshot/schedule/activate': this.newTaskMessage(
412+
this.commonOperations.activate,
413+
(metadata) => this.snapshotSchedule(metadata)
414+
),
415+
'cephfs/snapshot/schedule/deactivate': this.newTaskMessage(
416+
this.commonOperations.deactivate,
417+
(metadata) => this.snapshotSchedule(metadata)
396418
)
397419
};
398420

0 commit comments

Comments
 (0)