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';
6 NamespaceCreateRequest,
9 } from '~/app/shared/api/nvmeof.service';
10 import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
11 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
12 import { FinishedTask } from '~/app/shared/models/finished-task';
13 import { NvmeofSubsystemNamespace } from '~/app/shared/models/nvmeof';
14 import { Permission } from '~/app/shared/models/permissions';
15 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
16 import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
17 import { Pool } from '../../pool/pool';
18 import { PoolService } from '~/app/shared/api/pool.service';
19 import { RbdService } from '~/app/shared/api/rbd.service';
20 import { FormatterService } from '~/app/shared/services/formatter.service';
21 import { Observable } from 'rxjs';
22 import { CdValidators } from '~/app/shared/forms/cd-validators';
23 import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
26 selector: 'cd-nvmeof-namespaces-form',
27 templateUrl: './nvmeof-namespaces-form.component.html',
28 styleUrls: ['./nvmeof-namespaces-form.component.scss']
30 export class NvmeofNamespacesFormComponent implements OnInit {
32 permission: Permission;
33 poolPermission: Permission;
36 edit: boolean = false;
39 rbdPools: Array<Pool> = null;
40 units: Array<string> = ['KiB', 'MiB', 'GiB', 'TiB'];
43 invalidSizeError: boolean;
47 public actionLabels: ActionLabelsI18n,
48 private authStorageService: AuthStorageService,
49 private taskWrapperService: TaskWrapperService,
50 private nvmeofService: NvmeofService,
51 private poolService: PoolService,
52 private rbdService: RbdService,
53 private router: Router,
54 private route: ActivatedRoute,
55 public activeModal: NgbActiveModal,
56 public formatterService: FormatterService,
57 public dimlessBinaryPipe: DimlessBinaryPipe
59 this.permission = this.authStorageService.getPermissions().nvmeof;
60 this.poolPermission = this.authStorageService.getPermissions().pool;
61 this.resource = $localize`Namespace`;
62 this.pageURL = 'block/nvmeof/subsystems';
66 this.route.queryParams.subscribe((params) => {
67 this.group = params?.['group'];
70 this.action = this.actionLabels.CREATE;
71 this.route.params.subscribe((params: { subsystem_nqn: string; nsid: string }) => {
72 this.subsystemNQN = params.subsystem_nqn;
73 this.nsid = params?.nsid;
79 this.action = this.actionLabels.EDIT;
81 .getNamespace(this.subsystemNQN, this.nsid, this.group)
82 .subscribe((res: NvmeofSubsystemNamespace) => {
83 const convertedSize = this.dimlessBinaryPipe.transform(res.rbd_image_size).split(' ');
84 this.currentBytes = res.rbd_image_size;
85 this.nsForm.get('image').setValue(res.rbd_image_name);
86 this.nsForm.get('pool').setValue(res.rbd_pool_name);
87 this.nsForm.get('unit').setValue(convertedSize[1]);
88 this.nsForm.get('image_size').setValue(convertedSize[0]);
89 this.nsForm.get('image_size').addValidators(Validators.required);
90 this.nsForm.get('image').disable();
91 this.nsForm.get('pool').disable();
96 this.poolService.getList().subscribe((resp: Pool[]) => {
97 this.rbdPools = resp.filter(this.rbdService.isRBDPool);
103 if (this.router.url.includes('subsystems/(modal:edit')) {
106 this.initForCreate();
111 this.nsForm = new CdFormGroup({
112 image: new UntypedFormControl(`nvme_ns_image:${Date.now()}`, {
113 validators: [Validators.required, Validators.pattern(/^[^@/]+?$/)]
115 pool: new UntypedFormControl(null, {
116 validators: [Validators.required]
118 image_size: new UntypedFormControl(1, [CdValidators.number(false), Validators.min(1)]),
119 unit: new UntypedFormControl(this.units[2])
123 buildRequest(): NamespaceCreateRequest | NamespaceEditRequest {
124 const image_size = this.nsForm.getValue('image_size');
125 const image_size_unit = this.nsForm.getValue('unit');
126 const request = {} as NamespaceCreateRequest | NamespaceEditRequest;
127 request['gw_group'] = this.group;
129 const key: string = this.edit ? 'rbd_image_size' : 'size';
130 const value: number = this.formatterService.toBytes(image_size + image_size_unit);
131 request[key] = value;
134 const image = this.nsForm.getValue('image');
135 const pool = this.nsForm.getValue('pool');
136 request['rbd_image_name'] = image;
137 request['rbd_pool'] = pool;
143 const unit = this.nsForm.getValue('unit');
144 const image_size = this.nsForm.getValue('image_size');
145 if (image_size && unit) {
146 const bytes = this.formatterService.toBytes(image_size + unit);
147 return bytes <= this.currentBytes;
153 if (this.validateSize()) {
154 this.invalidSizeError = true;
155 this.nsForm.setErrors({ cdSubmitButton: true });
157 this.invalidSizeError = false;
158 const component = this;
159 const taskUrl: string = `nvmeof/namespace/${this.edit ? URLVerbs.EDIT : URLVerbs.CREATE}`;
160 const request = this.buildRequest();
161 let action: Observable<any>;
164 action = this.taskWrapperService.wrapTaskAroundCall({
165 task: new FinishedTask(taskUrl, {
166 nqn: this.subsystemNQN,
169 call: this.nvmeofService.updateNamespace(
172 request as NamespaceEditRequest
176 action = this.taskWrapperService.wrapTaskAroundCall({
177 task: new FinishedTask(taskUrl, {
178 nqn: this.subsystemNQN
180 call: this.nvmeofService.createNamespace(
182 request as NamespaceCreateRequest
189 component.nsForm.setErrors({ cdSubmitButton: true });
192 this.router.navigate([this.pageURL, { outlets: { modal: null } }]);