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