1 import { Component, OnInit, ViewChild } from '@angular/core';
2 import { UntypedFormControl, Validators } from '@angular/forms';
3 import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
4 import { CdForm } from '~/app/shared/forms/cd-form';
5 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
7 import { Permission } from '~/app/shared/models/permissions';
8 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
9 import { PoolService } from '~/app/shared/api/pool.service';
10 import { Pool } from '../../pool/pool';
11 import { NvmeofGatewayNodeComponent } from '../nvmeof-gateway-node/nvmeof-gateway-node.component';
12 import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
13 import { CephServiceService } from '~/app/shared/api/ceph-service.service';
14 import { FinishedTask } from '~/app/shared/models/finished-task';
15 import { Router } from '@angular/router';
16 import { CdValidators } from '~/app/shared/forms/cd-validators';
17 import { NvmeofService } from '~/app/shared/api/nvmeof.service';
20 selector: 'cd-nvmeof-group-form',
21 templateUrl: './nvmeof-group-form.component.html',
22 styleUrls: ['./nvmeof-group-form.component.scss'],
25 export class NvmeofGroupFormComponent extends CdForm implements OnInit {
26 @ViewChild(NvmeofGatewayNodeComponent) gatewayNodeComponent: NvmeofGatewayNodeComponent;
28 permission: Permission;
29 groupForm: CdFormGroup;
36 hasAvailableNodes = true;
39 private authStorageService: AuthStorageService,
40 public actionLabels: ActionLabelsI18n,
41 private poolService: PoolService,
42 private taskWrapperService: TaskWrapperService,
43 private cephServiceService: CephServiceService,
44 private nvmeofService: NvmeofService,
45 private router: Router
48 this.permission = this.authStorageService.getPermissions().nvmeof;
49 this.resource = $localize`gateway group`;
53 this.action = this.actionLabels.CREATE;
59 this.groupForm = new CdFormGroup({
60 groupName: new UntypedFormControl(
65 const value = control.value;
66 return value && /[^a-zA-Z0-9_-]/.test(value) ? { invalidChars: true } : null;
69 [CdValidators.unique(this.nvmeofService.exists, this.nvmeofService)]
71 pool: new UntypedFormControl('rbd', {
72 validators: [Validators.required]
74 unmanaged: new UntypedFormControl(false)
78 onHostsLoaded(count: number): void {
79 this.hasAvailableNodes = count > 0;
82 get isCreateDisabled(): boolean {
83 if (!this.hasAvailableNodes) {
86 if (!this.groupForm) {
89 if (this.groupForm.pending) {
92 if (this.groupForm.invalid) {
95 const errors = this.groupForm.errors as { [key: string]: any } | null;
96 if (errors && errors.cdSubmitButton) {
99 if (this.gatewayNodeComponent) {
100 const selected = this.gatewayNodeComponent.getSelectedHostnames?.() || [];
101 if (selected.length === 0) {
110 this.poolsLoading = true;
111 this.poolService.list().then(
113 this.pools = (pools || []).filter(
114 (pool: Pool) => pool.application_metadata && pool.application_metadata.includes('rbd')
116 this.poolsLoading = false;
117 if (this.pools.length >= 1) {
118 const allPoolNames = this.pools.map((pool) => pool.pool_name);
119 const poolName = allPoolNames.includes('rbd') ? 'rbd' : this.pools[0].pool_name;
120 this.groupForm.patchValue({ pool: poolName });
125 this.poolsLoading = false;
131 if (this.groupForm.invalid) {
135 if (this.groupForm.pending) {
136 this.groupForm.setErrors({ cdSubmitButton: true });
140 const formValues = this.groupForm.value;
141 const selectedHostnames = this.gatewayNodeComponent?.getSelectedHostnames() || [];
142 if (selectedHostnames.length === 0) {
143 this.groupForm.setErrors({ cdSubmitButton: true });
146 let taskUrl = `service/${URLVerbs.CREATE}`;
147 const serviceName = `${formValues.pool}.${formValues.groupName}`;
149 const serviceSpec = {
150 service_type: 'nvmeof',
151 service_id: serviceName,
152 pool: formValues.pool,
153 group: formValues.groupName,
155 hosts: selectedHostnames
157 unmanaged: formValues.unmanaged
160 this.taskWrapperService
161 .wrapTaskAroundCall({
162 task: new FinishedTask(taskUrl, {
163 service_name: `nvmeof.${serviceName}`
165 call: this.cephServiceService.create(serviceSpec)
172 this.groupForm.setErrors({ cdSubmitButton: true });
177 private goToListView() {
178 this.router.navigateByUrl('/block/nvmeof/gateways');