]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/blob
e5b55258d419badc8d4bc09767e2ab3a488d1a01
[ceph.git] /
1 import {
2   AfterViewInit,
3   ChangeDetectorRef,
4   Component,
5   Inject,
6   OnDestroy,
7   OnInit,
8   Optional
9 } from '@angular/core';
10 import { UntypedFormControl, UntypedFormGroup, ValidatorFn, Validators } from '@angular/forms';
11
12 import { BaseModal } from 'carbon-components-angular';
13 import _ from 'lodash';
14 import { concat, forkJoin, Subscription } from 'rxjs';
15 import { last, tap } from 'rxjs/operators';
16
17 import { Pool } from '~/app/ceph/pool/pool';
18 import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
19 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
20 import { FinishedTask } from '~/app/shared/models/finished-task';
21 import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
22
23 @Component({
24   selector: 'cd-bootstrap-create-modal',
25   templateUrl: './bootstrap-create-modal.component.html',
26   styleUrls: ['./bootstrap-create-modal.component.scss']
27 })
28 export class BootstrapCreateModalComponent
29   extends BaseModal
30   implements OnDestroy, OnInit, AfterViewInit {
31   pools: any[] = [];
32   token: string;
33
34   subs: Subscription;
35
36   createBootstrapForm: CdFormGroup;
37
38   constructor(
39     private rbdMirroringService: RbdMirroringService,
40     private taskWrapper: TaskWrapperService,
41     private changeDetectorRef: ChangeDetectorRef,
42
43     @Inject('siteName') @Optional() public siteName?: string
44   ) {
45     super();
46     this.createForm();
47   }
48
49   ngAfterViewInit(): void {
50     this.changeDetectorRef.detectChanges();
51   }
52
53   createForm() {
54     this.createBootstrapForm = new CdFormGroup({
55       siteName: new UntypedFormControl('', {
56         validators: [Validators.required]
57       }),
58       pools: new UntypedFormGroup(
59         {},
60         {
61           validators: [this.validatePools()]
62         }
63       ),
64       token: new UntypedFormControl('', {})
65     });
66   }
67
68   ngOnInit() {
69     this.createBootstrapForm.get('siteName').setValue(this.siteName);
70     this.rbdMirroringService.getSiteName().subscribe((response: any) => {
71       this.createBootstrapForm.get('siteName').setValue(response.site_name);
72     });
73
74     this.subs = this.rbdMirroringService.subscribeSummary((data) => {
75       const pools = data.content_data.pools;
76       this.pools = pools.reduce((acc: any[], pool: Pool) => {
77         acc.push({
78           name: pool['name'],
79           mirror_mode: pool['mirror_mode']
80         });
81         return acc;
82       }, []);
83
84       const poolsControl = this.createBootstrapForm.get('pools') as UntypedFormGroup;
85       _.each(this.pools, (pool) => {
86         const poolName = pool['name'];
87         const mirroring_disabled = pool['mirror_mode'] === 'disabled';
88         const control = poolsControl.controls[poolName];
89         if (control) {
90           if (mirroring_disabled && control.disabled) {
91             control.enable();
92           } else if (!mirroring_disabled && control.enabled) {
93             control.disable();
94             control.setValue(true);
95           }
96         } else {
97           poolsControl.addControl(
98             poolName,
99             new UntypedFormControl({ value: !mirroring_disabled, disabled: !mirroring_disabled })
100           );
101         }
102       });
103     });
104   }
105
106   ngOnDestroy() {
107     if (this.subs) {
108       this.subs.unsubscribe();
109     }
110   }
111
112   validatePools(): ValidatorFn {
113     return (poolsControl: UntypedFormGroup): { [key: string]: any } => {
114       let checkedCount = 0;
115       _.each(poolsControl.controls, (control) => {
116         if (control.value === true) {
117           ++checkedCount;
118         }
119       });
120
121       if (checkedCount > 0) {
122         return null;
123       }
124
125       return { requirePool: true };
126     };
127   }
128
129   generate() {
130     this.createBootstrapForm.get('token').setValue('');
131
132     let bootstrapPoolName = '';
133     const poolNames: string[] = [];
134     const poolsControl = this.createBootstrapForm.get('pools') as UntypedFormGroup;
135     _.each(poolsControl.controls, (control, poolName) => {
136       if (control.value === true) {
137         bootstrapPoolName = poolName;
138         if (!control.disabled) {
139           poolNames.push(poolName);
140         }
141       }
142     });
143
144     const poolModeRequest = {
145       mirror_mode: 'image'
146     };
147
148     const apiActionsObs = concat(
149       this.rbdMirroringService.setSiteName(this.createBootstrapForm.getValue('siteName')),
150       forkJoin(
151         poolNames.map((poolName) => this.rbdMirroringService.updatePool(poolName, poolModeRequest))
152       ),
153       this.rbdMirroringService
154         .createBootstrapToken(bootstrapPoolName)
155         .pipe(tap((data: any) => this.createBootstrapForm.get('token').setValue(data['token'])))
156     ).pipe(last());
157
158     const finishHandler = () => {
159       this.rbdMirroringService.refresh();
160       this.createBootstrapForm.setErrors({ cdSubmitButton: true });
161     };
162
163     const taskObs = this.taskWrapper.wrapTaskAroundCall({
164       task: new FinishedTask('rbd/mirroring/bootstrap/create', {}),
165       call: apiActionsObs
166     });
167     taskObs.subscribe({ error: finishHandler, complete: finishHandler });
168   }
169 }