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