]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
138bc4131ecf245aad83ddcb70406f24ed983e0e
[ceph-ci.git] /
1 <div cdsCol
2      [columnNumbers]="{ md: 4 }">
3   <ng-container *cdFormLoading="loading">
4     <form name="storageClassForm"
5           #formDir="ngForm"
6           [formGroup]="storageClassForm"
7           novalidate>
8       <div i18n="form title"
9            class="form-header">
10         {{ action | titlecase }} {{ resource | upperFirst }}
11
12         <cd-help-text [formAllFieldsRequired]="true"></cd-help-text>
13       </div>
14       <div class="form-item">
15         <cds-select
16           label="Type"
17           i18n-label
18           for="storageClassType"
19           formControlName="storageClassType"
20           [helperText]="helpTextLabels.storageClassText"
21           id="storageClassType"
22           [invalid]="storageClassForm.showError('storageClassType', formDir, 'required')"
23           [invalidText]="storageError"
24         >
25           <option value=""
26                   i18n>-- Select Storage Class --</option>
27           <option *ngFor="let opt of storageClassOptions"
28                   [value]="opt.value"
29                   i18n>
30             {{ opt.label }}
31           </option>
32         </cds-select>
33         <ng-template #storageError>
34           <span
35             class="invalid-feedback"
36             *ngIf="storageClassForm.showError('storageClassType', formDir, 'required')"
37             i18n
38             >This field is required.</span
39           >
40         </ng-template>
41       </div>
42       <div class="form-item form-item-append"
43            cdsRow>
44         <div cdsCol>
45           <!-- Zone Group -->
46           <cds-select
47             label="Zone Group Name"
48             i18n-label
49             formControlName="zonegroup"
50             id="zonegroup"
51             [invalid]="storageClassForm.showError('zonegroup', formDir, 'required')"
52             (change)="onZonegroupChange()"
53             [invalidText]="zonegroupError"
54           >
55             <option
56               *ngFor="let zonegrp of zonegroupNames"
57               [value]="zonegrp.name"
58               [selected]="zonegrp.name === storageClassForm.getValue('zonegroup')"
59               i18n
60             >
61               {{ zonegrp.name }}
62             </option>
63           </cds-select>
64           <ng-template #zonegroupError>
65             <span
66               class="invalid-feedback"
67               *ngIf="storageClassForm.showError('zonegroup', formDir, 'required')"
68               i18n
69               >This field is required.</span
70             >
71           </ng-template>
72         </div>
73         <div cdsCol>
74           <!-- Placement Target -->
75           <cds-select
76             label="Placement Target"
77             i18n-label
78             formControlName="placement_target"
79             id="placement_target"
80             [invalid]="storageClassForm.showError('placement_target', formDir, 'required')"
81             [invalidText]="placementError"
82           >
83             <option [value]="''"
84                     i18n>--Select--</option>
85             <option
86               *ngFor="let placementTarget of placementTargets"
87               [value]="placementTarget"
88               [selected]="placementTarget === storageClassForm.getValue('placement_target')"
89               i18n
90             >
91               {{ placementTarget }}
92             </option>
93           </cds-select>
94           <ng-template #placementError>
95             <span
96               class="invalid-feedback"
97               *ngIf="storageClassForm.showError('placement_target', formDir, 'required')"
98               i18n
99               >This field is required.</span
100             >
101           </ng-template>
102         </div>
103       </div>
104       <!-- Storage Class -->
105       <div class="form-item">
106         <cds-text-label
107           labelInputID="storage_class"
108           i18n
109           [disabled]="editing"
110           [invalid]="
111             storageClassForm.controls.storage_class.invalid &&
112             storageClassForm.controls.storage_class.dirty
113           "
114           [invalidText]="storageClassError"
115           >Name
116           <input
117             cdsText
118             type="text"
119             id="storage_class"
120             formControlName="storage_class"
121             [invalid]="storageClassForm.showError('storage_class', formDir, 'required')"
122           />
123         </cds-text-label>
124         <ng-template #storageClassError>
125           <span
126             class="invalid-feedback"
127             *ngIf="storageClassForm.showError('storage_class', formDir, 'required')"
128             i18n
129             >This field is required.</span
130           >
131         </ng-template>
132       </div>
133       @if( isTierMatch( TIER_TYPE.CLOUD_TIER, TIER_TYPE.GLACIER )){
134       <div>
135         <div class="form-item form-item-append"
136              cdsRow>
137           <div cdsCol>
138             <!-- Target Region -->
139             <cds-text-label
140               labelInputID="region"
141               i18n
142               [invalid]="storageClassForm.showError('region', formDir, 'required')"
143               [invalidText]="regionError"
144               [helperText]="helpTextLabels.targetRegionText"
145               >Target Region
146               <input
147                 cdsText
148                 type="text"
149                 id="region"
150                 formControlName="region"
151                 placeholder="e.g, us-east-1"
152                 i18n-placeholder
153                 [invalid]="storageClassForm.showError('region', formDir, 'required')"
154               />
155             </cds-text-label>
156             <ng-template #regionError>
157               <span
158                 class="invalid-feedback"
159                 *ngIf="storageClassForm.showError('region', formDir, 'required')"
160                 i18n
161                 >This field is required.</span
162               >
163             </ng-template>
164           </div>
165           <div cdsCol>
166             <!-- Target Endpoint -->
167             <cds-text-label
168               i18n
169               [invalid]="storageClassForm.showError('target_endpoint', formDir, 'required') || storageClassForm.showError('target_endpoint', formDir, 'invalidUrl')"
170
171               [invalidText]="
172                             storageClassForm.controls['target_endpoint'].errors?.['required'] ? 'This field is required.' :
173                             storageClassForm.controls['target_endpoint'].errors?.['invalidUrl'] ? 'Please enter a valid URL.' : ''
174                           "
175               i18n-invalidText
176               >Target Endpoint
177               <input
178                 cdsText
179                 formControlName="target_endpoint"
180                 placeholder="e.g. 192.168.0.10, 192.168.1.0/8"
181                  [invalid]="storageClassForm.showError('target_endpoint', formDir, 'required') || storageClassForm.showError('target_endpoint', formDir, 'invalidUrl')"
182               />
183             </cds-text-label>
184           </div>
185         </div>
186         <!-- Access Key  -->
187         <div class="form-item">
188           <div cdsCol
189                [columnNumbers]="{ md: 12 }"
190                class="d-flex">
191             <cds-password-label
192               labelInputID="access_key"
193               [invalid]="storageClassForm.showError('access_key', formDir, 'required')"
194               [invalidText]="accessError"
195               [helperText]="helpTextLabels.targetAccessKeyText"
196               i18n
197               >Target Access Key
198               <input
199                 cdsPassword
200                 type="password"
201                 id="access_key"
202                 formControlName="access_key"
203                 [invalid]="storageClassForm.showError('access_key', formDir, 'required')"
204               />
205             </cds-password-label>
206             <cd-copy-2-clipboard-button class="clipboard"> </cd-copy-2-clipboard-button>
207             <ng-template #accessError>
208               <span
209                 class="invalid-feedback"
210                 *ngIf="storageClassForm.showError('access_key', formDir, 'required')"
211                 i18n
212                 >This field is required.</span
213               >
214             </ng-template>
215           </div>
216         </div>
217         <!-- Secret Key  -->
218         <div class="form-item">
219           <div cdsCol
220                [columnNumbers]="{ md: 12 }"
221                class="d-flex">
222             <cds-password-label
223               labelInputID="secret_key"
224               [helperText]="helpTextLabels.targetSecretKeyText"
225               [invalid]="storageClassForm.showError('secret_key', formDir, 'required')"
226               [invalidText]="secretError"
227               i18n
228               >Target Secret Key
229               <input
230                 cdsPassword
231                 type="password"
232                 id="secret_key"
233                 formControlName="secret_key"
234                 [invalid]="storageClassForm.showError('secret_key', formDir, 'required')"
235               />
236             </cds-password-label>
237             <cd-copy-2-clipboard-button class="clipboard"> </cd-copy-2-clipboard-button>
238             <ng-template #secretError>
239               <span
240                 class="invalid-feedback"
241                 *ngIf="storageClassForm.showError('secret_key', formDir, 'required')"
242                 i18n
243                 >This field is required.</span
244               >
245             </ng-template>
246           </div>
247         </div>
248         <!-- Target Path -->
249         <div class="form-item">
250           <cds-text-label
251             labelInputID="target_path"
252             i18n
253             [invalid]="storageClassForm.showError('target_path', formDir, 'required')"
254             [invalidText]="targetError"
255             [helperText]="helpTextLabels.targetPathText"
256             >Target Path
257             <input
258               cdsText
259               type="text"
260               id="target_path"
261               formControlName="target_path"
262               [invalid]="storageClassForm.showError('target_path', formDir, 'required')"
263             />
264           </cds-text-label>
265           <ng-template #targetError>
266             <span
267               class="invalid-feedback"
268               *ngIf="storageClassForm.showError('target_path', formDir, 'required')"
269               i18n
270               >This field is required.</span
271             >
272           </ng-template>
273         </div>
274         <div class="form-item">
275           <cds-checkbox
276             id="allow_read_through"
277             formControlName="allow_read_through"
278             cdOptionalField="Allow Read Through"
279             i18n
280             (change)="onAllowReadThroughChange($event)"
281             >Allow Read Through
282             <cd-help-text>{{ helpTextLabels?.allowReadThroughText }}</cd-help-text>
283           </cds-checkbox>
284         </div>
285         <div class="form-item">
286           <cds-checkbox
287             id="retain_head_object"
288             formControlName="retain_head_object"
289             cdOptionalField="Head Object (Stub File)"
290             i18n
291             >Head Object (Stub File)
292             <cd-help-text>{{ helpTextLabels?.retainHeadObjectText }}</cd-help-text>
293           </cds-checkbox>
294         </div>
295         <div class="form-item form-item-append"
296              cdsRow>
297           <div cdsCol>
298             <cds-number
299               name="read_through_restore_days"
300               formControlName="read_through_restore_days"
301               id="read_through_restore_days"
302               min="1"
303               label="ReadThrough Restore Days"
304               [helperText]="helpTextLabels.readthroughrestoreDaysText"
305               i18n-helperText
306               i18n-label
307               i18n
308               [invalid]="
309                 storageClassForm.controls.read_through_restore_days.invalid &&
310                 storageClassForm.controls.read_through_restore_days.dirty
311               "
312               [invalidText]="readThroughError"
313             ></cds-number>
314             <ng-template #readThroughError>
315               <span
316                 class="invalid-feedback"
317                 *ngIf="storageClassForm.showError('read_through_restore_days', formDir, 'pattern')"
318                 i18n
319                 >The entered value must be a positive integer.</span
320               >
321               <span
322                 class="invalid-feedback"
323                 *ngIf="storageClassForm.showError('read_through_restore_days', formDir, 'lockDays')"
324                 i18n
325                 >ReadThrough Restore Days must be positive.</span
326               >
327             </ng-template>
328           </div>
329           <div cdsCol>
330             <cds-select
331               formControlName="restore_storage_class"
332               label="Restore Storage Class"
333               id="restore_storage_class"
334               [helperText]="helpTextLabels.restoreStorageClassText"
335               i18n-label
336             >
337               <option [value]="''"
338                       i18n>-- Select the glacier restore storage class --</option>
339               <option [ngValue]="standard"
340                       i18n>Standard</option>
341             </cds-select>
342           </div>
343         </div>
344       </div>
345       } @if(isTierMatch(TIER_TYPE.GLACIER)){
346       <div>
347         <legend class="cd-header"
348                 i18n>Glacier Configuration</legend>
349         <div class="form-item form-item-append"
350              cdsRow>
351           <div cdsCol>
352             <cds-select
353               formControlName="glacier_restore_tier_type"
354               label="Glacier Restore Tier Type"
355               cdRequiredField="Glacier Restore Tier Type"
356               id="glacier_restore_tier_type"
357               [invalid]="
358                 storageClassForm.controls.glacier_restore_tier_type.invalid &&
359                 storageClassForm.controls.glacier_restore_tier_type.dirty
360               "
361               [invalidText]="glacierError"
362               [helperText]="helpTextLabels.tiertypeText"
363               i18n-label
364             >
365               <option value="''"
366                       i18n>-- Select the glacier restore tier type --</option>
367               <option [ngValue]="standard"
368                       i18n>Standard</option>
369               <option [ngValue]="expedited"
370                       i18n>Expedited</option>
371             </cds-select>
372             <ng-template #glacierError>
373               <span
374                 class="invalid-feedback"
375                 *ngIf="storageClassForm.showError('glacier_restore_tier_type', formDir, 'required')"
376                 i18n
377                 >This field is required.</span
378               >
379             </ng-template>
380           </div>
381           <div cdsCol>
382             <cds-number
383               [id]="'glacier_restore_days'"
384               [formControlName]="'glacier_restore_days'"
385               [label]="'Glacier Restore Days'"
386               [helperText]="helpTextLabels.restoreDaysText"
387               [min]="1"
388               i18n-helperText
389               i18n-label
390               i18n
391               [invalid]="
392                 storageClassForm.controls.glacier_restore_days.invalid &&
393                 storageClassForm.controls.glacier_restore_days.dirty
394               "
395               [invalidText]="glacierRestoreError"
396             >
397             </cds-number>
398             <ng-template #glacierRestoreError>
399               <span
400                 class="invalid-feedback"
401                 *ngIf="storageClassForm.showError('glacier_restore_days', formDir, 'pattern')"
402                 i18n
403                 >The entered value must be a positive integer.</span
404               >
405               <span
406                 class="invalid-feedback"
407                 *ngIf="storageClassForm.showError('glacier_restore_days', formDir, 'lockDays')"
408                 i18n
409                 >Glacier Restore Days must be positive.</span
410               >
411             </ng-template>
412           </div>
413         </div>
414       </div>
415       } @if( isTierMatch( TIER_TYPE.CLOUD_TIER, TIER_TYPE.GLACIER )){
416       <fieldset>
417         <div>
418           <ng-template #title>
419             <h5 class="cds--accordion__title cd-header">Advanced</h5>
420           </ng-template>
421           <fieldset>
422             <cds-accordion size="lg"
423                            class="form-item">
424               <cds-accordion-item
425                 [title]="title"
426                 id="advanced-fieldset"
427                 (selected)="showAdvanced = !showAdvanced"
428               >
429                 <!-- Multi Part Sync Threshold -->
430                 <div class="form-item form-item-append"
431                      cdsRow>
432                   <div cdsCol>
433                     <cds-text-label
434                       labelInputID="multipart_sync_threshold"
435                       i18n
436                       [helperText]="helpTextLabels.multipartSyncThresholdText"
437                       cdOptionalField="Multipart Sync Threshold"
438                       >Multipart Sync Threshold
439                       <input
440                         cdsText
441                         type="text"
442                         id="multipart_sync_threshold"
443                         formControlName="multipart_sync_threshold"
444                         cdDimlessBinary
445                       />
446                     </cds-text-label>
447                   </div>
448                   <div cdsCol>
449                     <cds-text-label
450                       labelInputID="multipart_min_part_size"
451                       i18n
452                       [helperText]="helpTextLabels.multipartMinPartText"
453                       cdOptionalField="Multipart Minimum Part Size"
454                       >Multipart Minimum Part Size
455                       <input
456                         cdsText
457                         type="text"
458                         id="multipart_min_part_size"
459                         formControlName="multipart_min_part_size"
460                         cdDimlessBinary
461                       />
462                     </cds-text-label>
463                   </div>
464                 </div>
465                 <!-- ACLs -->
466                 <div>
467                   <legend class="cd-header"
468                           i18n>ACLs Mapping</legend>
469                   <ng-container formArrayName="acls">
470                     @for (acl of acls.controls; let i = $index; track acl) {
471                     <ng-container [formGroupName]="i">
472                       <div class="form-item form-item-append"
473                            cdsRow>
474                         <div cdsCol
475                              [columnNumbers]="{ lg: 7 }">
476                           <cds-select id="type"
477                                       formControlName="type"
478                                       i18n-label
479                                       label="Type">
480                             @for (type of typeOptions; track type.value) {
481                             <option [value]="type.value"
482                                     i18n>
483                               {{ type.label }}
484                             </option>
485                             }
486                           </cds-select>
487                         </div>
488                       </div>
489                       <div cdsRow
490                            class="form-item form-item-append">
491                         <div cdsCol>
492                           <cds-text-label
493                             labelInputID="source_id"
494                             i18n
495                             [helperText]="getAclHelperText(acl.get('type')?.value, 'source')"
496                             [invalid]="
497                               acl.get('source_id')?.invalid && acl.get('source_id')?.touched
498                             "
499                             [invalidText]="
500                             acl.get('source_id')?.errors?.['required'] ? 'This field is required.' :
501                             acl.get('source_id')?.errors?.['email'] ? 'Please enter a valid email address.' :
502                             acl.get('source_id')?.errors?.['invalidUrl'] ? 'Please enter a valid URL.' : ''
503                           "
504                           >
505                             {{ getAclLabel('source', acl.get('type')?.value) }}
506                             <input
507                               cdsText
508                               type="text"
509                               formControlName="source_id"
510                               [invalidText]="
511                             acl.get('source_id')?.errors?.['required'] ? 'This field is required.' :
512                             acl.get('source_id')?.errors?.['email'] ? 'Please enter a valid email address.' :
513                             acl.get('source_id')?.errors?.['invalidUrl'] ? 'Please enter a valid URL.' : ''
514                           "
515                             />
516                           </cds-text-label>
517                         </div>
518                         <div cdsCol>
519                           <cds-text-label
520                             labelInputID="dest_id"
521                             i18n
522                             [helperText]="getAclHelperText(acl.get('type')?.value, 'destination')"
523                             [invalid]="acl.get('dest_id')?.invalid && acl.get('dest_id')?.touched"
524                             [invalidText]="
525                               acl.get('dest_id')?.errors?.['required'] ? 'This field is required.' :
526                               acl.get('dest_id')?.errors?.['email'] ? 'Please enter a valid email address.' :
527                               acl.get('dest_id')?.errors?.['invalidUrl'] ? 'Please enter a valid URL.' : ''
528                             "
529                           >
530                             {{ getAclLabel('destination', acl.get('type')?.value) }}
531                             <input
532                               cdsText
533                               type="text"
534                               formControlName="dest_id"
535                               [invalidText]="
536                               acl.get('dest_id')?.errors?.['required'] ? 'This field is required.' :
537                               acl.get('dest_id')?.errors?.['email'] ? 'Please enter a valid email address.' :
538                               acl.get('dest_id')?.errors?.['invalidUrl'] ? 'Please enter a valid URL.' : ''
539                             "
540                             />
541                           </cds-text-label>
542                         </div>
543
544                         <div
545                           cdsCol
546                           [columnNumbers]="{ lg: 1, md: 1 }"
547                           class="item-action-btn spacing"
548                         >
549                           <cds-icon-button kind="primary"
550                                            size="sm"
551                                            (click)="addAcls(acls, i)">
552                             <svg cdsIcon="add"
553                                  size="32"
554                                  class="cds--btn__icon"></svg>
555                           </cds-icon-button>
556                         </div>
557                         <div cdsCol
558                              [columnNumbers]="{ lg: 1, md: 1 }"
559                              class="item-action-btn">
560                           <cds-icon-button kind="danger"
561                                            size="sm"
562                                            (click)="removeAcl(i)">
563                             <svg cdsIcon="trash-can"
564                                  size="32"
565                                  class="cds--btn__icon"></svg>
566                           </cds-icon-button>
567                         </div>
568                       </div>
569                     </ng-container>
570                     }
571                   </ng-container>
572                 </div>
573               </cds-accordion-item>
574             </cds-accordion>
575           </fieldset>
576         </div>
577       </fieldset>
578       } @if( isTierMatch( TIER_TYPE.CLOUD_TIER, TIER_TYPE.GLACIER )){
579       <cd-alert-panel type="warning"
580                       spacingClass="mb-2">
581         <span i18n>RGW service would be restarted after creating the storage class.</span>
582       </cd-alert-panel>
583       }
584       <cd-form-button-panel
585         (submitActionEvent)="submitAction()"
586         [form]="storageClassForm"
587         [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
588         wrappingClass="text-right"
589       ></cd-form-button-panel>
590     </form>
591   </ng-container>
592 </div>