]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
91fe926518227d5cd21966c042fb2298cc23aa3f
[ceph-ci.git] /
1 import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
2
3 import { I18n } from '@ngx-translate/i18n-polyfill';
4 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
5 import { Subscription } from 'rxjs';
6
7 import { IscsiService } from '../../../shared/api/iscsi.service';
8 import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
9 import { TableComponent } from '../../../shared/datatable/table/table.component';
10 import { CellTemplate } from '../../../shared/enum/cell-template.enum';
11 import { CdTableAction } from '../../../shared/models/cd-table-action';
12 import { CdTableColumn } from '../../../shared/models/cd-table-column';
13 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
14 import { FinishedTask } from '../../../shared/models/finished-task';
15 import { Permissions } from '../../../shared/models/permissions';
16 import { CephReleaseNamePipe } from '../../../shared/pipes/ceph-release-name.pipe';
17 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
18 import { SummaryService } from '../../../shared/services/summary.service';
19 import { TaskListService } from '../../../shared/services/task-list.service';
20 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
21
22 @Component({
23   selector: 'cd-iscsi-target-list',
24   templateUrl: './iscsi-target-list.component.html',
25   styleUrls: ['./iscsi-target-list.component.scss'],
26   providers: [TaskListService]
27 })
28 export class IscsiTargetListComponent implements OnInit, OnDestroy {
29   @ViewChild(TableComponent)
30   table: TableComponent;
31
32   available: boolean = undefined;
33   columns: CdTableColumn[];
34   docsUrl: string;
35   modalRef: BsModalRef;
36   permissions: Permissions;
37   selection = new CdTableSelection();
38   settings: any;
39   status: string;
40   summaryDataSubscription: Subscription;
41   tableActions: CdTableAction[];
42   targets = [];
43
44   builders = {
45     'iscsi/target/create': (metadata) => {
46       return {
47         target_iqn: metadata['target_iqn']
48       };
49     }
50   };
51
52   constructor(
53     private authStorageService: AuthStorageService,
54     private i18n: I18n,
55     private iscsiService: IscsiService,
56     private taskListService: TaskListService,
57     private cephReleaseNamePipe: CephReleaseNamePipe,
58     private summaryservice: SummaryService,
59     private modalService: BsModalService,
60     private taskWrapper: TaskWrapperService
61   ) {
62     this.permissions = this.authStorageService.getPermissions();
63
64     this.tableActions = [
65       {
66         permission: 'create',
67         icon: 'fa-plus',
68         routerLink: () => '/block/iscsi/targets/add',
69         name: this.i18n('Add')
70       },
71       {
72         permission: 'delete',
73         icon: 'fa-times',
74         click: () => this.deleteIscsiTargetModal(),
75         name: this.i18n('Delete')
76       }
77     ];
78   }
79
80   ngOnInit() {
81     this.columns = [
82       {
83         name: this.i18n('Target'),
84         prop: 'target_iqn',
85         flexGrow: 2,
86         cellTransformation: CellTemplate.executing
87       },
88       {
89         name: this.i18n('Portals'),
90         prop: 'cdPortals',
91         flexGrow: 2
92       },
93       {
94         name: this.i18n('Images'),
95         prop: 'cdImages',
96         flexGrow: 2
97       }
98     ];
99
100     this.iscsiService.status().subscribe((result: any) => {
101       this.available = result.available;
102
103       if (result.available) {
104         this.taskListService.init(
105           () => this.iscsiService.listTargets(),
106           (resp) => this.prepareResponse(resp),
107           (targets) => (this.targets = targets),
108           () => this.onFetchError(),
109           this.taskFilter,
110           this.itemFilter,
111           this.builders
112         );
113
114         this.iscsiService.settings().subscribe((settings: any) => {
115           this.settings = settings;
116         });
117       } else {
118         const summary = this.summaryservice.getCurrentSummary();
119         const releaseName = this.cephReleaseNamePipe.transform(summary.version);
120         this.docsUrl = `http://docs.ceph.com/docs/${releaseName}/rbd/iscsi-targets/`;
121         this.status = result.message;
122       }
123     });
124   }
125
126   ngOnDestroy() {
127     if (this.summaryDataSubscription) {
128       this.summaryDataSubscription.unsubscribe();
129     }
130   }
131
132   prepareResponse(resp: any): any[] {
133     resp.forEach((element) => {
134       element.cdPortals = element.portals.map((portal) => `${portal.host}:${portal.ip}`);
135       element.cdImages = element.disks.map((disk) => `${disk.pool}/${disk.image}`);
136     });
137
138     return resp;
139   }
140
141   onFetchError() {
142     this.table.reset(); // Disable loading indicator.
143   }
144
145   itemFilter(entry, task) {
146     return entry.target_iqn === task.metadata['target_iqn'];
147   }
148
149   taskFilter(task) {
150     return ['iscsi/target/create', 'iscsi/target/delete'].includes(task.name);
151   }
152
153   updateSelection(selection: CdTableSelection) {
154     this.selection = selection;
155   }
156
157   deleteIscsiTargetModal() {
158     const target_iqn = this.selection.first().target_iqn;
159
160     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
161       initialState: {
162         itemDescription: this.i18n('iSCSI'),
163         submitActionObservable: () =>
164           this.taskWrapper.wrapTaskAroundCall({
165             task: new FinishedTask('iscsi/target/delete', {
166               target_iqn: target_iqn
167             }),
168             call: this.iscsiService.deleteTarget(target_iqn)
169           })
170       }
171     });
172   }
173 }