]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
07499f34848994158383fc41c1abd4c27f97cfdd
[ceph-ci.git] /
1 import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
2
3 import { I18n } from '@ngx-translate/i18n-polyfill';
4 import * as _ from 'lodash';
5 import { NodeEvent, TreeModel } from 'ng2-tree';
6
7 import { TableComponent } from '../../../shared/datatable/table/table.component';
8 import { Icons } from '../../../shared/enum/icons.enum';
9 import { CdTableColumn } from '../../../shared/models/cd-table-column';
10 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
11 import { IscsiBackstorePipe } from '../../../shared/pipes/iscsi-backstore.pipe';
12
13 @Component({
14   selector: 'cd-iscsi-target-details',
15   templateUrl: './iscsi-target-details.component.html',
16   styleUrls: ['./iscsi-target-details.component.scss']
17 })
18 export class IscsiTargetDetailsComponent implements OnChanges, OnInit {
19   @Input()
20   selection: CdTableSelection;
21   @Input()
22   settings: any;
23
24   @ViewChild('highlightTpl')
25   highlightTpl: TemplateRef<any>;
26
27   private detailTable: TableComponent;
28   @ViewChild('detailTable')
29   set content(content: TableComponent) {
30     this.detailTable = content;
31     if (content) {
32       content.updateColumns();
33     }
34   }
35
36   columns: CdTableColumn[];
37   data: any;
38   metadata: any = {};
39   selectedItem: any;
40   title: string;
41   tree: TreeModel;
42
43   constructor(private i18n: I18n, private iscsiBackstorePipe: IscsiBackstorePipe) {}
44
45   ngOnInit() {
46     this.columns = [
47       {
48         prop: 'displayName',
49         name: this.i18n('Name'),
50         flexGrow: 2,
51         cellTemplate: this.highlightTpl
52       },
53       {
54         prop: 'current',
55         name: this.i18n('Current'),
56         flexGrow: 1,
57         cellTemplate: this.highlightTpl
58       },
59       {
60         prop: 'default',
61         name: this.i18n('Default'),
62         flexGrow: 1,
63         cellTemplate: this.highlightTpl
64       }
65     ];
66   }
67
68   ngOnChanges() {
69     if (this.selection.hasSelection) {
70       this.selectedItem = this.selection.first();
71       this.generateTree();
72     }
73
74     this.data = undefined;
75   }
76
77   private generateTree() {
78     this.metadata = { root: this.selectedItem.target_controls };
79     const cssClasses = {
80       target: {
81         expanded: _.join([Icons.large, Icons.bullseye], ' ')
82       },
83       initiators: {
84         expanded: _.join([Icons.large, Icons.user], ' '),
85         leaf: _.join([Icons.user], ' ')
86       },
87       groups: {
88         expanded: _.join([Icons.large, Icons.user], ' '),
89         leaf: _.join([Icons.user], ' ')
90       },
91       disks: {
92         expanded: _.join([Icons.large, Icons.disk], ' '),
93         leaf: _.join([Icons.disk], ' ')
94       },
95       portals: {
96         expanded: _.join([Icons.large, Icons.server], ' '),
97         leaf: _.join([Icons.large, Icons.server], ' ')
98       }
99     };
100
101     const disks = [];
102     _.forEach(this.selectedItem.disks, (disk) => {
103       const id = 'disk_' + disk.pool + '_' + disk.image;
104       this.metadata[id] = {
105         controls: disk.controls,
106         backstore: disk.backstore
107       };
108
109       disks.push({
110         value: `${disk.pool}/${disk.image}`,
111         id: id
112       });
113     });
114
115     const portals = [];
116     _.forEach(this.selectedItem.portals, (portal) => {
117       portals.push({ value: `${portal.host}:${portal.ip}` });
118     });
119
120     const clients = [];
121     _.forEach(this.selectedItem.clients, (client) => {
122       const client_metadata = _.cloneDeep(client.auth);
123       _.extend(client_metadata, client.info);
124       delete client_metadata['state'];
125       _.forEach(Object.keys(client.info.state), (state) => {
126         client_metadata[state.toLowerCase()] = client.info.state[state];
127       });
128       this.metadata['client_' + client.client_iqn] = client_metadata;
129
130       const luns = [];
131       client.luns.forEach((lun) => {
132         luns.push({
133           value: `${lun.pool}/${lun.image}`,
134           id: 'disk_' + lun.pool + '_' + lun.image,
135           settings: {
136             cssClasses: cssClasses.disks
137           }
138         });
139       });
140
141       clients.push({
142         value: client.client_iqn,
143         status: Object.keys(client.info.state).includes('LOGGED_IN') ? 'logged_in' : 'logged_out',
144         id: 'client_' + client.client_iqn,
145         children: luns
146       });
147     });
148
149     const groups = [];
150     _.forEach(this.selectedItem.groups, (group) => {
151       const luns = [];
152       group.disks.forEach((disk) => {
153         luns.push({
154           value: `${disk.pool}/${disk.image}`,
155           id: 'disk_' + disk.pool + '_' + disk.image
156         });
157       });
158
159       const initiators = [];
160       group.members.forEach((member) => {
161         initiators.push({
162           value: member,
163           id: 'client_' + member
164         });
165       });
166
167       groups.push({
168         value: group.group_id,
169         children: [
170           {
171             value: 'Disks',
172             children: luns,
173             settings: {
174               selectionAllowed: false,
175               cssClasses: cssClasses.disks
176             }
177           },
178           {
179             value: 'Initiators',
180             children: initiators,
181             settings: {
182               selectionAllowed: false,
183               cssClasses: cssClasses.initiators
184             }
185           }
186         ]
187       });
188     });
189
190     this.tree = {
191       value: this.selectedItem.target_iqn,
192       id: 'root',
193       settings: {
194         static: true,
195         cssClasses: cssClasses.target
196       },
197       children: [
198         {
199           value: 'Disks',
200           children: disks,
201           settings: {
202             selectionAllowed: false,
203             cssClasses: cssClasses.disks
204           }
205         },
206         {
207           value: 'Portals',
208           children: portals,
209           settings: {
210             selectionAllowed: false,
211             cssClasses: cssClasses.portals
212           }
213         },
214         {
215           value: 'Initiators',
216           children: clients,
217           settings: {
218             selectionAllowed: false,
219             cssClasses: cssClasses.initiators
220           }
221         },
222         {
223           value: 'Groups',
224           children: groups,
225           settings: {
226             selectionAllowed: false,
227             cssClasses: cssClasses.groups
228           }
229         }
230       ]
231     };
232   }
233
234   onNodeSelected(e: NodeEvent) {
235     if (e.node.id) {
236       this.title = e.node.value;
237       const tempData = this.metadata[e.node.id] || {};
238
239       if (e.node.id === 'root') {
240         this.columns[2].isHidden = false;
241         this.data = _.map(this.settings.target_default_controls, (value, key) => {
242           return {
243             displayName: key,
244             default: value,
245             current: tempData[key] || value
246           };
247         });
248       } else if (e.node.id.toString().startsWith('disk_')) {
249         this.columns[2].isHidden = false;
250         this.data = _.map(this.settings.disk_default_controls[tempData.backstore], (value, key) => {
251           return {
252             displayName: key,
253             default: value,
254             current: !_.isUndefined(tempData.controls[key]) ? tempData.controls[key] : value
255           };
256         });
257         this.data.push({
258           displayName: 'backstore',
259           default: this.iscsiBackstorePipe.transform(this.settings.default_backstore),
260           current: this.iscsiBackstorePipe.transform(tempData.backstore)
261         });
262       } else {
263         this.columns[2].isHidden = true;
264         this.data = _.map(tempData, (value, key) => {
265           return {
266             displayName: key,
267             default: undefined,
268             current: value
269           };
270         });
271       }
272     } else {
273       this.data = undefined;
274     }
275
276     if (this.detailTable) {
277       this.detailTable.updateColumns();
278     }
279   }
280 }