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