]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/blob
860cdefa1a99e45116ec4526f68697554959dfb4
[ceph-ci.git] /
1
2 <cds-modal size="lg"
3            [open]="open"
4            [hasScrollingContent]="true"
5            (overlaySelected)="closeModal()">
6   <cds-modal-header (closeSelect)="closeModal()">
7     <h3 cdsModalHeaderHeading
8         data-testid="rgw-multisite-wizard-header"
9         i18n>Set up Multi-site Replication</h3>
10   </cds-modal-header>
11
12   <div cdsModalContent>
13     <div cdsRow>
14       <div cdsCol
15            [columnNumbers]="{'lg': 2, 'md': 2, 'sm': 2}"
16            class="indicator-wrapper">
17         <cd-wizard [stepsTitle]="stepTitles"></cd-wizard>
18       </div>
19
20       <div cdsCol
21            [columnNumbers]="{'lg': 14, 'md': 14, 'sm': 14}">
22         <form [formGroup]="multisiteSetupForm"
23               #formDir="ngForm"
24               novalidate>
25           <ng-container [ngSwitch]="currentStep?.stepIndex">
26             <div *ngSwitchCase="0"
27                  class="ms-5">
28               <ng-container *ngIf="environment.build === 'ibm'; else defaultAlert">
29                 <cd-alert-panel type="info"
30                                 spacingClass="mb-3">
31                   This wizard enables you to set up multi-site replication within your
32                   Ceph environment. If you have already added another cluster to your
33                   multi-cluster setup, you can select that cluster in the wizard to
34                   automate the replication process. If no additional cluster is currently
35                   added, the wizard will guide you through creating the necessary realm,
36                   zonegroup, and zone, and provide a realm token. This token can be used
37                   later to manually import into a desired cluster to establish replication
38                   between the clusters.
39                 </cd-alert-panel>
40               </ng-container>
41
42               <ng-template #defaultAlert>
43                 <cd-alert-panel type="info"
44                                 spacingClass="mb-3">
45                   This wizard enables you to set up multi-site replication within your
46                   Ceph environment.It will guide you through creating the necessary realm,
47                   zonegroup, and zone, and provide a realm token. This token can be used
48                   later to manually import into a desired cluster to establish replication
49                   between the clusters.
50                 </cd-alert-panel>
51               </ng-template>
52
53               <div class="form-group row"
54                    *ngIf="showConfigType && isMultiClusterConfigured">
55                 <label class="cd-col-form-label required"
56                        for="configType"
57                        i18n>Realm configuration mode</label>
58                 <div class="col-md-auto custom-checkbox form-check-inline  ms-3">
59                   <input class="form-check-input"
60                          formControlName="configType"
61                          id="newRealm"
62                          value="newRealm"
63                          (change)="onConfigTypeChange()"
64                          type="radio">
65                   <label class="custom-check-label"
66                          for="newRealm"
67                          i18n>Create new realm/zonegroup/zone</label>
68                 </div>
69                 <div class="col-md-auto custom-checkbox form-check-inline">
70                   <input class="form-check-input"
71                          formControlName="configType"
72                          id="existingRealm"
73                          type="radio"
74                          (change)="onConfigTypeChange()"
75                          value="existingRealm">
76                   <label class="custom-check-label"
77                          for="existingRealm"
78                          i18n>Select existing realm</label>
79                 </div>
80               </div>
81               <div class="form-group row"
82                    *ngIf="multisiteSetupForm.get('configType').value === 'existingRealm' && showConfigType && isMultiClusterConfigured">
83                 <label class="cd-col-form-label"
84                        for="selectedRealm"
85                        i18n>Select Realm</label>
86                 <div class="cd-col-form-input">
87                   <select class="form-select"
88                           id="selectedRealm"
89                           formControlName="selectedRealm">
90                   <option *ngFor="let realm of realmList"
91                           [value]="realm">
92                         {{ realm }}
93                   </option>
94                   </select>
95                 </div>
96               </div>
97               <div *ngIf="multisiteSetupForm.get('configType').value === 'newRealm' || !showConfigType">
98                 <div class="form-group row">
99                   <label class="cd-col-form-label required"
100                          for="realmName"
101                          i18n>Realm Name</label>
102                   <div class="cd-col-form-input">
103                     <input class="form-control"
104                            type="text"
105                            id="realmName"
106                            formControlName="realmName">
107                     <cd-help-text>
108                       <span i18n>Enter a unique name for the Realm. The Realm is a logical grouping of all your Zonegroups.</span>
109                     </cd-help-text>
110                     <span class="invalid-feedback"
111                           *ngIf="multisiteSetupForm.showError('realmName', formDir, 'required')"
112                           i18n>This field is required.</span>
113                     <span class="invalid-feedback"
114                           *ngIf="multisiteSetupForm.showError('realmName', formDir, 'uniqueName')"
115                           i18n>This realm name is already in use. Choose a unique name.</span>
116                   </div>
117                 </div>
118                 <div class="form-group row">
119                   <label class="cd-col-form-label required"
120                          for="zonegroupName"
121                          i18n>Zone Group Name</label>
122                   <div class="cd-col-form-input">
123                     <input class="form-control"
124                            type="text"
125                            id="zonegroupName"
126                            formControlName="zonegroupName">
127                     <cd-help-text>
128                       <span i18n>Enter a name for the Zonegroup. Zonegroup will help you identify and manage the group of zones.</span>
129                     </cd-help-text>
130                     <span class="invalid-feedback"
131                           *ngIf="multisiteSetupForm.showError('zonegroupName', formDir, 'required')"
132                           i18n>This field is required.</span>
133                     <span class="invalid-feedback"
134                           *ngIf="multisiteSetupForm.showError('zonegroupName', formDir, 'uniqueName')"
135                           i18n>This zonegroup name is already in use. Choose a unique name.</span>
136                   </div>
137                 </div>
138                 <div class="form-group row">
139                   <label class="cd-col-form-label required"
140                          for="zonegroup_endpoints"
141                          i18n>Zonegroup Endpoints</label>
142                   <div class="cd-col-form-input">
143                     <cd-select-badges id="zonegroup_endpoints"
144                                       [data]="rgwEndpoints.value"
145                                       [options]="rgwEndpoints.options"
146                                       [customBadges]="true">
147                     </cd-select-badges>
148                     <cd-help-text>
149                       <span i18n>Select the endpoints for the Zonegroup. Endpoints are the URLs or IP addresses from which the rgw gateways in that zonegroup can be accessed. You can select multiple endpoints in case you have multiple rgw gateways in a zonegroup</span>
150                     </cd-help-text>
151                   </div>
152                 </div>
153               </div>
154             </div>
155             <ng-container *ngSwitchCase="1">
156               <div *ngIf="multisiteSetupForm.get('configType').value === 'newRealm'"
157                    class="ms-5">
158                 <div class="form-group row">
159                   <label class="cd-col-form-label required"
160                          for="zonegroupName"
161                          i18n>Zone Name</label>
162                   <div class="cd-col-form-input">
163                     <input class="form-control"
164                            type="text"
165                            id="zoneName"
166                            formControlName="zoneName">
167                     <cd-help-text>
168                       <span i18n>Enter a unique name for the Zone. A Zone represents a distinct data center or geographical location within a Zonegroup.</span>
169                     </cd-help-text>
170                     <span class="invalid-feedback"
171                           *ngIf="multisiteSetupForm.showError('zoneName', formDir, 'required')"
172                           i18n>This field is required.</span>
173                     <span class="invalid-feedback"
174                           *ngIf="multisiteSetupForm.showError('zoneName', formDir, 'uniqueName')"
175                           i18n>This zone name is already in use. Choose a unique name.</span>
176                   </div>
177                 </div>
178                 <div class="form-group row">
179                   <label class="cd-col-form-label required"
180                          for="zone_endpoints"
181                          i18n>Zone Endpoints</label>
182                   <div class="cd-col-form-input">
183                     <cd-select-badges id="zone_endpoints"
184                                       [data]="rgwEndpoints.value"
185                                       [options]="rgwEndpoints.options"
186                                       [customBadges]="true"></cd-select-badges>
187                     <cd-help-text>
188                       <span i18n>Select the endpoints for the Zone. Endpoints are the URLs or IP addresses from which the rgw gateways in that zone can be accessed. You can select multiple endpoints in case you have multiple rgw gateways in a zone</span>
189                     </cd-help-text>
190                   </div>
191                 </div>
192                 <div class="form-group row">
193                   <label class="cd-col-form-label required"
194                          for="username"
195                          i18n>Username</label>
196                   <div class="cd-col-form-input">
197                     <input class="form-control"
198                            type="text"
199                            id="username"
200                            formControlName="username"
201                            ngbTooltip="White spaces at the beginning and end will be trimmed"
202                            i18n-ngbTooltip
203                            cdTrim>
204                     <cd-help-text>
205                       <span i18n>Specify the username for the system user.</span>
206                     </cd-help-text>
207                     <cd-alert-panel type="info"
208                                     [showTitle]="false">
209                       <span i18n>This user will be created automatically as part of the process, and it will have the necessary permissions to manage and synchronize resources across zones.</span>
210                     </cd-alert-panel>
211                     <span class="invalid-feedback"
212                           *ngIf="multisiteSetupForm.showError('username', formDir, 'required')"
213                           i18n>This field is required.</span>
214                     <span class="invalid-feedback"
215                           *ngIf="multisiteSetupForm.showError('username', formDir, 'notUnique')"
216                           i18n>This username is already in use. Choose a unique name.</span>
217                   </div>
218                 </div>
219               </div>
220               <div *ngIf="isMultiClusterConfigured && (multisiteSetupForm.get('configType').value === 'existingRealm')"
221                    class="ms-5">
222                 <ng-container *ngTemplateOutlet="replicationTemplate"></ng-container>
223               </div>
224             </ng-container>
225             <ng-container *ngSwitchCase="2">
226               <div *ngIf="multisiteSetupForm.get('configType').value === 'newRealm'"
227                    class="ms-5">
228                 <ng-container *ngIf="isMultiClusterConfigured; else newRealmReviewTemplate">
229                   <ng-container *ngTemplateOutlet="replicationTemplate"></ng-container>
230                 </ng-container>
231               </div>
232               <div *ngIf="multisiteSetupForm.get('configType').value === 'existingRealm' && isMultiClusterConfigured"
233                    class="ms-5">
234                 <ng-container *ngIf="!loading; else loadingTemplate">
235                   <ng-container *ngIf="!setupCompleted; else progressCompleteTemplate">
236                     <ng-container *ngTemplateOutlet="reviewTemplate"></ng-container>
237                   </ng-container>
238                 </ng-container>
239               </div>
240             </ng-container>
241             <ng-template #newRealmReviewTemplate>
242               <ng-container *ngTemplateOutlet="reviewTemplate"></ng-container>
243             </ng-template>
244             <ng-template #replicationTemplate>
245               <div class="form-group row">
246                 <label class="cd-col-form-label required"
247                        for="cluster"
248                        i18n>Replication Cluster</label>
249                 <div class="cd-col-form-input">
250                   <select class="form-select"
251                           id="cluster"
252                           [(ngModel)]="selectedCluster"
253                           formControlName="cluster"
254                           name="cluster">
255                     <option *ngFor="let cluster_detail of clusterDetailsArray"
256                             [value]="cluster_detail.name">
257                       {{ cluster_detail.cluster_alias }} - {{ cluster_detail.name }}
258                     </option>
259                   </select>
260                   <cd-help-text>
261                     <span i18n>Choose the cluster where you want to apply this multisite configuration. The selected cluster will integrate the defined Realm, Zonegroup, and Zones, enabling data synchronization and management across the multisite setup.</span>
262                   </cd-help-text>
263                   <cd-alert-panel type="info"
264                                   [showTitle]="false">
265                     <span i18n>Before submitting this form, please verify that the selected cluster has an active RGW (Rados Gateway) service running.</span>
266                   </cd-alert-panel>
267                 </div>
268               </div>
269               <div class="form-group row">
270                 <label class="cd-col-form-label required"
271                        for="replicationZoneName"
272                        i18n>Replication Zone Name</label>
273                 <div class="cd-col-form-input">
274                   <input class="form-control"
275                          type="text"
276                          id="replicationZoneName"
277                          name="replicationZoneName"
278                          formControlName="replicationZoneName">
279                   <cd-help-text>
280                     <span i18n>Replication zone represents the zone to be created in the replication cluster where your data will be replicated.</span>
281                   </cd-help-text>
282                   <span class="invalid-feedback"
283                         *ngIf="multisiteSetupForm.showError('replicationZoneName', formDir, 'required')"
284                         i18n>This field is required.</span>
285                 </div>
286               </div>
287             </ng-template>
288             <div *ngSwitchCase="3"
289                  class="ms-5">
290               <div *ngIf="isMultiClusterConfigured">
291                 <ng-container *ngIf="!loading; else loadingTemplate">
292                   <ng-container *ngIf="!setupCompleted; else progressCompleteTemplate">
293                     <ng-container *ngTemplateOutlet="reviewTemplate"></ng-container>
294                   </ng-container>
295                 </ng-container>
296               </div>
297             </div>
298           </ng-container>
299         </form>
300       </div>
301     </div>
302   </div>
303   <cds-modal-footer>
304     <button cdsButton="secondary"
305             name="skip-cluster-selection"
306             aria-label="Skip"
307             (click)="onSkip()"
308             *ngIf="stepTitles[currentStep.stepIndex]['label'] === 'Select Cluster' && multisiteSetupForm.get('configType').value === 'newRealm'"
309             i18n>Skip</button>
310     <button cdsButton="secondary"
311             (click)="onPreviousStep()"
312             [attr.aria-label]="showCancelButtonLabel()"
313             i18n>{{ showCancelButtonLabel() }}</button>
314     <button cdsButton="primary"
315             (click)="onNextStep()"
316             aria-label="Next"
317             [disabled]="loading"
318             i18n>{{ showSubmitButtonLabel() }}
319       <cds-loading [isActive]="loading"
320                    [overlay]="false"
321                    size="sm"
322                    *ngIf="loading">
323       </cds-loading>
324     </button>
325   </cds-modal-footer>
326 </cds-modal>
327
328
329 <ng-template #nonMultiClusterTemplate>
330   <ng-container *ngIf="!loading; else loadingTemplate">
331     <ng-container *ngIf="!setupCompleted else exportTokenTemplate">
332       <ng-container *ngTemplateOutlet="reviewTemplate"></ng-container>
333     </ng-container>
334   </ng-container>
335 </ng-template>
336
337 <ng-template #loadingTemplate>
338   <ng-container *ngTemplateOutlet="progressTemplate"></ng-container>
339 </ng-template>
340
341 <ng-template #progressCompleteTemplate>
342   <div *ngIf="isMultiClusterConfigured && !stepsToSkip['Select Cluster']; else exportTokenTemplate">
343     <div class="text-center text-success"
344          i18n>
345       Multi-site replication setup is complete.
346     </div>
347   </div>
348 </ng-template>
349
350 <ng-template #progressTemplate>
351   <cd-progress [value]="executingTask?.progress"
352                [description]="executingTask?.name?.replace('progress/Multisite-Setup:', '')?.split('||')[0]?.trim()"
353                [subDescription]="executingTask?.name?.replace('progress/Multisite-Setup:', '')?.split('||')[1]?.trim()">
354   </cd-progress>
355 </ng-template>
356
357 <ng-template #exportTokenTemplate>
358   <div *ngFor="let realminfo of realms">
359     <div class="form-group row">
360       <label class="cd-col-form-label"
361              for="realmName"
362              i18n>Realm Name</label>
363       <div class="cd-col-form-input">
364         <input id="realmName"
365                name="realmName"
366                type="text"
367                [value]="realminfo.realm"
368                readonly>
369         <cd-help-text>
370           <span i18n>Name of the realm that will be involved in replication.</span>
371         </cd-help-text>
372       </div>
373     </div>
374     <div class="form-group row">
375       <label class="cd-col-form-label"
376              for="token"
377              i18n>Token</label>
378       <div class="cd-col-form-input">
379         <input id="realmToken"
380                name="realmToken"
381                type="text"
382                [value]="realminfo.token"
383                class="me-2 mb-4"
384                readonly>
385         <cd-copy-2-clipboard-button [source]="realminfo.token"
386                                     [byId]="false">
387         </cd-copy-2-clipboard-button>
388         <cd-help-text>
389           <span i18n>This field displays the token needed to import the multisite configuration into a secondary cluster. Copy this token securely and use it on the secondary cluster to replicate the current multisite setup. Ensure that the token is handled securely to prevent unauthorized access.</span>
390         </cd-help-text>
391       </div>
392     </div>
393     <hr *ngIf="realms.length > 1">
394   </div>
395 </ng-template>
396
397 <ng-template #reviewTemplate>
398   <cd-alert-panel type="warning"
399                   [showTitle]="false">
400     <span i18n>
401       During the automation process, the RGW module will be enabled on both the source and target clusters, if it is not already enabled.
402       This action may cause a temporary downtime (5-10 seconds) on each cluster.
403     </span>
404   </cd-alert-panel>
405   <ng-container [ngSwitch]="multisiteSetupForm.get('configType').value">
406     <ng-container *ngSwitchCase="'newRealm'">
407       <ng-container *ngTemplateOutlet="newRealmInfo"></ng-container>
408       <ng-container *ngTemplateOutlet="replicationInfo"></ng-container>
409     </ng-container>
410     <ng-container *ngSwitchCase="'existingRealm'">
411       <ng-container *ngTemplateOutlet="existingRealmInfo"></ng-container>
412       <ng-container *ngTemplateOutlet="replicationInfo"></ng-container>
413     </ng-container>
414   </ng-container>
415 </ng-template>
416
417 <ng-template #newRealmInfo>
418   <div class="form-group row">
419     <label class="cd-col-form-label"
420            i18n>Realm Name:</label>
421     <div class="cd-col-form-input mt-2 text-muted"><b>{{ multisiteSetupForm.get('realmName').value }}</b></div>
422   </div>
423   <div class="form-group row">
424     <label class="cd-col-form-label"
425            i18n>Zonegroup Name:</label>
426     <div class="cd-col-form-input mt-2 text-muted"><b>{{ multisiteSetupForm.get('zonegroupName').value }}</b></div>
427   </div>
428   <div class="form-group row">
429     <label class="cd-col-form-label"
430            i18n>Zonegroup Endpoints:</label>
431     <div class="cd-col-form-input mt-2 text-muted"><b>{{ rgwEndpoints.value.join(', ') }}</b></div>
432   </div>
433   <div class="form-group row">
434     <label class="cd-col-form-label"
435            i18n>Zone Name:</label>
436     <div class="cd-col-form-input mt-2 text-muted"><b>{{ multisiteSetupForm.get('zoneName').value }}</b></div>
437   </div>
438   <div class="form-group row">
439     <label class="cd-col-form-label"
440            i18n>Zone Endpoints:</label>
441     <div class="cd-col-form-input mt-2 text-muted"><b>{{ rgwEndpoints.value.join(', ') }}</b></div>
442   </div>
443   <div class="form-group row">
444     <label class="cd-col-form-label"
445            i18n>Username:</label>
446     <div class="cd-col-form-input mt-2 text-muted"><b>{{ multisiteSetupForm.get('username').value }}</b></div>
447   </div>
448 </ng-template>
449
450 <ng-template #existingRealmInfo>
451   <div class="form-group row">
452     <label class="cd-col-form-label"
453            i18n>Selected Realm:</label>
454     <div class="cd-col-form-input mt-2 text-muted"><b>{{ multisiteSetupForm.get('selectedRealm').value }}</b></div>
455   </div>
456 </ng-template>
457
458 <ng-template #replicationInfo>
459   <div *ngIf="isMultiClusterConfigured && !stepsToSkip['Select Cluster']">
460     <div class="form-group row">
461       <label class="cd-col-form-label"
462              i18n>Selected Replication Cluster:</label>
463       <div class="cd-col-form-input mt-2 text-muted"><b>{{ selectedCluster }}</b></div>
464     </div>
465     <div class="form-group row">
466       <label class="cd-col-form-label"
467              i18n>Replication Zone Name:</label>
468       <div class="cd-col-form-input mt-2 text-muted"><b>{{ multisiteSetupForm.get('replicationZoneName').value }}</b></div>
469     </div>
470   </div>
471 </ng-template>