]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
435cdb9644fdfd83fa68e65be9932d3a5ec75ce0
[ceph.git] /
1 import {
2   AfterViewInit,
3   ChangeDetectorRef,
4   Component,
5   Inject,
6   OnInit,
7   Optional
8 } from '@angular/core';
9 import { FormControl, Validators } from '@angular/forms';
10 import { OperatorFunction, Observable, of } from 'rxjs';
11 import { debounceTime, distinctUntilChanged, switchMap, catchError } from 'rxjs/operators';
12 import { CephfsService } from '~/app/shared/api/cephfs.service';
13 import { DirectoryStoreService } from '~/app/shared/api/directory-store.service';
14 import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
15 import { Icons } from '~/app/shared/enum/icons.enum';
16 import { CdForm } from '~/app/shared/forms/cd-form';
17 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
18 import { FinishedTask } from '~/app/shared/models/finished-task';
19 import { ModalCdsService } from '~/app/shared/services/modal-cds.service';
20 import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
21
22 const DEBOUNCE_TIMER = 300;
23
24 @Component({
25   selector: 'cd-cephfs-auth-modal',
26   templateUrl: './cephfs-auth-modal.component.html',
27   styleUrls: ['./cephfs-auth-modal.component.scss']
28 })
29 export class CephfsAuthModalComponent extends CdForm implements OnInit, AfterViewInit {
30   subvolumeGroup: string;
31   subvolume: string;
32   isDefaultSubvolumeGroup = false;
33   isSubvolume = false;
34   form: CdFormGroup;
35   action: string;
36   resource: string;
37   icons = Icons;
38
39   clientPermissions = [
40     {
41       name: 'read',
42       description: $localize`Read permission is the minimum givable access`
43     },
44     {
45       name: 'write',
46       description: $localize`Permission to set layouts or quotas, write access needed`
47     },
48     {
49       name: 'quota',
50       description: $localize`Permission to set layouts or quotas, write access needed`
51     },
52     {
53       name: 'snapshot',
54       description: $localize`Permission to create or delete snapshots, write access needed`
55     },
56     {
57       name: 'rootSquash',
58       description: $localize`Safety measure to prevent scenarios such as accidental sudo rm -rf /path`
59     }
60   ];
61
62   constructor(
63     private actionLabels: ActionLabelsI18n,
64     public directoryStore: DirectoryStoreService,
65     private cephfsService: CephfsService,
66     private taskWrapper: TaskWrapperService,
67     private modalService: ModalCdsService,
68     private changeDetectorRef: ChangeDetectorRef,
69
70     @Optional() @Inject('fsName') public fsName: string,
71     @Optional() @Inject('id') public id: number
72   ) {
73     super();
74     this.action = this.actionLabels.UPDATE;
75     this.resource = $localize`access`;
76   }
77
78   ngAfterViewInit(): void {
79     this.changeDetectorRef.detectChanges();
80   }
81
82   ngOnInit() {
83     this.directoryStore.loadDirectories(this.id, '/', 3);
84     this.createForm();
85     this.loadingReady();
86   }
87
88   createForm() {
89     this.form = new CdFormGroup({
90       fsName: new FormControl(
91         { value: this.fsName, disabled: true },
92         {
93           validators: [Validators.required]
94         }
95       ),
96       directory: new FormControl(undefined, {
97         updateOn: 'blur',
98         validators: [Validators.required]
99       }),
100       userId: new FormControl(undefined, {
101         validators: [Validators.required]
102       }),
103       read: new FormControl(
104         { value: true, disabled: true },
105         {
106           validators: [Validators.required]
107         }
108       ),
109       write: new FormControl(undefined),
110       snapshot: new FormControl({ value: false, disabled: true }),
111       quota: new FormControl({ value: false, disabled: true }),
112       rootSquash: new FormControl(undefined)
113     });
114   }
115
116   search: OperatorFunction<string, readonly string[]> = (input: Observable<string>) =>
117     input.pipe(
118       debounceTime(DEBOUNCE_TIMER),
119       distinctUntilChanged(),
120       switchMap((term) =>
121         this.directoryStore.search(term, this.id).pipe(
122           catchError(() => {
123             return of([]);
124           })
125         )
126       )
127     );
128
129   onSubmit() {
130     const clientId: number = this.form.getValue('userId');
131     const caps: string[] = [this.form.getValue('directory'), this.transformPermissions()];
132     const rootSquash: boolean = this.form.getValue('rootSquash');
133     this.taskWrapper
134       .wrapTaskAroundCall({
135         task: new FinishedTask('cephfs/auth', {
136           clientId: clientId
137         }),
138         call: this.cephfsService.setAuth(this.fsName, clientId, caps, rootSquash)
139       })
140       .subscribe({
141         error: () => this.form.setErrors({ cdSubmitButton: true }),
142         complete: () => {
143           this.modalService.dismissAll();
144         }
145       });
146   }
147
148   transformPermissions(): string {
149     const write = this.form.getValue('write');
150     const snapshot = this.form.getValue('snapshot');
151     const quota = this.form.getValue('quota');
152     return `r${write ? 'w' : ''}${quota ? 'p' : ''}${snapshot ? 's' : ''}`;
153   }
154
155   toggleFormControl() {
156     const snapshot = this.form.get('snapshot');
157     const quota = this.form.get('quota');
158     snapshot.disabled ? snapshot.enable() : snapshot.disable();
159     quota.disabled ? quota.enable() : quota.disable();
160   }
161 }