1 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
2 import { Router } from '@angular/router';
4 import { I18n } from '@ngx-translate/i18n-polyfill';
5 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
7 import { HostService } from '../../../shared/api/host.service';
8 import { ListWithDetails } from '../../../shared/classes/list-with-details.class';
9 import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
10 import { FormModalComponent } from '../../../shared/components/form-modal/form-modal.component';
11 import { SelectMessages } from '../../../shared/components/select/select-messages.model';
12 import { ActionLabelsI18n } from '../../../shared/constants/app.constants';
13 import { TableComponent } from '../../../shared/datatable/table/table.component';
14 import { Icons } from '../../../shared/enum/icons.enum';
15 import { NotificationType } from '../../../shared/enum/notification-type.enum';
16 import { CdTableAction } from '../../../shared/models/cd-table-action';
17 import { CdTableColumn } from '../../../shared/models/cd-table-column';
18 import { CdTableFetchDataContext } from '../../../shared/models/cd-table-fetch-data-context';
19 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
20 import { FinishedTask } from '../../../shared/models/finished-task';
21 import { Permissions } from '../../../shared/models/permissions';
22 import { CephShortVersionPipe } from '../../../shared/pipes/ceph-short-version.pipe';
23 import { JoinPipe } from '../../../shared/pipes/join.pipe';
24 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
25 import { DepCheckerService } from '../../../shared/services/dep-checker.service';
26 import { NotificationService } from '../../../shared/services/notification.service';
27 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
28 import { URLBuilderService } from '../../../shared/services/url-builder.service';
30 const BASE_URL = 'hosts';
34 templateUrl: './hosts.component.html',
35 styleUrls: ['./hosts.component.scss'],
36 providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }]
38 export class HostsComponent extends ListWithDetails implements OnInit {
39 @ViewChild(TableComponent, { static: true })
40 table: TableComponent;
41 @ViewChild('servicesTpl', { static: true })
42 public servicesTpl: TemplateRef<any>;
44 permissions: Permissions;
45 columns: Array<CdTableColumn> = [];
46 hosts: Array<object> = [];
47 isLoadingHosts = false;
48 cdParams = { fromLink: '/hosts' };
49 tableActions: CdTableAction[];
50 selection = new CdTableSelection();
54 private authStorageService: AuthStorageService,
55 private hostService: HostService,
56 private cephShortVersionPipe: CephShortVersionPipe,
57 private joinPipe: JoinPipe,
59 private urlBuilder: URLBuilderService,
60 private actionLabels: ActionLabelsI18n,
61 private modalService: BsModalService,
62 private taskWrapper: TaskWrapperService,
63 private router: Router,
64 private depCheckerService: DepCheckerService,
65 private notificationService: NotificationService
68 this.permissions = this.authStorageService.getPermissions();
71 name: this.actionLabels.CREATE,
75 this.depCheckerService.checkOrchestratorOrModal(
76 this.actionLabels.CREATE,
79 this.router.navigate([this.urlBuilder.getCreate()]);
85 name: this.actionLabels.EDIT,
89 this.depCheckerService.checkOrchestratorOrModal(
90 this.actionLabels.EDIT,
92 () => this.editAction()
95 disable: (selection: CdTableSelection) =>
96 !selection.hasSingleSelection || !selection.first().sources.orchestrator,
97 disableDesc: this.getEditDisableDesc.bind(this)
100 name: this.actionLabels.DELETE,
101 permission: 'delete',
104 this.depCheckerService.checkOrchestratorOrModal(
105 this.actionLabels.DELETE,
107 () => this.deleteAction()
110 disable: () => !this.selection.hasSelection
118 name: this.i18n('Hostname'),
123 name: this.i18n('Services'),
126 cellTemplate: this.servicesTpl
129 name: this.i18n('Labels'),
135 name: this.i18n('Version'),
136 prop: 'ceph_version',
138 pipe: this.cephShortVersionPipe
143 updateSelection(selection: CdTableSelection) {
144 this.selection = selection;
148 this.hostService.getLabels().subscribe((resp: string[]) => {
149 const host = this.selection.first();
150 const allLabels = resp.map((label) => {
151 return { enabled: true, name: label };
153 this.modalService.show(FormModalComponent, {
155 titleText: this.i18n('Edit Host: {{hostname}}', host),
158 type: 'select-badges',
160 value: host['labels'],
161 label: this.i18n('Labels'),
165 messages: new SelectMessages(
167 empty: this.i18n('There are no labels.'),
168 filter: this.i18n('Filter or add labels'),
169 add: this.i18n('Add label')
176 submitButtonText: this.i18n('Edit Host'),
177 onSubmit: (values: any) => {
178 this.hostService.update(host['hostname'], values.labels).subscribe(() => {
179 this.notificationService.show(
180 NotificationType.success,
181 this.i18n('Updated Host "{{hostname}}"', host)
183 // Reload the data table content.
184 this.table.refreshBtn();
192 getEditDisableDesc(selection: CdTableSelection): string | undefined {
193 if (selection && selection.hasSingleSelection && !selection.first().sources.orchestrator) {
194 return this.i18n('Host editing is disabled because the host is not managed by Orchestrator.');
200 const hostname = this.selection.first().hostname;
201 this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
203 itemDescription: 'Host',
204 itemNames: [hostname],
205 actionDescription: 'delete',
206 submitActionObservable: () =>
207 this.taskWrapper.wrapTaskAroundCall({
208 task: new FinishedTask('host/delete', { hostname: hostname }),
209 call: this.hostService.delete(hostname)
215 getHosts(context: CdTableFetchDataContext) {
216 if (this.isLoadingHosts) {
219 const typeToPermissionKey = {
224 'rbd-mirror': 'rbdMirroring',
226 'tcmu-runner': 'iscsi'
228 this.isLoadingHosts = true;
229 this.hostService.list().subscribe(
232 host.services.map((service: any) => {
233 service.cdLink = `/perf_counters/${service.type}/${encodeURIComponent(service.id)}`;
234 const permission = this.permissions[typeToPermissionKey[service.type]];
235 service.canRead = permission ? permission.read : false;
241 this.isLoadingHosts = false;
244 this.isLoadingHosts = false;