]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/blob
3cb52c20e05decef4e89b394d687e5dd25fd12f6
[ceph.git] /
1 import { Component, Inject, OnInit, Optional } from '@angular/core';
2 import { FormControl, Validators } from '@angular/forms';
3 import { CephfsSubvolumeService } from '~/app/shared/api/cephfs-subvolume.service';
4 import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
5 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
6 import { FinishedTask } from '~/app/shared/models/finished-task';
7 import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
8 import { Pool } from '../../pool/pool';
9 import { FormatterService } from '~/app/shared/services/formatter.service';
10 import { CdTableColumn } from '~/app/shared/models/cd-table-column';
11 import { CdValidators } from '~/app/shared/forms/cd-validators';
12 import { CephfsSubvolumeInfo } from '~/app/shared/models/cephfs-subvolume.model';
13 import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
14 import { OctalToHumanReadablePipe } from '~/app/shared/pipes/octal-to-human-readable.pipe';
15 import { CdForm } from '~/app/shared/forms/cd-form';
16 import { CephfsSubvolumeGroupService } from '~/app/shared/api/cephfs-subvolume-group.service';
17 import { CephfsSubvolumeGroup } from '~/app/shared/models/cephfs-subvolume-group.model';
18 import { Observable } from 'rxjs';
19
20 @Component({
21   selector: 'cd-cephfs-subvolume-form',
22   templateUrl: './cephfs-subvolume-form.component.html',
23   styleUrls: ['./cephfs-subvolume-form.component.scss']
24 })
25 export class CephfsSubvolumeFormComponent extends CdForm implements OnInit {
26   subvolumeForm: CdFormGroup;
27
28   action: string;
29   resource: string;
30
31   subVolumeGroups$: Observable<CephfsSubvolumeGroup[]>;
32   subVolumeGroups: CephfsSubvolumeGroup[];
33   dataPools: Pool[];
34
35   columns: CdTableColumn[];
36   scopePermissions: Array<any> = [];
37   initialMode = {
38     owner: ['read', 'write', 'execute'],
39     group: ['read', 'execute'],
40     others: ['read', 'execute']
41   };
42   scopes: string[] = ['owner', 'group', 'others'];
43
44   constructor(
45     private actionLabels: ActionLabelsI18n,
46     private taskWrapper: TaskWrapperService,
47     private cephFsSubvolumeService: CephfsSubvolumeService,
48     private cephFsSubvolumeGroupService: CephfsSubvolumeGroupService,
49     private formatter: FormatterService,
50     private dimlessBinary: DimlessBinaryPipe,
51     private octalToHumanReadable: OctalToHumanReadablePipe,
52
53     @Optional() @Inject('fsName') public fsName: string,
54     @Optional() @Inject('subVolumeName') public subVolumeName: string,
55     @Optional() @Inject('subVolumeGroupName') public subVolumeGroupName: string,
56     @Optional() @Inject('pools') public pools: Pool[],
57     @Optional() @Inject('isEdit') public isEdit = false
58   ) {
59     super();
60     this.resource = $localize`Subvolume`;
61   }
62
63   ngOnInit(): void {
64     this.action = this.actionLabels.CREATE;
65     this.columns = [
66       {
67         prop: 'scope',
68         name: $localize`All`,
69         flexGrow: 0.5
70       },
71       {
72         prop: 'read',
73         name: $localize`Read`,
74         flexGrow: 0.5,
75         cellClass: 'text-center'
76       },
77       {
78         prop: 'write',
79         name: $localize`Write`,
80         flexGrow: 0.5,
81         cellClass: 'text-center'
82       },
83       {
84         prop: 'execute',
85         name: $localize`Execute`,
86         flexGrow: 0.5,
87         cellClass: 'text-center'
88       }
89     ];
90
91     this.subVolumeGroups$ = this.cephFsSubvolumeGroupService.get(this.fsName);
92     this.dataPools = this.pools.filter((pool) => pool.type === 'data');
93     this.createForm();
94
95     this.isEdit ? this.populateForm() : this.loadingReady();
96   }
97
98   createForm() {
99     this.subvolumeForm = new CdFormGroup({
100       volumeName: new FormControl({ value: this.fsName, disabled: true }),
101       subvolumeName: new FormControl('', {
102         validators: [Validators.required, Validators.pattern(/^[.A-Za-z0-9_-]+$/)],
103         asyncValidators: [
104           CdValidators.unique(
105             this.cephFsSubvolumeService.exists,
106             this.cephFsSubvolumeService,
107             null,
108             null,
109             this.fsName,
110             this.subVolumeGroupName
111           )
112         ]
113       }),
114       subvolumeGroupName: new FormControl(this.subVolumeGroupName),
115       pool: new FormControl(this.dataPools[0]?.pool, {
116         validators: [Validators.required]
117       }),
118       size: new FormControl(null, {
119         updateOn: 'blur'
120       }),
121       uid: new FormControl(null),
122       gid: new FormControl(null),
123       mode: new FormControl({}),
124       isolatedNamespace: new FormControl(false)
125     });
126   }
127
128   populateForm() {
129     this.action = this.actionLabels.EDIT;
130     this.cephFsSubvolumeService
131       .info(this.fsName, this.subVolumeName, this.subVolumeGroupName)
132       .subscribe((resp: CephfsSubvolumeInfo) => {
133         // Disabled these fields since its not editable
134         this.subvolumeForm.get('subvolumeName').disable();
135         this.subvolumeForm.get('subvolumeGroupName').disable();
136         this.subvolumeForm.get('pool').disable();
137         this.subvolumeForm.get('uid').disable();
138         this.subvolumeForm.get('gid').disable();
139
140         this.subvolumeForm.get('isolatedNamespace').disable();
141         this.subvolumeForm.get('subvolumeName').setValue(this.subVolumeName);
142         this.subvolumeForm.get('subvolumeGroupName').setValue(this.subVolumeGroupName);
143         if (resp.bytes_quota !== 'infinite') {
144           this.subvolumeForm.get('size').setValue(this.dimlessBinary.transform(resp.bytes_quota));
145         }
146         this.subvolumeForm.get('uid').setValue(resp.uid);
147         this.subvolumeForm.get('gid').setValue(resp.gid);
148         this.subvolumeForm.get('isolatedNamespace').setValue(resp.pool_namespace);
149         this.initialMode = this.octalToHumanReadable.transform(resp.mode, true);
150
151         this.loadingReady();
152       });
153   }
154
155   submit() {
156     const subVolumeName = this.subvolumeForm.getValue('subvolumeName');
157     const subVolumeGroupName = this.subvolumeForm.getValue('subvolumeGroupName');
158     const pool = this.subvolumeForm.getValue('pool');
159     const size = this.formatter.toBytes(this.subvolumeForm.getValue('size')) || 0;
160     const uid = this.subvolumeForm.getValue('uid');
161     const gid = this.subvolumeForm.getValue('gid');
162     const mode = this.formatter.toOctalPermission(this.subvolumeForm.getValue('mode'));
163     const isolatedNamespace = this.subvolumeForm.getValue('isolatedNamespace');
164
165     if (this.isEdit) {
166       const editSize = size === 0 ? 'infinite' : size;
167       this.taskWrapper
168         .wrapTaskAroundCall({
169           task: new FinishedTask('cephfs/subvolume/' + URLVerbs.EDIT, {
170             subVolumeName: subVolumeName
171           }),
172           call: this.cephFsSubvolumeService.update(
173             this.fsName,
174             subVolumeName,
175             String(editSize),
176             subVolumeGroupName
177           )
178         })
179         .subscribe({
180           error: () => {
181             this.subvolumeForm.setErrors({ cdSubmitButton: true });
182           },
183           complete: () => {
184             this.closeModal();
185           }
186         });
187     } else {
188       this.taskWrapper
189         .wrapTaskAroundCall({
190           task: new FinishedTask('cephfs/subvolume/' + URLVerbs.CREATE, {
191             subVolumeName: subVolumeName
192           }),
193           call: this.cephFsSubvolumeService.create(
194             this.fsName,
195             subVolumeName,
196             subVolumeGroupName,
197             pool,
198             String(size),
199             uid,
200             gid,
201             mode,
202             isolatedNamespace
203           )
204         })
205         .subscribe({
206           error: () => {
207             this.subvolumeForm.setErrors({ cdSubmitButton: true });
208           },
209           complete: () => {
210             this.closeModal();
211           }
212         });
213     }
214   }
215 }