1 import { Component, OnInit } from '@angular/core';
2 import { UntypedFormControl, Validators } from '@angular/forms';
3 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
4 import { Subscription, forkJoin } from 'rxjs';
5 import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
6 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
7 import { WizardStepModel } from '~/app/shared/models/wizard-steps';
8 import { WizardStepsService } from '~/app/shared/services/wizard-steps.service';
9 import { RgwDaemonService } from '~/app/shared/api/rgw-daemon.service';
10 import { RgwDaemon } from '../models/rgw-daemon';
11 import { MultiClusterService } from '~/app/shared/api/multi-cluster.service';
12 import { RgwMultisiteService } from '~/app/shared/api/rgw-multisite.service';
13 import { Icons } from '~/app/shared/enum/icons.enum';
14 import { SelectOption } from '~/app/shared/components/select/select-option.model';
15 import _ from 'lodash';
16 import { SelectMessages } from '~/app/shared/components/select/select-messages.model';
17 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
18 import { NotificationService } from '~/app/shared/services/notification.service';
19 import { Router } from '@angular/router';
20 import { map, switchMap } from 'rxjs/operators';
23 selector: 'cd-rgw-multisite-wizard',
24 templateUrl: './rgw-multisite-wizard.component.html',
25 styleUrls: ['./rgw-multisite-wizard.component.scss']
27 export class RgwMultisiteWizardComponent implements OnInit {
28 multisiteSetupForm: CdFormGroup;
29 currentStep: WizardStepModel;
30 currentStepSub: Subscription;
31 permissions: Permissions;
32 stepTitles = ['Create Realm & Zonegroup', 'Create Zone', 'Select Cluster'];
33 stepsToSkip: { [steps: string]: boolean } = {};
34 daemons: RgwDaemon[] = [];
36 clusterDetailsArray: any;
37 isMultiClusterConfigured = false;
38 exportTokenForm: CdFormGroup;
43 rgwEndpoints: { value: any[]; options: any[]; messages: any };
46 private wizardStepsService: WizardStepsService,
47 public activeModal: NgbActiveModal,
48 public actionLabels: ActionLabelsI18n,
49 private rgwDaemonService: RgwDaemonService,
50 private multiClusterService: MultiClusterService,
51 private rgwMultisiteService: RgwMultisiteService,
52 public notificationService: NotificationService,
53 private router: Router
55 this.pageURL = 'rgw/multisite';
56 this.currentStepSub = this.wizardStepsService
58 .subscribe((step: WizardStepModel) => {
59 this.currentStep = step;
61 this.currentStep.stepIndex = 1;
66 messages: new SelectMessages({
67 empty: $localize`There are no endpoints.`,
68 filter: $localize`Select endpoints`
77 switchMap((daemons) => {
78 this.daemons = daemons;
79 const daemonStatsObservables = daemons.map((daemon) =>
80 this.rgwDaemonService.get(daemon.id).pipe(
81 map((daemonStats) => ({
82 hostname: daemon.server_hostname,
84 frontendConfig: daemonStats['rgw_metadata']['frontend_config#0']
88 return forkJoin(daemonStatsObservables);
91 .subscribe((daemonStatsArray) => {
92 this.rgwEndpoints.value = daemonStatsArray.map((daemonStats) => {
93 const protocol = daemonStats.frontendConfig.includes('ssl_port') ? 'https' : 'http';
94 return `${protocol}://${daemonStats.hostname}:${daemonStats.port}`;
96 const options: SelectOption[] = this.rgwEndpoints.value.map(
97 (endpoint: string) => new SelectOption(false, endpoint, '')
99 this.rgwEndpoints.options = [...options];
102 this.multiClusterService.getCluster().subscribe((clusters) => {
103 this.clusterDetailsArray = Object.values(clusters['config'])
105 .filter((cluster) => cluster['cluster_alias'] !== 'local-cluster');
106 this.isMultiClusterConfigured = this.clusterDetailsArray.length > 0;
107 if (!this.isMultiClusterConfigured) {
108 this.stepTitles = ['Create Realm & Zonegroup', 'Create Zone', 'Export Multi-site token'];
110 this.selectedCluster = this.clusterDetailsArray[0]['name'];
116 this.multisiteSetupForm = new CdFormGroup({
117 realmName: new UntypedFormControl('default_realm', {
118 validators: [Validators.required]
120 zonegroupName: new UntypedFormControl('default_zonegroup', {
121 validators: [Validators.required]
123 zonegroup_endpoints: new UntypedFormControl(null, [Validators.required]),
124 zoneName: new UntypedFormControl('default_zone', {
125 validators: [Validators.required]
127 zone_endpoints: new UntypedFormControl(null, {
128 validators: [Validators.required]
130 username: new UntypedFormControl('default_system_user', {
131 validators: [Validators.required]
133 cluster: new UntypedFormControl(null, {
134 validators: [Validators.required]
138 if (!this.isMultiClusterConfigured) {
139 this.exportTokenForm = new CdFormGroup({});
143 showSubmitButtonLabel() {
144 if (this.isMultiClusterConfigured) {
145 return !this.wizardStepsService.isLastStep()
146 ? this.actionLabels.NEXT
147 : $localize`Configure Multi-site`;
149 return !this.wizardStepsService.isLastStep() ? this.actionLabels.NEXT : $localize`Close`;
153 showCancelButtonLabel() {
154 return !this.wizardStepsService.isFirstStep()
155 ? this.actionLabels.BACK
156 : this.actionLabels.CANCEL;
160 if (!this.wizardStepsService.isLastStep()) {
161 this.wizardStepsService.getCurrentStep().subscribe((step: WizardStepModel) => {
162 this.currentStep = step;
164 if (this.currentStep.stepIndex === 2 && !this.isMultiClusterConfigured) {
167 this.wizardStepsService.moveToNextStep();
176 const values = this.multisiteSetupForm.value;
177 const realmName = values['realmName'];
178 const zonegroupName = values['zonegroupName'];
179 const zonegroupEndpoints = this.rgwEndpoints.value.join(',');
180 const zoneName = values['zoneName'];
181 const zoneEndpoints = this.rgwEndpoints.value.join(',');
182 const username = values['username'];
183 if (!this.isMultiClusterConfigured) {
184 if (this.wizardStepsService.isLastStep()) {
185 this.activeModal.close();
186 this.refreshMultisitePage();
188 this.rgwMultisiteService
189 .setUpMultisiteReplication(
197 .subscribe((data: object[]) => {
198 this.loading = false;
200 this.wizardStepsService.moveToNextStep();
201 this.showSuccessNotification();
205 const cluster = values['cluster'];
206 this.rgwMultisiteService
207 .setUpMultisiteReplication(
218 this.showSuccessNotification();
219 this.activeModal.close();
220 this.refreshMultisitePage();
223 this.multisiteSetupForm.setErrors({ cdSubmitButton: true });
229 showSuccessNotification() {
230 this.notificationService.show(
231 NotificationType.success,
232 $localize`Multi-site setup completed successfully.`
236 refreshMultisitePage() {
237 const currentRoute = this.router.url.split('?')[0];
238 const navigateTo = currentRoute.includes('multisite') ? '/pool' : '/';
239 this.router.navigateByUrl(navigateTo, { skipLocationChange: true }).then(() => {
240 this.router.navigate([currentRoute]);
245 if (!this.wizardStepsService.isFirstStep()) {
246 this.wizardStepsService.moveToPreviousStep();
248 this.activeModal.close();
253 const stepTitle = this.stepTitles[this.currentStep.stepIndex - 1];
254 this.stepsToSkip[stepTitle] = true;