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