]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
b4e482a8fa5a6a531be2a54e658239810b2bbeb5
[ceph.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 { CdTableColumn } from '../../../shared/models/cd-table-column';
9 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
10 import { IscsiBackstorePipe } from '../../../shared/pipes/iscsi-backstore.pipe';
11
12 @Component({
13   selector: 'cd-iscsi-target-details',
14   templateUrl: './iscsi-target-details.component.html',
15   styleUrls: ['./iscsi-target-details.component.scss']
16 })
17 export class IscsiTargetDetailsComponent implements OnChanges, OnInit {
18   @Input()
19   selection: CdTableSelection;
20   @Input()
21   settings: any;
22
23   @ViewChild('highlightTpl')
24   highlightTpl: TemplateRef<any>;
25
26   private detailTable: TableComponent;
27   @ViewChild('detailTable')
28   set content(content: TableComponent) {
29     this.detailTable = content;
30     if (content) {
31       content.updateColumns();
32     }
33   }
34
35   columns: CdTableColumn[];
36   data: any;
37   metadata: any = {};
38   selectedItem: any;
39   title: string;
40   tree: TreeModel;
41
42   constructor(private i18n: I18n, private iscsiBackstorePipe: IscsiBackstorePipe) {}
43
44   ngOnInit() {
45     this.columns = [
46       {
47         prop: 'displayName',
48         name: this.i18n('Name'),
49         flexGrow: 2,
50         cellTemplate: this.highlightTpl
51       },
52       {
53         prop: 'current',
54         name: this.i18n('Current'),
55         flexGrow: 1,
56         cellTemplate: this.highlightTpl
57       },
58       {
59         prop: 'default',
60         name: this.i18n('Default'),
61         flexGrow: 1,
62         cellTemplate: this.highlightTpl
63       }
64     ];
65   }
66
67   ngOnChanges() {
68     if (this.selection.hasSelection) {
69       this.selectedItem = this.selection.first();
70       this.generateTree();
71     }
72
73     this.data = undefined;
74   }
75
76   private generateTree() {
77     this.metadata = { root: this.selectedItem.target_controls };
78
79     const cssClasses = {
80       target: {
81         expanded: 'fa fa-fw fa-bullseye fa-lg'
82       },
83       initiators: {
84         expanded: 'fa fa-fw fa-user fa-lg',
85         leaf: 'fa fa-fw fa-user'
86       },
87       groups: {
88         expanded: 'fa fa-fw fa-users fa-lg',
89         leaf: 'fa fa-fw fa-users'
90       },
91       disks: {
92         expanded: 'fa fa-fw fa-hdd-o fa-lg',
93         leaf: 'fa fa-fw fa-hdd-o'
94       },
95       portals: {
96         expanded: 'fa fa-fw fa-server fa-lg',
97         leaf: 'fa fa-fw fa-server fa-lg'
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 }