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