1 import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
3 import * as _ from 'lodash';
4 import { BsModalRef, BsModalService } from 'ngx-bootstrap';
6 import { RbdService } from '../../../shared/api/rbd.service';
7 import { ConfirmationModalComponent } from '../../../shared/components/confirmation-modal/confirmation-modal.component';
8 import { DeletionModalComponent } from '../../../shared/components/deletion-modal/deletion-modal.component';
9 import { CellTemplate } from '../../../shared/enum/cell-template.enum';
10 import { CdTableColumn } from '../../../shared/models/cd-table-column';
11 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
12 import { ExecutingTask } from '../../../shared/models/executing-task';
13 import { FinishedTask } from '../../../shared/models/finished-task';
14 import { Permission } from '../../../shared/models/permissions';
15 import { CdDatePipe } from '../../../shared/pipes/cd-date.pipe';
16 import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';
17 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
18 import { NotificationService } from '../../../shared/services/notification.service';
19 import { TaskManagerService } from '../../../shared/services/task-manager.service';
20 import { RbdSnapshotFormComponent } from '../rbd-snapshot-form/rbd-snapshot-form.component';
21 import { RbdSnapshotModel } from './rbd-snapshot.model';
24 selector: 'cd-rbd-snapshot-list',
25 templateUrl: './rbd-snapshot-list.component.html',
26 styleUrls: ['./rbd-snapshot-list.component.scss']
28 export class RbdSnapshotListComponent implements OnInit, OnChanges {
30 snapshots: RbdSnapshotModel[] = [];
36 executingTasks: ExecutingTask[] = [];
39 nameTpl: TemplateRef<any>;
40 @ViewChild('protectTpl')
41 protectTpl: TemplateRef<any>;
42 @ViewChild('rollbackTpl')
43 rollbackTpl: TemplateRef<any>;
45 permission: Permission;
47 data: RbdSnapshotModel[];
49 columns: CdTableColumn[];
53 selection = new CdTableSelection();
56 private authStorageService: AuthStorageService,
57 private modalService: BsModalService,
58 private dimlessBinaryPipe: DimlessBinaryPipe,
59 private cdDatePipe: CdDatePipe,
60 private rbdService: RbdService,
61 private taskManagerService: TaskManagerService,
62 private notificationService: NotificationService
64 this.permission = this.authStorageService.getPermissions().rbdImage;
72 cellTransformation: CellTemplate.executing,
79 cellClass: 'text-right',
80 pipe: this.dimlessBinaryPipe
86 cellClass: 'text-right',
87 pipe: this.dimlessBinaryPipe
93 cellClass: 'text-center',
94 cellTemplate: this.protectTpl
100 pipe: this.cdDatePipe
106 this.data = this.merge(this.snapshots, this.executingTasks);
109 private merge(snapshots: RbdSnapshotModel[], executingTasks: ExecutingTask[] = []) {
110 const resultSnapshots = _.clone(snapshots);
111 executingTasks.forEach((executingTask) => {
112 const snapshotExecuting = resultSnapshots.find((snapshot) => {
113 return snapshot.name === executingTask.metadata['snapshot_name'];
115 if (snapshotExecuting) {
116 if (executingTask.name === 'rbd/snap/delete') {
117 snapshotExecuting.cdExecuting = 'deleting';
118 } else if (executingTask.name === 'rbd/snap/edit') {
119 snapshotExecuting.cdExecuting = 'updating';
120 } else if (executingTask.name === 'rbd/snap/rollback') {
121 snapshotExecuting.cdExecuting = 'rolling back';
123 } else if (executingTask.name === 'rbd/snap/create') {
124 const rbdSnapshotModel = new RbdSnapshotModel();
125 rbdSnapshotModel.name = executingTask.metadata['snapshot_name'];
126 rbdSnapshotModel.cdExecuting = 'creating';
127 this.pushIfNotExists(resultSnapshots, rbdSnapshotModel);
130 return resultSnapshots;
133 private pushIfNotExists(resultSnapshots: RbdSnapshotModel[], rbdSnapshotModel: RbdSnapshotModel) {
134 const exists = resultSnapshots.some((resultSnapshot) => {
135 return resultSnapshot.name === rbdSnapshotModel.name;
138 resultSnapshots.push(rbdSnapshotModel);
142 private openSnapshotModal(taskName: string, oldSnapshotName: string = null) {
143 this.modalRef = this.modalService.show(RbdSnapshotFormComponent);
144 this.modalRef.content.poolName = this.poolName;
145 this.modalRef.content.imageName = this.rbdName;
146 if (oldSnapshotName) {
147 this.modalRef.content.setSnapName(this.selection.first().name);
149 this.modalRef.content.onSubmit.subscribe((snapshotName: string) => {
150 const executingTask = new ExecutingTask();
151 executingTask.name = taskName;
152 executingTask.metadata = { snapshot_name: snapshotName };
153 this.executingTasks.push(executingTask);
158 openCreateSnapshotModal() {
159 this.openSnapshotModal('rbd/snap/create');
162 openEditSnapshotModal() {
163 this.openSnapshotModal('rbd/snap/edit', this.selection.first().name);
167 const snapshotName = this.selection.first().name;
168 const isProtected = this.selection.first().is_protected;
169 const finishedTask = new FinishedTask();
170 finishedTask.name = 'rbd/snap/edit';
171 finishedTask.metadata = {
172 pool_name: this.poolName,
173 image_name: this.rbdName,
174 snapshot_name: snapshotName
177 .protectSnapshot(this.poolName, this.rbdName, snapshotName, !isProtected)
180 const executingTask = new ExecutingTask();
181 executingTask.name = finishedTask.name;
182 executingTask.metadata = finishedTask.metadata;
183 this.executingTasks.push(executingTask);
185 this.taskManagerService.subscribe(
187 finishedTask.metadata,
188 (asyncFinishedTask: FinishedTask) => {
189 this.notificationService.notifyTask(asyncFinishedTask);
195 _asyncTask(task: string, taskName: string, snapshotName: string) {
196 const finishedTask = new FinishedTask();
197 finishedTask.name = taskName;
198 finishedTask.metadata = {
199 pool_name: this.poolName,
200 image_name: this.rbdName,
201 snapshot_name: snapshotName
203 this.rbdService[task](this.poolName, this.rbdName, snapshotName)
206 const executingTask = new ExecutingTask();
207 executingTask.name = finishedTask.name;
208 executingTask.metadata = finishedTask.metadata;
209 this.executingTasks.push(executingTask);
210 this.modalRef.hide();
212 this.taskManagerService.subscribe(
214 executingTask.metadata,
215 (asyncFinishedTask: FinishedTask) => {
216 this.notificationService.notifyTask(asyncFinishedTask);
221 this.modalRef.content.stopLoadingSpinner();
226 const snapshotName = this.selection.selected[0].name;
227 const initialState = {
228 titleText: 'RBD snapshot rollback',
229 buttonText: 'Rollback',
230 bodyTpl: this.rollbackTpl,
232 snapName: `${this.poolName}/${this.rbdName}@${snapshotName}`
235 this._asyncTask('rollbackSnapshot', 'rbd/snap/rollback', snapshotName);
239 this.modalRef = this.modalService.show(ConfirmationModalComponent, { initialState });
242 deleteSnapshotModal() {
243 const snapshotName = this.selection.selected[0].name;
244 this.modalRef = this.modalService.show(DeletionModalComponent);
245 this.modalRef.content.setUp({
246 metaType: 'RBD snapshot',
247 pattern: snapshotName,
248 deletionMethod: () => this._asyncTask('deleteSnapshot', 'rbd/snap/delete', snapshotName),
249 modalRef: this.modalRef
253 updateSelection(selection: CdTableSelection) {
254 this.selection = selection;