]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/blob
cdcb637551f718bb9dd7bd7a33b5f7676f10989d
[ceph-ci.git] /
1 <cd-modal [pageURL]="pageURL"
2           [modalRef]="activeModal">
3   <span class="modal-title"
4         i18n>{{ action | titlecase }} {{ resource | upperFirst }}</span>
5   <ng-container class="modal-content">
6     <form #frm="ngForm"
7           [formGroup]="serviceForm"
8           novalidate>
9       <div class="modal-body">
10         <cd-alert-panel *ngIf="serviceForm.controls.service_type.value === 'rgw' && showRealmCreationForm"
11                         type="info"
12                         spacingClass="mb-3"
13                         i18n>
14           <a class="text-decoration-underline"
15              (click)="createMultisiteSetup()">
16              Click here</a> to create a new Realm/Zone Group/Zone
17         </cd-alert-panel>
18
19         <cd-alert-panel *ngIf="serviceForm.controls.service_type.value === 'oauth2-proxy'"
20                         type="info"
21                         spacingClass="mb-3"
22                         i18n>
23           Authentication must be enabled in an active `mgtm-gateway` service to enable Single Sign-On(SSO) with `oauth2-proxy`
24         </cd-alert-panel>
25         <cd-alert-panel *ngIf="serviceForm.controls.service_type.value === 'mgmt-gateway'"
26                         type="info"
27                         spacingClass="mb-3"
28                         i18n>
29           With an active mgmt-gateway service, the dashboard will continue to be served on {{currentURL}}:{{port}} and all other services will be accessible from {{currentURL}}:{{port}}/service_name
30         </cd-alert-panel>
31
32         <cd-alert-panel *ngIf="serviceForm.controls.service_type.value === 'smb'"
33                         type="warning"
34                         spacingClass="mb-3"
35                         i18n>
36           SMB service management is intended for advanced users only.
37           For most scenarios, it is  recommended to use the SMB module instead.
38           To manage SMB clusters and shares, please visit the <a routerLink="/cephfs/smb">SMB page</a>.
39         </cd-alert-panel>
40
41         <!-- Service type -->
42         <div class="form-group row">
43           <label class="cd-col-form-label required"
44                  for="service_type"
45                  i18n>Type</label>
46           <div class="cd-col-form-input">
47             <select id="service_type"
48                     name="service_type"
49                     class="form-select"
50                     formControlName="service_type"
51                     (change)="onServiceTypeChange($event.target.value)">
52               <option i18n
53                       [ngValue]="null">-- Select a service type --</option>
54               <option *ngFor="let serviceType of serviceTypes"
55                       [value]="serviceType">
56                 {{ serviceType }}
57               </option>
58             </select>
59             <span class="invalid-feedback"
60                   *ngIf="serviceForm.showError('service_type', frm, 'required')"
61                   i18n>This field is required.</span>
62           </div>
63         </div>
64
65         <!-- backend_service -->
66         <div *ngIf="serviceForm.controls.service_type.value === 'ingress'"
67              class="form-group row">
68           <label i18n
69                  class="cd-col-form-label"
70                  [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
71                  for="backend_service">Backend Service</label>
72           <div class="cd-col-form-input">
73             <select id="backend_service"
74                     name="backend_service"
75                     class="form-select"
76                     formControlName="backend_service"
77                     (change)="prePopulateId()">
78               <option *ngIf="services === null"
79                       [ngValue]="null"
80                       i18n>Loading...</option>
81               <option *ngIf="services !== null && services.length === 0"
82                       [ngValue]="null"
83                       i18n>-- No service available --</option>
84               <option *ngIf="services !== null && services.length > 0"
85                       [ngValue]="null"
86                       i18n>-- Select an existing service --</option>
87               <option *ngFor="let service of services"
88                       [value]="service.service_name">{{ service.service_name }}</option>
89             </select>
90             <span class="invalid-feedback"
91                   *ngIf="serviceForm.showError('backend_service', frm, 'required')"
92                   i18n>This field is required.</span>
93           </div>
94         </div>
95
96         <!-- NVMe/TCP -->
97         <!-- Block Pool -->
98         <div class="form-group row"
99              *ngIf="serviceForm.controls.service_type.value === 'nvmeof'">
100           <label i18n
101                  class="cd-col-form-label required"
102                  for="pool">Block Pool</label>
103           <div class="cd-col-form-input">
104             <select id="pool"
105                     name="pool"
106                     class="form-select"
107                     formControlName="pool"
108                     (change)="setNvmeServiceId()">
109               <option *ngIf="rbdPools === null"
110                       [ngValue]="null"
111                       i18n>Loading...</option>
112               <option *ngIf="rbdPools && rbdPools.length === 0"
113                       [ngValue]="null"
114                       i18n>-- No block pools available --</option>
115               <option *ngIf="rbdPools && rbdPools.length > 0"
116                       [ngValue]="null"
117                       i18n>-- Select a pool --</option>
118               <option *ngFor="let pool of rbdPools"
119                       [value]="pool.pool_name">{{ pool.pool_name }}</option>
120             </select>
121             <cd-help-text i18n>
122               An RBD application-enabled pool in which the gateway configuration can be managed.
123             </cd-help-text>
124             <span class="invalid-feedback"
125                   *ngIf="serviceForm.showError('pool', frm, 'required')"
126                   i18n>This field is required.</span>
127           </div>
128         </div>
129
130         <!-- Group Name -->
131         <div class="form-group row"
132              *ngIf="serviceForm.controls.service_type.value === 'nvmeof'">
133           <label class="cd-col-form-label required"
134                  for="group">
135             <span i18n>Group Name</span>
136           </label>
137           <div class="cd-col-form-input">
138             <div class="input-group">
139               <input id="group"
140                      class="form-control"
141                      type="text"
142                      formControlName="group"
143                      (change)="setNvmeServiceId()">
144             </div>
145             <cd-help-text i18n>
146               The name of the gateway group.
147             </cd-help-text>
148             <span class="invalid-feedback"
149                   *ngIf="serviceForm.showError('service_id', frm, 'required')"
150                   i18n>This field is required.</span>
151           </div>
152         </div>
153
154         <!-- Service id -->
155         <div class="form-group row"
156              *ngIf="serviceForm.controls.service_type.value !== 'snmp-gateway'">
157           <label class="cd-col-form-label"
158                  [ngClass]="{'required': ['mds', 'rgw', 'nfs', 'iscsi', 'nvmeof', 'smb', 'ingress'].includes(serviceForm.controls.service_type.value)}"
159                  for="service_id">
160             <span i18n>Service Name</span>
161           </label>
162           <div class="cd-col-form-input">
163             <div class="input-group">
164               <span class="input-group-text"
165                     *ngIf="serviceForm.controls.service_type.value && ['mds', 'rgw', 'nfs', 'iscsi', 'nvmeof', 'smb', 'ingress'].includes(serviceForm.controls.service_type.value)"
166                     for="userId"
167                     i18n>{{serviceForm.controls.service_type.value}}.
168               </span>
169               <input id="service_id"
170                      class="form-control"
171                      type="text"
172                      formControlName="service_id">
173             </div>
174             <span class="invalid-feedback"
175                   *ngIf="serviceForm.showError('service_id', frm, 'required')"
176                   i18n>This field is required.</span>
177             <span class="invalid-feedback"
178                   *ngIf="serviceForm.showError('service_id', frm, 'uniqueName')"
179                   i18n>This service id is already in use.</span>
180             <span class="invalid-feedback"
181                   *ngIf="serviceForm.showError('service_id', frm, 'mdsPattern')"
182                   i18n>MDS service id must start with a letter and contain alphanumeric characters or '.', '-', and '_'</span>
183           </div>
184         </div>
185
186         <div class="form-group row"
187              *ngIf="serviceForm.controls.service_type.value === 'rgw'">
188           <label class="cd-col-form-label"
189                  for="realm_name"
190                  i18n>Realm</label>
191           <div class="cd-col-form-input">
192             <select class="form-select"
193                     id="realm_name"
194                     formControlName="realm_name"
195                     name="realm_name"
196                     [attr.disabled]="realmList.length === 0  || editing ? true : null">
197             <option *ngIf="realmList.length === 0"
198                     i18n
199                     selected>-- No realm available --</option>
200             <option *ngFor="let realm of realmList"
201                     [value]="realm.name">
202                   {{ realm.name }}
203             </option>
204             </select>
205           </div>
206         </div>
207
208         <div class="form-group row"
209              *ngIf="serviceForm.controls.service_type.value === 'rgw'">
210           <label class="cd-col-form-label"
211                  for="zonegroup_name"
212                  i18n>Zone Group</label>
213           <div class="cd-col-form-input">
214             <select class="form-select"
215                     id="zonegroup_name"
216                     formControlName="zonegroup_name"
217                     name="zonegroup_name"
218                     [attr.disabled]="zonegroupList.length === 0  || editing ? true : null">
219               <option *ngFor="let zonegroup of zonegroupList"
220                       [value]="zonegroup.name">
221               {{ zonegroup.name }}
222               </option>
223             </select>
224           </div>
225         </div>
226
227         <div class="form-group row"
228              *ngIf="serviceForm.controls.service_type.value === 'rgw'">
229           <label class="cd-col-form-label"
230                  for="zone_name"
231                  i18n>Zone</label>
232           <div class="cd-col-form-input">
233             <select class="form-select"
234                     id="zone_name"
235                     formControlName="zone_name"
236                     name="zone_name"
237                     [attr.disabled]="zoneList.length === 0  || editing ? true : null">
238               <option *ngFor="let zone of zoneList"
239                       [value]="zone.name">
240               {{ zone.name }}
241               </option>
242             </select>
243           </div>
244         </div>
245
246         <!-- unmanaged -->
247         <div class="form-group row">
248           <div class="cd-col-form-offset">
249             <div class="custom-control custom-checkbox">
250               <input class="custom-control-input"
251                      id="unmanaged"
252                      type="checkbox"
253                      formControlName="unmanaged">
254               <label class="custom-control-label m-0"
255                      for="unmanaged"
256                      i18n>Unmanaged</label>
257               <cd-help-text i18n>If Unmanaged is selected, the orchestrator will not start or stop any daemons associated with this service. Placement and all other properties will be ignored.</cd-help-text>
258             </div>
259           </div>
260         </div>
261
262         <!-- Placement -->
263         <div *ngIf="!serviceForm.controls.unmanaged.value"
264              class="form-group row">
265           <label class="cd-col-form-label"
266                  for="placement"
267                  i18n>Placement</label>
268           <div class="cd-col-form-input">
269             <select id="placement"
270                     class="form-select"
271                     formControlName="placement"
272                     (change)="onPlacementChange($event.target.value)">
273               <option i18n
274                       value="hosts">Hosts</option>
275               <option i18n
276                       value="label">Label</option>
277             </select>
278           </div>
279         </div>
280
281         <!-- Label -->
282         <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'label'"
283              class="form-group row">
284           <label i18n
285                  class="cd-col-form-label"
286                  for="label">Label</label>
287           <div class="cd-col-form-input">
288             <input id="label"
289                    class="form-control"
290                    type="text"
291                    formControlName="label"
292                    [ngbTypeahead]="searchLabels"
293                    (focus)="labelFocus.next($any($event).target.value)"
294                    (click)="labelClick.next($any($event).target.value)">
295             <span class="invalid-feedback"
296                   *ngIf="serviceForm.showError('label', frm, 'required')"
297                   i18n>This field is required.</span>
298           </div>
299         </div>
300
301         <!-- Hosts -->
302         <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'hosts'"
303              class="form-group row">
304           <label class="cd-col-form-label"
305                  for="hosts"
306                  i18n>Hosts</label>
307           <div class="cd-col-form-input">
308             <cd-select-badges id="hosts"
309                               [data]="serviceForm.controls.hosts.value"
310                               [options]="hosts.options"
311                               [messages]="hosts.messages">
312             </cd-select-badges>
313           </div>
314         </div>
315
316         <!-- Count -->
317         <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value !== 'nvmeof'"
318              class="form-group row">
319           <label class="cd-col-form-label"
320                  for="count">
321             <span i18n>Count</span>
322           </label>
323           <div class="cd-col-form-input">
324             <input id="count"
325                    class="form-control"
326                    type="number"
327                    formControlName="count"
328                    min="1">
329             <cd-help-text i18n>Number of deamons that will be deployed</cd-help-text>
330             <span class="invalid-feedback"
331                   *ngIf="serviceForm.showError('count', frm, 'min')"
332                   i18n>The value must be at least 1.</span>
333             <span class="invalid-feedback"
334                   *ngIf="serviceForm.showError('count', frm, 'pattern')"
335                   i18n>The entered value needs to be a number.</span>
336           </div>
337         </div>
338
339         <!-- RGW -->
340         <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'rgw'">
341           <!-- rgw_frontend_port -->
342           <div class="form-group row">
343             <label i18n
344                    class="cd-col-form-label"
345                    for="rgw_frontend_port">Port</label>
346             <div class="cd-col-form-input">
347               <input id="rgw_frontend_port"
348                      class="form-control"
349                      type="number"
350                      formControlName="rgw_frontend_port"
351                      min="1"
352                      max="65535">
353               <span class="invalid-feedback"
354                     *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'pattern')"
355                     i18n>The entered value needs to be a number.</span>
356               <span class="invalid-feedback"
357                     *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'min')"
358                     i18n>The value must be at least 1.</span>
359               <span class="invalid-feedback"
360                     *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'max')"
361                     i18n>The value cannot exceed 65535.</span>
362             </div>
363           </div>
364         </ng-container>
365
366         <!-- iSCSI -->
367         <!-- pool -->
368         <div class="form-group row"
369              *ngIf="serviceForm.controls.service_type.value === 'iscsi'">
370           <label i18n
371                  class="cd-col-form-label required"
372                  for="pool">Pool</label>
373           <div class="cd-col-form-input">
374             <select id="pool"
375                     name="pool"
376                     class="form-select"
377                     formControlName="pool">
378               <option *ngIf="pools === null"
379                       [ngValue]="null"
380                       i18n>Loading...</option>
381               <option *ngIf="pools && pools.length === 0"
382                       [ngValue]="null"
383                       i18n>-- No pools available --</option>
384               <option *ngIf="pools && pools.length > 0"
385                       [ngValue]="null"
386                       i18n>-- Select a pool --</option>
387               <option *ngFor="let pool of pools"
388                       [value]="pool.pool_name">{{ pool.pool_name }}</option>
389             </select>
390             <span class="invalid-feedback"
391                   *ngIf="serviceForm.showError('pool', frm, 'required')"
392                   i18n>This field is required.</span>
393           </div>
394         </div>
395
396         <!-- fields in iSCSI which are hidden when unmanaged is true -->
397         <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'iscsi'">
398           <!-- trusted_ip_list -->
399           <div class="form-group row">
400             <label class="cd-col-form-label"
401                    for="trusted_ip_list">
402               <span i18n>Trusted IPs</span>
403               <cd-helper>
404                 <span i18n>Comma separated list of IP addresses.</span>
405                 <br>
406                 <span i18n>Please add the <b>Ceph Manager</b> IP addresses here, otherwise the iSCSI gateways can't be reached.</span>
407               </cd-helper>
408             </label>
409             <div class="cd-col-form-input">
410               <input id="trusted_ip_list"
411                      class="form-control"
412                      type="text"
413                      formControlName="trusted_ip_list">
414             </div>
415           </div>
416
417           <!-- api_port -->
418           <div class="form-group row">
419             <label i18n
420                    class="cd-col-form-label"
421                    for="api_port">Port</label>
422             <div class="cd-col-form-input">
423               <input id="api_port"
424                      class="form-control"
425                      type="number"
426                      formControlName="api_port"
427                      min="1"
428                      max="65535">
429               <span class="invalid-feedback"
430                     *ngIf="serviceForm.showError('api_port', frm, 'pattern')"
431                     i18n>The entered value needs to be a number.</span>
432               <span class="invalid-feedback"
433                     *ngIf="serviceForm.showError('api_port', frm, 'min')"
434                     i18n>The value must be at least 1.</span>
435               <span class="invalid-feedback"
436                     *ngIf="serviceForm.showError('api_port', frm, 'max')"
437                     i18n>The value cannot exceed 65535.</span>
438             </div>
439           </div>
440
441           <!-- api_user -->
442           <div class="form-group row">
443             <label i18n
444                    class="cd-col-form-label"
445                    [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
446                    for="api_user">User</label>
447             <div class="cd-col-form-input">
448               <input id="api_user"
449                      class="form-control"
450                      type="text"
451                      formControlName="api_user">
452               <span class="invalid-feedback"
453                     *ngIf="serviceForm.showError('api_user', frm, 'required')"
454                     i18n>This field is required.</span>
455             </div>
456           </div>
457
458           <!-- api_password -->
459           <div class="form-group row">
460             <label i18n
461                    class="cd-col-form-label"
462                    [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
463                    for="api_password">Password</label>
464             <div class="cd-col-form-input">
465               <div class="input-group">
466                 <input id="api_password"
467                        class="form-control"
468                        type="password"
469                        autocomplete="new-password"
470                        formControlName="api_password">
471                 <button type="button"
472                         class="btn btn-light"
473                         cdPasswordButton="api_password">
474                 </button>
475                 <cd-copy-2-clipboard-button source="api_password">
476                 </cd-copy-2-clipboard-button>
477                 <span class="invalid-feedback"
478                       *ngIf="serviceForm.showError('api_password', frm, 'required')"
479                       i18n>This field is required.</span>
480               </div>
481             </div>
482           </div>
483         </ng-container>
484
485         <!-- smb -->
486         <ng-container *ngIf="serviceForm.controls.service_type.value === 'smb'">
487           <div class="form-group row">
488             <label class="cd-col-form-label required"
489                    for="cluster_id"
490                    i18n>
491               Cluster id
492               <cd-helper>
493                 <span>A short name identifying the SMB “cluster”. In this case a cluster is simply a management unit of one or more Samba services sharing a common configuration,
494                    and may not provide actual clustering or availability mechanisms.</span>
495               </cd-helper>
496             </label>
497             <div class="cd-col-form-input">
498               <input id="cluster_id"
499                      class="form-control"
500                      type="text"
501                      formControlName="cluster_id"
502                      placeholder="foo"
503                      i18n-placeholder>
504               <span class="invalid-feedback"
505                     *ngIf="serviceForm.showError('cluster_id', frm, 'required')"
506                     i18n>This field is required.</span>
507             </div>
508           </div>
509
510           <div class="form-group row">
511             <label class="cd-col-form-label required"
512                    for="config_uri">
513               <span i18n>Config URI</span>
514               <cd-helper i18n>
515                 Configuration source that should be loaded by the samba-container as the primary configuration file.
516               </cd-helper>
517             </label>
518             <div class="cd-col-form-input">
519               <input id="config_uri"
520                      class="form-control"
521                      type="text"
522                      formControlName="config_uri"
523                      placeholder="rados://.smb/foo/scc.toml"
524                      i18n-placeholder>
525               <span class="invalid-feedback"
526                     *ngIf="serviceForm.showError('config_uri', frm, 'required')"
527                     i18n>This field is required.</span>
528               <span class="invalid-feedback"
529                     *ngIf="serviceForm.showError('config_uri', frm, 'configUriPattern')"
530                     i18n>The value must start with either 'http:', 'https:', 'rados:' or 'rados:mon-config-key:'</span>
531             </div>
532           </div>
533
534           <div class="form-group row"
535                formGroupName="features">
536             <label class="cd-col-form-label"
537                    for="features"
538                    i18n>Features
539               <cd-helper>
540                 <span>Pre-defined terms enabling specific deployment characteristics.</span>
541               </cd-helper>
542             </label>
543             <div class="cd-col-form-input">
544               <div class="custom-control custom-checkbox"
545                    *ngFor="let feature of smbFeaturesList">
546                 <input class="custom-control-input"
547                        type="checkbox"
548                        name="{{feature}}"
549                        id="{{feature}}"
550                        formControlName="{{feature}}">
551                 <label class="custom-control-label"
552                        for="{{feature}}"
553                        i18n>{{feature}}
554                 </label>
555               </div>
556             </div>
557           </div>
558
559           <div class="form-item">
560             <cd-text-label-list formControlName="custom_dns"
561                                 label="Custom DNS"
562                                 helperText="IP addresses that will be used as the DNS servers for a Samba container."
563                                 placeholder="192.168.76.204">
564             </cd-text-label-list>
565           </div>
566
567           <div class="form-group row">
568             <label class="cd-col-form-label"
569                    for="join_sources">
570               <span i18n>Join sources</span>
571               <cd-helper i18n>
572                 <span>Comma separated list of URIs.</span>
573                 <br>
574                 <span>A list of values that will be used to identify where authentication data that will be used to perform domain joins are located.</span>
575               </cd-helper>
576             </label>
577             <div class="cd-col-form-input">
578               <input id="join_sources"
579                      class="form-control"
580                      type="text"
581                      formControlName="join_sources"
582                      placeholder="rados:mon-config-key:smb/config/foo/join1.json"
583                      i18n-placeholder>
584             </div>
585           </div>
586
587           <div class="form-group row">
588             <label class="cd-col-form-label"
589                    for="user_sources">
590               <span i18n>User sources</span>
591               <cd-helper i18n>
592                 <span>Comma separated list of URIs.</span>
593                 <br>
594                 <span>A list of pseudo-uris containing data the samba-container can use to create users (and/or
595                   groups). A ceph based samba container may typically use a rados uri
596                   or a mon config-key store uri </span>
597               </cd-helper>
598             </label>
599             <div class="cd-col-form-input">
600               <input id="user_sources"
601                      class="form-control"
602                      type="text"
603                      formControlName="user_sources"
604                      placeholder="rados:mon-config-key:smb/config/foo/join2.json"
605                      i18n-placeholder>
606             </div>
607           </div>
608
609           <div class="form-group row">
610             <label class="cd-col-form-label"
611                    for="include_ceph_users">
612               <span i18n>Ceph users</span>
613               <cd-helper i18n>
614                 <span>Comma separated list of Ceph users.</span>
615                 <br>
616                 <span>A list of cephx user names that the Samba Containers may use.</span>
617               </cd-helper>
618             </label>
619             <div class="cd-col-form-input">
620               <input id="include_ceph_users"
621                      class="form-control"
622                      type="text"
623                      formControlName="include_ceph_users"
624                      placeholder="client.smb.fs.cluster.foo"
625                      i18n-placeholder>
626             </div>
627           </div>
628
629         </ng-container>
630
631         <!-- Ingress -->
632         <ng-container *ngIf="serviceForm.controls.service_type.value === 'ingress'">
633           <!-- virtual_ip -->
634           <div class="form-group row">
635             <label class="cd-col-form-label"
636                    [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
637                    for="virtual_ip">
638               <span i18n>Virtual IP</span>
639               <cd-helper>
640                 <span i18n>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</span>
641               </cd-helper>
642             </label>
643             <div class="cd-col-form-input">
644               <input id="virtual_ip"
645                      class="form-control"
646                      type="text"
647                      formControlName="virtual_ip">
648               <span class="invalid-feedback"
649                     *ngIf="serviceForm.showError('virtual_ip', frm, 'required')"
650                     i18n>This field is required.</span>
651             </div>
652           </div>
653
654           <!-- frontend_port -->
655           <div class="form-group row">
656             <label class="cd-col-form-label"
657                    [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
658                    for="frontend_port">
659               <span i18n>Frontend Port</span>
660               <cd-helper>
661                 <span i18n>The port used to access the ingress service.</span>
662               </cd-helper>
663             </label>
664             <div class="cd-col-form-input">
665               <input id="frontend_port"
666                      class="form-control"
667                      type="number"
668                      formControlName="frontend_port"
669                      min="1"
670                      max="65535">
671               <span class="invalid-feedback"
672                     *ngIf="serviceForm.showError('frontend_port', frm, 'pattern')"
673                     i18n>The entered value needs to be a number.</span>
674               <span class="invalid-feedback"
675                     *ngIf="serviceForm.showError('frontend_port', frm, 'min')"
676                     i18n>The value must be at least 1.</span>
677               <span class="invalid-feedback"
678                     *ngIf="serviceForm.showError('frontend_port', frm, 'max')"
679                     i18n>The value cannot exceed 65535.</span>
680               <span class="invalid-feedback"
681                     *ngIf="serviceForm.showError('frontend_port', frm, 'required')"
682                     i18n>This field is required.</span>
683             </div>
684           </div>
685
686           <!-- monitor_port -->
687           <div class="form-group row">
688             <label class="cd-col-form-label"
689                    [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
690                    for="monitor_port">
691               <span i18n>Monitor Port</span>
692               <cd-helper>
693                 <span i18n>The port used by haproxy for load balancer status.</span>
694               </cd-helper>
695             </label>
696             <div class="cd-col-form-input">
697               <input id="monitor_port"
698                      class="form-control"
699                      type="number"
700                      formControlName="monitor_port"
701                      min="1"
702                      max="65535">
703               <span class="invalid-feedback"
704                     *ngIf="serviceForm.showError('monitor_port', frm, 'pattern')"
705                     i18n>The entered value needs to be a number.</span>
706               <span class="invalid-feedback"
707                     *ngIf="serviceForm.showError('monitor_port', frm, 'min')"
708                     i18n>The value must be at least 1.</span>
709               <span class="invalid-feedback"
710                     *ngIf="serviceForm.showError('monitor_port', frm, 'max')"
711                     i18n>The value cannot exceed 65535.</span>
712               <span class="invalid-feedback"
713                     *ngIf="serviceForm.showError('monitor_port', frm, 'required')"
714                     i18n>This field is required.</span>
715             </div>
716           </div>
717           <!-- virtual_interface_networks -->
718           <div class="form-group row"
719                *ngIf="!serviceForm.controls.unmanaged.value">
720             <label class="cd-col-form-label"
721                    for="virtual_interface_networks">
722               <span i18n>CIDR Networks</span>
723               <cd-helper>
724                 <span i18n>A list of networks to identify which network interface to use for the virtual IP address.</span>
725               </cd-helper>
726             </label>
727             <div class="cd-col-form-input">
728               <input id="virtual_interface_networks"
729                      class="form-control"
730                      type="text"
731                      formControlName="virtual_interface_networks">
732             </div>
733           </div>
734         </ng-container>
735
736         <!-- SNMP-Gateway -->
737         <ng-container *ngIf="serviceForm.controls.service_type.value === 'snmp-gateway'">
738           <!-- snmp-version -->
739           <div class="form-group row">
740             <label class="cd-col-form-label required"
741                    for="snmp_version"
742                    i18n>Version</label>
743             <div class="cd-col-form-input">
744               <select id="snmp_version"
745                       name="snmp_version"
746                       class="form-select"
747                       formControlName="snmp_version"
748                       (change)="clearValidations()">
749                 <option i18n
750                         [ngValue]="null">-- Select SNMP version --</option>
751                 <option *ngFor="let snmpVersion of ['V2c', 'V3']"
752                         [value]="snmpVersion">{{ snmpVersion }}</option>
753               </select>
754               <span class="invalid-feedback"
755                     *ngIf="serviceForm.showError('snmp_version', frm, 'required')"
756                     i18n>This field is required.</span>
757             </div>
758           </div>
759           <!-- Destination -->
760           <div class="form-group row">
761             <label class="cd-col-form-label required"
762                    for="snmp_destination">
763               <span i18n>Destination</span>
764               <cd-helper>
765                 <span i18n>Must be of the format hostname:port.</span>
766               </cd-helper>
767             </label>
768             <div class="cd-col-form-input">
769               <input id="snmp_destination"
770                      class="form-control"
771                      type="text"
772                      formControlName="snmp_destination">
773               <span class="invalid-feedback"
774                     *ngIf="serviceForm.showError('snmp_destination', frm, 'required')"
775                     i18n>This field is required.</span>
776               <span class="invalid-feedback"
777                     *ngIf="serviceForm.showError('snmp_destination', frm, 'snmpDestinationPattern')"
778                     i18n>The value does not match the pattern: <strong>hostname:port</strong></span>
779             </div>
780           </div>
781           <!-- Engine id for snmp V3 -->
782           <div class="form-group row"
783                *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
784             <label class="cd-col-form-label required"
785                    for="engine_id">
786               <span i18n>Engine Id</span>
787               <cd-helper>
788                 <span i18n>Unique identifier for the device (in hex).</span>
789               </cd-helper>
790             </label>
791             <div class="cd-col-form-input">
792               <input id="engine_id"
793                      class="form-control"
794                      type="text"
795                      formControlName="engine_id">
796               <span class="invalid-feedback"
797                     *ngIf="serviceForm.showError('engine_id', frm, 'required')"
798                     i18n>This field is required.</span>
799               <span class="invalid-feedback"
800                     *ngIf="serviceForm.showError('engine_id', frm, 'snmpEngineIdPattern')"
801                     i18n>The value does not match the pattern: <strong>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.</strong></span>
802             </div>
803           </div>
804           <!-- Auth protocol for snmp V3 -->
805           <div class="form-group row"
806                *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
807             <label class="cd-col-form-label required"
808                    for="auth_protocol"
809                    i18n>Auth Protocol</label>
810             <div class="cd-col-form-input">
811               <select id="auth_protocol"
812                       name="auth_protocol"
813                       class="form-select"
814                       formControlName="auth_protocol">
815                 <option i18n
816                         [ngValue]="null">-- Select auth protocol --</option>
817                 <option *ngFor="let authProtocol of ['SHA', 'MD5']"
818                         [value]="authProtocol">
819                   {{ authProtocol }}
820                 </option>
821               </select>
822               <span class="invalid-feedback"
823                     *ngIf="serviceForm.showError('auth_protocol', frm, 'required')"
824                     i18n>This field is required.</span>
825             </div>
826           </div>
827           <!-- Privacy protocol for snmp V3 -->
828           <div class="form-group row"
829                *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
830             <label class="cd-col-form-label"
831                    for="privacy_protocol"
832                    i18n>Privacy Protocol</label>
833             <div class="cd-col-form-input">
834               <select id="privacy_protocol"
835                       name="privacy_protocol"
836                       class="form-select"
837                       formControlName="privacy_protocol">
838                 <option i18n
839                         [ngValue]="null">-- Select privacy protocol --</option>
840                 <option *ngFor="let privacyProtocol of ['DES', 'AES']"
841                         [value]="privacyProtocol">
842                   {{ privacyProtocol }}
843                 </option>
844               </select>
845             </div>
846           </div>
847           <!-- Credentials -->
848           <fieldset>
849             <legend i18n>Credentials</legend>
850             <!-- snmp v2c snmp_community -->
851             <div class="form-group row"
852                  *ngIf="serviceForm.controls.snmp_version.value === 'V2c'">
853               <label class="cd-col-form-label required"
854                      for="snmp_community">
855                 <span i18n>SNMP Community</span>
856               </label>
857               <div class="cd-col-form-input">
858                 <input id="snmp_community"
859                        class="form-control"
860                        type="text"
861                        formControlName="snmp_community">
862                 <span class="invalid-feedback"
863                       *ngIf="serviceForm.showError('snmp_community', frm, 'required')"
864                       i18n>This field is required.</span>
865               </div>
866             </div>
867             <!-- snmp v3 auth username -->
868             <div class="form-group row"
869                  *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
870               <label class="cd-col-form-label required"
871                      for="snmp_v3_auth_username">
872                 <span i18n>Username</span>
873               </label>
874               <div class="cd-col-form-input">
875                 <input id="snmp_v3_auth_username"
876                        class="form-control"
877                        type="text"
878                        formControlName="snmp_v3_auth_username">
879                 <span class="invalid-feedback"
880                       *ngIf="serviceForm.showError('snmp_v3_auth_username', frm, 'required')"
881                       i18n>This field is required.</span>
882               </div>
883             </div>
884             <!-- snmp v3 auth password -->
885             <div class="form-group row"
886                  *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
887               <label class="cd-col-form-label required"
888                      for="snmp_v3_auth_password">
889                 <span i18n>Password</span>
890               </label>
891               <div class="cd-col-form-input">
892                 <input id="snmp_v3_auth_password"
893                        class="form-control"
894                        type="password"
895                        formControlName="snmp_v3_auth_password">
896                 <span class="invalid-feedback"
897                       *ngIf="serviceForm.showError('snmp_v3_auth_password', frm, 'required')"
898                       i18n>This field is required.</span>
899               </div>
900             </div>
901             <!-- snmp v3 priv password -->
902             <div class="form-group row"
903                  *ngIf="serviceForm.controls.snmp_version.value === 'V3' && serviceForm.controls.privacy_protocol.value !== null && serviceForm.controls.privacy_protocol.value !== undefined">
904               <label class="cd-col-form-label required"
905                      for="snmp_v3_priv_password">
906                 <span i18n>Encryption</span>
907               </label>
908               <div class="cd-col-form-input">
909                 <input id="snmp_v3_priv_password"
910                        class="form-control"
911                        type="password"
912                        formControlName="snmp_v3_priv_password">
913                 <span class="invalid-feedback"
914                       *ngIf="serviceForm.showError('snmp_v3_priv_password', frm, 'required')"
915                       i18n>This field is required.</span>
916               </div>
917             </div>
918           </fieldset>
919         </ng-container>
920
921         <!-- oauth2-proxy -->
922         <ng-container *ngIf="serviceForm.controls.service_type.value === 'oauth2-proxy'">
923           <!-- provider_display_name -->
924           <div class="form-group row">
925             <label class="cd-col-form-label required"
926                    for="provider_display_name">
927               <span i18n>Provider display name</span>
928             </label>
929             <div class="cd-col-form-input">
930               <input id="provider_display_name"
931                      class="form-control"
932                      type="text"
933                      formControlName="provider_display_name"
934                      placeholder="My OIDC Provider"
935                      i18n-placeholder>
936               <cd-help-text i18n>The display name for the identity provider (IdP) in the UI.</cd-help-text>
937               <span class="invalid-feedback"
938                     *ngIf="serviceForm.showError('provider_display_name', frm, 'required')"
939                     i18n>This field is required.</span>
940             </div>
941           </div>
942           <!-- client_id -->
943           <div class="form-group row">
944             <label class="cd-col-form-label required"
945                    for="client_id">
946               <span i18n>Client ID</span>
947             </label>
948             <div class="cd-col-form-input">
949               <input id="client_id"
950                      class="form-control"
951                      type="text"
952                      formControlName="client_id"
953                      placeholder="oauth2-client">
954               <cd-help-text i18n>The client ID for authenticating with the IdP.</cd-help-text>
955               <span class="invalid-feedback"
956                     *ngIf="serviceForm.showError('client_id', frm, 'required')"
957                     i18n>This field is required.</span>
958             </div>
959           </div>
960           <!-- client_secret -->
961           <div class="form-group row">
962             <label class="cd-col-form-label required"
963                    for="client_secret">
964               <span i18n>Client secret</span>
965             </label>
966             <div class="cd-col-form-input">
967               <div class="input-group">
968                 <input id="client_secret"
969                        class="form-control"
970                        type="password"
971                        formControlName="client_secret">
972                 <span class="input-group-append">
973                   <button type="button"
974                           class="btn btn-light"
975                           cdPasswordButton="client_secret">
976                   </button>
977                   <cd-copy-2-clipboard-button source="client_secret">
978                   </cd-copy-2-clipboard-button>
979                 </span>
980               </div>
981               <cd-help-text i18n>The client secret for authenticating with the IdP.</cd-help-text>
982               <span class="invalid-feedback"
983                     *ngIf="serviceForm.showError('client_secret', frm, 'required')"
984                     i18n>This field is required.</span>
985             </div>
986           </div>
987           <!-- oidc_issuer_url -->
988           <div class="form-group row">
989             <label class="cd-col-form-label required"
990                    for="oidc_issuer_url">
991               <span i18n>OIDC Issuer URL</span>
992             </label>
993             <div class="cd-col-form-input">
994               <input id="oidc_issuer_url"
995                      class="form-control"
996                      type="text"
997                      formControlName="oidc_issuer_url"
998                      placeholder="https://<IdPs-domain>/realms/<realm-name>">
999               <cd-help-text i18n>The URL of the OpenID Connect (OIDC) issuer.</cd-help-text>
1000               <span class="invalid-feedback"
1001                     *ngIf="serviceForm.showError('oidc_issuer_url', frm, 'required')"
1002                     i18n>This field is required.</span>
1003               <span class="invalid-feedback"
1004                     *ngIf="serviceForm.showError('oidc_issuer_url', frm, 'validUrl')"
1005                     i18n>Invalid url.</span>
1006             </div>
1007           </div>
1008           <!-- https_address -->
1009           <div class="form-group row">
1010             <label class="cd-col-form-label"
1011                    for="https_address">
1012               <span i18n>Https address</span>
1013             </label>
1014             <div class="cd-col-form-input">
1015               <input id="https_address"
1016                      class="form-control"
1017                      type="text"
1018                      formControlName="https_address"
1019                      placeholder="0.0.0.0:4180">
1020               <cd-help-text i18n>The address for HTTPS connections as [IP|Hostname]:port.</cd-help-text>
1021               <span class="invalid-feedback"
1022                     *ngIf="serviceForm.showError('https_address', frm, 'invalidAddress')"
1023                     i18n>Format must be [IP|Hostname]:port and the port between 0 and 65535</span>
1024             </div>
1025           </div>
1026           <!-- redirect_url -->
1027           <div class="form-group row">
1028             <label class="cd-col-form-label"
1029                    for="redirect_url">
1030               <span i18n>Redirect URL</span>
1031             </label>
1032             <div class="cd-col-form-input">
1033               <input id="redirect_url"
1034                      class="form-control"
1035                      type="text"
1036                      formControlName="redirect_url"
1037                      placeholder="https://<IP|Hostname>:4180/oauth2/callback">
1038               <cd-help-text i18n>The URL the oauth2-proxy service will redirect to after a successful login.</cd-help-text>
1039             </div>
1040           </div>
1041           <!-- Allowlist_domains -->
1042           <div class="form-group row">
1043             <label class="cd-col-form-label"
1044                    for="allowlist_domains">
1045               <span i18n>Allowlist domains</span>
1046             </label>
1047             <div class="cd-col-form-input">
1048               <input id="allowlist_domains"
1049                      class="form-control"
1050                      type="text"
1051                      formControlName="allowlist_domains"
1052                      placeholder="domain1.com,192.168.100.1:8080">
1053               <cd-help-text i18n>Comma separated list of domains to be allowed to redirect to, used for login or logout.</cd-help-text>
1054             </div>
1055           </div>
1056         </ng-container>
1057
1058         <ng-container *ngIf="!serviceForm.controls.unmanaged.value && ['mgmt-gateway'].includes(serviceForm.controls.service_type.value)">
1059           <!-- port -->
1060           <div class="form-group row">
1061             <label i18n
1062                    class="cd-col-form-label"
1063                    for="port">Port</label>
1064             <div class="cd-col-form-input">
1065               <input id="port"
1066                      class="form-control"
1067                      type="number"
1068                      formControlName="port"
1069                      min="1"
1070                      max="65535">
1071               <span class="invalid-feedback"
1072                     *ngIf="serviceForm.showError('port', frm, 'pattern')"
1073                     i18n>The entered value needs to be a number.</span>
1074               <span class="invalid-feedback"
1075                     *ngIf="serviceForm.showError('port', frm, 'min')"
1076                     i18n>The value must be at least 1.</span>
1077               <span class="invalid-feedback"
1078                     *ngIf="serviceForm.showError('port', frm, 'max')"
1079                     i18n>The value cannot exceed 65535.</span>
1080             </div>
1081           </div>
1082           <!-- enable_auth -->
1083           <div class="form-item">
1084             <fieldset>
1085               <label class="cds--label"
1086                      for="pools"
1087                      i18n>Authentication</label>
1088                 <cds-checkbox i18n-label
1089                               id="enable_auth"
1090                               name="enable_auth"
1091                               formControlName="enable_auth">
1092                 Enable
1093                 <cd-help-text i18n>
1094                   Allows to enable authentication through an external Identity Provider (IdP) using Single Sign-On (SSO)
1095                 </cd-help-text>
1096               </cds-checkbox>
1097             </fieldset>
1098           </div>
1099           <!-- ssl_protocols -->
1100           <div class="form-item">
1101             <cds-combo-box type="multi"
1102                            label="SSL protocols"
1103                            selectionFeedback="top-after-reopen"
1104                            for="ssl_protocols"
1105                            name="ssl_protocols"
1106                            formControlName="ssl_protocols"
1107                            id="ssl_protocols"
1108                            placeholder="Select protocols..."
1109                            [appendInline]="true"
1110                            [items]="sslProtocolsItems"
1111                            i18n-placeholder
1112                            i18n>
1113               <cds-dropdown-list></cds-dropdown-list>
1114             </cds-combo-box>
1115           </div>
1116           <!-- ssl_ciphers -->
1117           <div class="form-group row">
1118           <label class="cd-col-form-label"
1119                  for="ssl_ciphers">
1120             <span i18n>SSL ciphers</span>
1121           </label>
1122           <div class="cd-col-form-input">
1123             <div class="input-group">
1124               <input id="ssl_ciphers"
1125                      class="form-control"
1126                      type="text"
1127                      formControlName="ssl_ciphers"
1128                      placeholder="ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256">
1129             </div>
1130             <cd-help-text i18n>Default cipher list used: <a href="https://ssl-config.mozilla.org/#server=nginx"
1131                                                             target="_blank">https://ssl-config.mozilla.org/#server=nginx</a></cd-help-text>
1132             <span class="invalid-feedback"
1133                   *ngIf="serviceForm.showError('ssl_ciphers', frm, 'invalidPattern')"
1134                   i18n>Invalid cipher suite. Each cipher must be separated by '-' and each cipher suite must be separated by ':'</span>
1135           </div>
1136         </div>
1137         </ng-container>
1138         <!-- RGW, Ingress, iSCSI, Oauth2-proxy & mgmt-gateway -->
1139         <ng-container *ngIf="!serviceForm.controls.unmanaged.value && ['rgw', 'iscsi', 'ingress', 'oauth2-proxy', 'mgmt-gateway'].includes(serviceForm.controls.service_type.value)">
1140           <!-- ssl -->
1141           <ng-container *ngIf="!['mgmt-gateway'].includes(serviceForm.controls.service_type.value)">
1142             <div class="form-group row">
1143               <div class="cd-col-form-offset">
1144                 <div class="custom-control custom-checkbox">
1145                   <input class="custom-control-input"
1146                          id="ssl"
1147                          type="checkbox"
1148                          formControlName="ssl">
1149                   <label class="custom-control-label"
1150                          for="ssl"
1151                          i18n>SSL</label>
1152                 </div>
1153               </div>
1154             </div>
1155           </ng-container>
1156           <!-- ssl_cert -->
1157           <div *ngIf="serviceForm.controls.ssl.value || ['mgmt-gateway'].includes(serviceForm.controls.service_type.value)"
1158                class="form-group row">
1159             <label class="cd-col-form-label"
1160                    for="ssl_cert">
1161               <span i18n>Certificate</span>
1162               <cd-helper i18n>The SSL certificate in PEM format.</cd-helper>
1163             </label>
1164             <div class="cd-col-form-input">
1165               <textarea id="ssl_cert"
1166                         class="form-control resize-vertical text-monospace text-pre"
1167                         formControlName="ssl_cert"
1168                         rows="5">
1169               </textarea>
1170               <input type="file"
1171                      (change)="fileUpload($event.target.files, 'ssl_cert')">
1172               <span class="invalid-feedback"
1173                     *ngIf="serviceForm.showError('ssl_cert', frm, 'required')"
1174                     i18n>This field is required.</span>
1175               <span class="invalid-feedback"
1176                     *ngIf="serviceForm.showError('ssl_cert', frm, 'pattern')"
1177                     i18n>Invalid SSL certificate.</span>
1178             </div>
1179           </div>
1180
1181           <!-- ssl_key -->
1182           <div *ngIf="(serviceForm.controls.ssl.value && !(['rgw', 'ingress'].includes(serviceForm.controls.service_type.value))) || ['mgmt-gateway'].includes(serviceForm.controls.service_type.value)"
1183                class="form-group row">
1184             <label class="cd-col-form-label"
1185                    for="ssl_key">
1186               <span i18n>Private key</span>
1187               <cd-helper i18n>The SSL private key in PEM format.</cd-helper>
1188             </label>
1189             <div class="cd-col-form-input">
1190               <textarea id="ssl_key"
1191                         class="form-control resize-vertical text-monospace text-pre"
1192                         formControlName="ssl_key"
1193                         rows="5">
1194               </textarea>
1195               <input type="file"
1196                      (change)="fileUpload($event.target.files,'ssl_key')">
1197               <span class="invalid-feedback"
1198                     *ngIf="serviceForm.showError('ssl_key', frm, 'required')"
1199                     i18n>This field is required.</span>
1200               <span class="invalid-feedback"
1201                     *ngIf="serviceForm.showError('ssl_key', frm, 'pattern')"
1202                     i18n>Invalid SSL private key.</span>
1203             </div>
1204           </div>
1205         </ng-container>
1206
1207       <!-- RGW QAT Compression -->
1208         @if(serviceForm.controls.service_type.value === 'rgw') {
1209         <div class="form-item"
1210              formGroupName="qat">
1211           <cds-select formControlName="compression"
1212                       name="compression"
1213                       label="QAT compression mode"
1214                       id="compression"
1215                       helperText="QAT compression is optional. Choose Hardware or Software to enable compression, or select None to disable it."
1216                       i18n-helperText>
1217             <option *ngFor="let option of qatCompressionOptions"
1218                     [value]="option.value"
1219                     i18n>{{ option.label }}</option>
1220           </cds-select>
1221         </div>
1222         }
1223
1224         <!-- Grafana -->
1225         <ng-container *ngIf="serviceForm.controls.service_type.value === 'grafana'">
1226           <div class="form-group row">
1227             <label class="cd-col-form-label"
1228                    for="grafana_port">
1229               <span i18n>Grafana Port</span>
1230               <cd-helper>
1231                 <span i18n>The default port used by grafana.</span>
1232               </cd-helper>
1233             </label>
1234             <div class="cd-col-form-input">
1235               <input id="grafana_port"
1236                      class="form-control"
1237                      type="number"
1238                      formControlName="grafana_port"
1239                      min="1"
1240                      max="65535">
1241               <span class="invalid-feedback"
1242                     *ngIf="serviceForm.showError('grafana_port', frm, 'pattern')"
1243                     i18n>The entered value needs to be a number.</span>
1244               <span class="invalid-feedback"
1245                     *ngIf="serviceForm.showError('grafana_port', frm, 'min')"
1246                     i18n>The value must be at least 1.</span>
1247               <span class="invalid-feedback"
1248                     *ngIf="serviceForm.showError('grafana_port', frm, 'max')"
1249                     i18n>The value cannot exceed 65535.</span>
1250               <span class="invalid-feedback"
1251                     *ngIf="serviceForm.showError('grafana_port', frm, 'required')"
1252                     i18n>This field is required.</span>
1253             </div>
1254           </div>
1255
1256           <div class="form-group row">
1257             <label i18n
1258                    class="cd-col-form-label"
1259                    for="grafana_admin_password">
1260               <span>Grafana Password</span>
1261               <cd-helper>The password of the default Grafana Admin. Set once on first-run.</cd-helper>
1262             </label>
1263             <div class="cd-col-form-input">
1264               <div class="input-group">
1265                 <input id="grafana_admin_password"
1266                        class="form-control"
1267                        type="password"
1268                        autocomplete="new-password"
1269                        [attr.disabled]="editing ? true:null"
1270                        formControlName="grafana_admin_password">
1271                 <span class="input-group-append">
1272                   <button type="button"
1273                           class="btn btn-light"
1274                           cdPasswordButton="grafana_admin_password">
1275                   </button>
1276                   <cd-copy-2-clipboard-button source="grafana_admin_password">
1277                   </cd-copy-2-clipboard-button>
1278                 </span>
1279               </div>
1280             </div>
1281           </div>
1282         </ng-container>
1283
1284       <cd-alert-panel *ngIf="serviceForm.controls.service_type.value === 'mgmt-gateway' && showMgmtGatewayMessage"
1285                       type="warning"
1286                       spacingClass="mb-3"
1287                       i18n>
1288         Modifying the default settings could lead to a weaker security configuration
1289       </cd-alert-panel>
1290
1291         <!-- NVMe/TCP -->
1292         <!-- mTLS -->
1293         <div class="form-group row"
1294              *ngIf="serviceForm.controls.service_type.value === 'nvmeof'">
1295           <div class="cd-col-form-offset">
1296             <div class="custom-control custom-checkbox">
1297               <input class="custom-control-input"
1298                      id="enable_mtls"
1299                      type="checkbox"
1300                      formControlName="enable_mtls">
1301               <label class="custom-control-label"
1302                      for="enable_mtls"
1303                      i18n>Encryption</label>
1304               <cd-help-text i18n>Enables mutual TLS (mTLS) between the client and the gateway server.</cd-help-text>
1305             </div>
1306           </div>
1307         </div>
1308
1309         <!-- root_ca_cert -->
1310         <div *ngIf="serviceForm.controls.enable_mtls.value"
1311              class="form-group row">
1312           <label class="cd-col-form-label required"
1313                  for="root_ca_cert">
1314             <span i18n>Root CA certificate</span>
1315           </label>
1316           <div class="cd-col-form-input">
1317             <textarea id="root_ca_cert"
1318                       class="form-control resize-vertical text-monospace text-pre"
1319                       formControlName="root_ca_cert"
1320                       rows="5"></textarea>
1321             <input type="file"
1322                    (change)="fileUpload($event.target.files, 'root_ca_cert')">
1323             <span class="invalid-feedback"
1324                   *ngIf="serviceForm.showError('root_ca_cert', frm, 'required')"
1325                   i18n>This field is required.</span>
1326           </div>
1327         </div>
1328
1329         <!-- client_cert -->
1330         <div *ngIf="serviceForm.controls.enable_mtls.value"
1331              class="form-group row">
1332           <label class="cd-col-form-label required"
1333                  for="client_cert">
1334             <span i18n>Client CA certificate</span>
1335           </label>
1336           <div class="cd-col-form-input">
1337             <textarea id="client_cert"
1338                       class="form-control resize-vertical text-monospace text-pre"
1339                       formControlName="client_cert"
1340                       rows="5"></textarea>
1341             <input type="file"
1342                    (change)="fileUpload($event.target.files, 'client_cert')">
1343             <span class="invalid-feedback"
1344                   *ngIf="serviceForm.showError('client_cert', frm, 'required')"
1345                   i18n>This field is required.</span>
1346           </div>
1347         </div>
1348
1349         <!-- client_key -->
1350         <div *ngIf="serviceForm.controls.enable_mtls.value"
1351              class="form-group row">
1352           <label class="cd-col-form-label required"
1353                  for="client_key">
1354             <span i18n>Client key</span>
1355           </label>
1356           <div class="cd-col-form-input">
1357             <textarea id="client_key"
1358                       class="form-control resize-vertical text-monospace text-pre"
1359                       formControlName="client_key"
1360                       rows="5"></textarea>
1361             <input type="file"
1362                    (change)="fileUpload($event.target.files, 'client_key')">
1363             <span class="invalid-feedback"
1364                   *ngIf="serviceForm.showError('client_key', frm, 'required')"
1365                   i18n>This field is required.</span>
1366           </div>
1367         </div>
1368
1369         <!-- server_cert -->
1370         <div *ngIf="serviceForm.controls.enable_mtls.value"
1371              class="form-group row">
1372           <label class="cd-col-form-label required"
1373                  for="server_cert">
1374             <span i18n>Gateway server certificate</span>
1375           </label>
1376           <div class="cd-col-form-input">
1377             <textarea id="server_cert"
1378                       class="form-control resize-vertical text-monospace text-pre"
1379                       formControlName="server_cert"
1380                       rows="5"></textarea>
1381             <input type="file"
1382                    (change)="fileUpload($event.target.files, 'server_cert')">
1383             <span class="invalid-feedback"
1384                   *ngIf="serviceForm.showError('server_cert', frm, 'required')"
1385                   i18n>This field is required.</span>
1386           </div>
1387         </div>
1388
1389         <!-- server_key -->
1390         <div *ngIf="serviceForm.controls.enable_mtls.value"
1391              class="form-group row">
1392           <label class="cd-col-form-label required"
1393                  for="server_key">
1394             <span i18n>Gateway server key</span>
1395           </label>
1396           <div class="cd-col-form-input">
1397             <textarea id="server_key"
1398                       class="form-control resize-vertical text-monospace text-pre"
1399                       formControlName="server_key"
1400                       rows="5"></textarea>
1401             <input type="file"
1402                    (change)="fileUpload($event.target.files, 'server_key')">
1403             <span class="invalid-feedback"
1404                   *ngIf="serviceForm.showError('server_key', frm, 'required')"
1405                   i18n>This field is required.</span>
1406           </div>
1407         </div>
1408
1409       </div>
1410
1411       <div class="modal-footer">
1412         <div class="text-right">
1413           <cd-form-button-panel (submitActionEvent)="onSubmit()"
1414                                 [form]="serviceForm"
1415                                 [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>
1416         </div>
1417       </div>
1418     </form>
1419   </ng-container>
1420 </cd-modal>