]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/blob
1a17fdb61ccddd2d07187f528a5cc7f952029239
[ceph.git] /
1 import {
2   AfterViewInit,
3   Component,
4   Input,
5   OnChanges,
6   OnDestroy,
7   OnInit,
8   QueryList,
9   TemplateRef,
10   ViewChild,
11   ViewChildren
12 } from '@angular/core';
13
14 import _ from 'lodash';
15 import { Observable, Subscription } from 'rxjs';
16
17 import { CephServiceService } from '~/app/shared/api/ceph-service.service';
18 import { HostService } from '~/app/shared/api/host.service';
19 import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
20 import { TableComponent } from '~/app/shared/datatable/table/table.component';
21 import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
22 import { Icons } from '~/app/shared/enum/icons.enum';
23 import { CdTableColumn } from '~/app/shared/models/cd-table-column';
24 import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
25 import { Daemon } from '~/app/shared/models/daemon.interface';
26 import { CephServiceSpec } from '~/app/shared/models/service.interface';
27 import { RelativeDatePipe } from '~/app/shared/pipes/relative-date.pipe';
28
29 @Component({
30   selector: 'cd-service-daemon-list',
31   templateUrl: './service-daemon-list.component.html',
32   styleUrls: ['./service-daemon-list.component.scss']
33 })
34 export class ServiceDaemonListComponent implements OnInit, OnChanges, AfterViewInit, OnDestroy {
35   @ViewChild('statusTpl', { static: true })
36   statusTpl: TemplateRef<any>;
37
38   @ViewChild('listTpl', { static: true })
39   listTpl: TemplateRef<any>;
40
41   @ViewChildren('daemonsTable')
42   daemonsTableTpls: QueryList<TemplateRef<TableComponent>>;
43
44   @Input()
45   serviceName?: string;
46
47   @Input()
48   hostname?: string;
49
50   @Input()
51   flag?: string;
52
53   icons = Icons;
54
55   daemons: Daemon[] = [];
56   services: Array<CephServiceSpec> = [];
57   columns: CdTableColumn[] = [];
58   serviceColumns: CdTableColumn[] = [];
59
60   hasOrchestrator = false;
61   showDocPanel = false;
62
63   private daemonsTable: TableComponent;
64   private daemonsTableTplsSub: Subscription;
65   private serviceSub: Subscription;
66
67   constructor(
68     private hostService: HostService,
69     private cephServiceService: CephServiceService,
70     private orchService: OrchestratorService,
71     private relativeDatePipe: RelativeDatePipe
72   ) {}
73
74   ngOnInit() {
75     this.columns = [
76       {
77         name: $localize`Hostname`,
78         prop: 'hostname',
79         flexGrow: 2,
80         filterable: true
81       },
82       {
83         name: $localize`Daemon type`,
84         prop: 'daemon_type',
85         flexGrow: 1,
86         filterable: true
87       },
88       {
89         name: $localize`Daemon ID`,
90         prop: 'daemon_id',
91         flexGrow: 1,
92         filterable: true
93       },
94       {
95         name: $localize`Container ID`,
96         prop: 'container_id',
97         flexGrow: 2,
98         filterable: true,
99         cellTransformation: CellTemplate.truncate,
100         customTemplateConfig: {
101           length: 12
102         }
103       },
104       {
105         name: $localize`Container Image name`,
106         prop: 'container_image_name',
107         flexGrow: 3,
108         filterable: true
109       },
110       {
111         name: $localize`Container Image ID`,
112         prop: 'container_image_id',
113         flexGrow: 2,
114         filterable: true,
115         cellTransformation: CellTemplate.truncate,
116         customTemplateConfig: {
117           length: 12
118         }
119       },
120       {
121         name: $localize`Version`,
122         prop: 'version',
123         flexGrow: 1,
124         filterable: true
125       },
126       {
127         name: $localize`Status`,
128         prop: 'status_desc',
129         flexGrow: 1,
130         filterable: true,
131         cellTemplate: this.statusTpl
132       },
133       {
134         name: $localize`Last Refreshed`,
135         prop: 'last_refresh',
136         pipe: this.relativeDatePipe,
137         flexGrow: 1
138       },
139       {
140         name: $localize`Daemon Events`,
141         prop: 'events',
142         flexGrow: 5,
143         cellTemplate: this.listTpl
144       }
145     ];
146
147     this.serviceColumns = [
148       {
149         name: $localize`Service Name`,
150         prop: 'service_name',
151         flexGrow: 2,
152         filterable: true
153       },
154       {
155         name: $localize`Service Type`,
156         prop: 'service_type',
157         flexGrow: 1,
158         filterable: true
159       },
160       {
161         name: $localize`Service Events`,
162         prop: 'events',
163         flexGrow: 5,
164         cellTemplate: this.listTpl
165       }
166     ];
167
168     this.orchService.status().subscribe((data: { available: boolean }) => {
169       this.hasOrchestrator = data.available;
170       this.showDocPanel = !data.available;
171     });
172   }
173
174   ngOnChanges() {
175     if (!_.isUndefined(this.daemonsTable)) {
176       this.daemonsTable.reloadData();
177     }
178   }
179
180   ngAfterViewInit() {
181     this.daemonsTableTplsSub = this.daemonsTableTpls.changes.subscribe(
182       (tableRefs: QueryList<TableComponent>) => {
183         this.daemonsTable = tableRefs.first;
184       }
185     );
186   }
187
188   ngOnDestroy() {
189     if (this.daemonsTableTplsSub) {
190       this.daemonsTableTplsSub.unsubscribe();
191     }
192     if (this.serviceSub) {
193       this.serviceSub.unsubscribe();
194     }
195   }
196
197   getStatusClass(row: Daemon): string {
198     return _.get(
199       {
200         '-1': 'badge-danger',
201         '0': 'badge-warning',
202         '1': 'badge-success'
203       },
204       row.status,
205       'badge-dark'
206     );
207   }
208
209   getDaemons(context: CdTableFetchDataContext) {
210     let observable: Observable<Daemon[]>;
211     if (this.hostname) {
212       observable = this.hostService.getDaemons(this.hostname);
213     } else if (this.serviceName) {
214       observable = this.cephServiceService.getDaemons(this.serviceName);
215     } else {
216       this.daemons = [];
217       return;
218     }
219     observable.subscribe(
220       (daemons: Daemon[]) => {
221         this.daemons = daemons;
222       },
223       () => {
224         this.daemons = [];
225         context.error();
226       }
227     );
228   }
229
230   getServices(context: CdTableFetchDataContext) {
231     this.serviceSub = this.cephServiceService.list(this.serviceName).subscribe(
232       (services: CephServiceSpec[]) => {
233         this.services = services;
234       },
235       () => {
236         this.services = [];
237         context.error();
238       }
239     );
240   }
241
242   trackByFn(_index: any, item: any) {
243     return item.created;
244   }
245 }