]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
8310e65d203e5409c55d04039718b18ba1d29109
[ceph-ci.git] /
1 import { Component, OnInit } from '@angular/core';
2 import { UntypedFormControl, Validators } from '@angular/forms';
3 import { ActivatedRoute, Router } from '@angular/router';
4 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
5 import { ListenerRequest, NvmeofService } from '~/app/shared/api/nvmeof.service';
6 import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
7 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
8 import { FinishedTask } from '~/app/shared/models/finished-task';
9 import { Permission } from '~/app/shared/models/permissions';
10 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
11 import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
12 import { FormatterService } from '~/app/shared/services/formatter.service';
13 import { CdValidators } from '~/app/shared/forms/cd-validators';
14 import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
15 import { HostService } from '~/app/shared/api/host.service';
16 import { map } from 'rxjs/operators';
17 import { forkJoin } from 'rxjs';
18 import { CephServiceSpec } from '~/app/shared/models/service.interface';
19
20 @Component({
21   selector: 'cd-nvmeof-listeners-form',
22   templateUrl: './nvmeof-listeners-form.component.html',
23   styleUrls: ['./nvmeof-listeners-form.component.scss']
24 })
25 export class NvmeofListenersFormComponent implements OnInit {
26   action: string;
27   permission: Permission;
28   hostPermission: Permission;
29   resource: string;
30   pageURL: string;
31   listenerForm: CdFormGroup;
32   subsystemNQN: string;
33   hosts: Array<object> = null;
34   group: string;
35
36   constructor(
37     public actionLabels: ActionLabelsI18n,
38     private authStorageService: AuthStorageService,
39     private taskWrapperService: TaskWrapperService,
40     private nvmeofService: NvmeofService,
41     private hostService: HostService,
42     private router: Router,
43     private route: ActivatedRoute,
44     public activeModal: NgbActiveModal,
45     public formatterService: FormatterService,
46     public dimlessBinaryPipe: DimlessBinaryPipe
47   ) {
48     this.permission = this.authStorageService.getPermissions().nvmeof;
49     this.hostPermission = this.authStorageService.getPermissions().hosts;
50     this.resource = $localize`Listener`;
51     this.pageURL = 'block/nvmeof/subsystems';
52   }
53
54   setHosts() {
55     forkJoin({
56       gwGroups: this.nvmeofService.listGatewayGroups(),
57       hosts: this.hostService.getAllHosts()
58     })
59       .pipe(
60         map(({ gwGroups, hosts }) => {
61           // Find the gateway hosts in current group
62           const selectedGwGroup: CephServiceSpec = gwGroups?.[0]?.find(
63             (gwGroup: CephServiceSpec) => gwGroup?.spec?.group === this.group
64           );
65           const gatewayHosts: string[] = selectedGwGroup?.placement?.hosts;
66           // Return the gateway hosts in current group with their metadata
67           return gatewayHosts
68             ? hosts.filter((host: any) => gatewayHosts.includes(host.hostname))
69             : [];
70         })
71       )
72       .subscribe((nvmeofHosts: any[]) => {
73         this.hosts = nvmeofHosts.map((h) => ({ hostname: h.hostname, addr: h.addr }));
74       });
75   }
76
77   ngOnInit() {
78     this.createForm();
79     this.action = this.actionLabels.CREATE;
80     this.route.params.subscribe((params: { subsystem_nqn: string }) => {
81       this.subsystemNQN = params?.subsystem_nqn;
82     });
83     this.route.queryParams.subscribe((params) => {
84       this.group = params?.['group'];
85     });
86     this.setHosts();
87   }
88
89   createForm() {
90     this.listenerForm = new CdFormGroup({
91       host: new UntypedFormControl(null, {
92         validators: [Validators.required]
93       }),
94       trsvcid: new UntypedFormControl(4420, [
95         Validators.required,
96         CdValidators.number(false),
97         Validators.max(65535)
98       ])
99     });
100   }
101
102   buildRequest(): ListenerRequest {
103     const host = this.listenerForm.getValue('host');
104     let trsvcid = Number(this.listenerForm.getValue('trsvcid'));
105     if (!trsvcid) trsvcid = 4420;
106     const request: ListenerRequest = {
107       gw_group: this.group,
108       host_name: host.hostname,
109       traddr: host.addr,
110       trsvcid
111     };
112     return request;
113   }
114
115   onSubmit() {
116     const component = this;
117     const taskUrl: string = `nvmeof/listener/${URLVerbs.CREATE}`;
118     const request = this.buildRequest();
119     this.taskWrapperService
120       .wrapTaskAroundCall({
121         task: new FinishedTask(taskUrl, {
122           nqn: this.subsystemNQN,
123           host_name: request.host_name
124         }),
125         call: this.nvmeofService.createListener(this.subsystemNQN, request)
126       })
127       .subscribe({
128         error() {
129           component.listenerForm.setErrors({ cdSubmitButton: true });
130         },
131         complete: () => {
132           this.router.navigate([this.pageURL, { outlets: { modal: null } }]);
133         }
134       });
135   }
136 }