]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/blob
db346efda65ea4d09b030b81273f5542c6427ece
[ceph.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
11         <!-- Service type -->
12         <div class="form-group row">
13           <label class="cd-col-form-label required"
14                  for="service_type"
15                  i18n>Type</label>
16           <div class="cd-col-form-input">
17             <select id="service_type"
18                     name="service_type"
19                     class="form-control"
20                     formControlName="service_type"
21                     (change)="getServiceIds($event.target.value)">
22               <option i18n
23                       [ngValue]="null">-- Select a service type --</option>
24               <option *ngFor="let serviceType of serviceTypes"
25                       [value]="serviceType">
26                 {{ serviceType }}
27               </option>
28             </select>
29             <span class="invalid-feedback"
30                   *ngIf="serviceForm.showError('service_type', frm, 'required')"
31                   i18n>This field is required.</span>
32           </div>
33         </div>
34
35         <!-- backend_service -->
36           <div *ngIf="serviceForm.controls.service_type.value === 'ingress'"
37                class="form-group row">
38             <label i18n
39                    class="cd-col-form-label"
40                    [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
41                    for="backend_service">Backend Service</label>
42             <div class="cd-col-form-input">
43               <select id="backend_service"
44                       name="backend_service"
45                       class="form-control"
46                       formControlName="backend_service"
47                       (change)="prePopulateId()">
48                 <option *ngIf="services === null"
49                         [ngValue]="null"
50                         i18n>Loading...</option>
51                 <option *ngIf="services !== null && services.length === 0"
52                         [ngValue]="null"
53                         i18n>-- No service available --</option>
54                 <option *ngIf="services !== null && services.length > 0"
55                         [ngValue]="null"
56                         i18n>-- Select an existing service --</option>
57                 <option *ngFor="let service of services"
58                         [value]="service.service_name">{{ service.service_name }}</option>
59               </select>
60               <span class="invalid-feedback"
61                     *ngIf="serviceForm.showError('backend_service', frm, 'required')"
62                     i18n>This field is required.</span>
63             </div>
64           </div>
65
66         <!-- Service id -->
67         <div class="form-group row"
68              *ngIf="serviceForm.controls.service_type.value !== 'snmp-gateway'">
69           <label i18n
70                  class="cd-col-form-label"
71                  [ngClass]="{'required': ['mds', 'rgw', 'nfs', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)}"
72                  for="service_id">Id</label>
73           <div class="cd-col-form-input">
74             <input id="service_id"
75                    class="form-control"
76                    type="text"
77                    formControlName="service_id">
78             <span class="invalid-feedback"
79                   *ngIf="serviceForm.showError('service_id', frm, 'required')"
80                   i18n>This field is required.</span>
81             <span class="invalid-feedback"
82                   *ngIf="serviceForm.showError('service_id', frm, 'uniqueName')"
83                   i18n>This service id is already in use.</span>
84             <span class="invalid-feedback"
85                   *ngIf="serviceForm.showError('service_id', frm, 'rgwPattern')"
86                   i18n>The value does not match the pattern <strong>&lt;service_id&gt;[.&lt;realm_name&gt;.&lt;zone_name&gt;]</strong>.</span>
87           </div>
88         </div>
89
90         <!-- unmanaged -->
91         <div class="form-group row"
92              *ngIf="serviceForm.controls.service_type.value !== 'snmp-gateway'">
93           <div class="cd-col-form-offset">
94             <div class="custom-control custom-checkbox">
95               <input class="custom-control-input"
96                      id="unmanaged"
97                      type="checkbox"
98                      formControlName="unmanaged">
99               <label class="custom-control-label"
100                      for="unmanaged"
101                      i18n>Unmanaged</label>
102             </div>
103           </div>
104         </div>
105
106         <!-- Placement -->
107         <div *ngIf="!serviceForm.controls.unmanaged.value"
108              class="form-group row">
109           <label class="cd-col-form-label"
110                  for="placement"
111                  i18n>Placement</label>
112           <div class="cd-col-form-input">
113             <select id="placement"
114                     class="form-control"
115                     formControlName="placement">
116               <option i18n
117                       value="hosts">Hosts</option>
118               <option i18n
119                       value="label">Label</option>
120             </select>
121           </div>
122         </div>
123
124         <!-- Label -->
125         <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'label'"
126              class="form-group row">
127           <label i18n
128                  class="cd-col-form-label"
129                  for="label">Label</label>
130           <div class="cd-col-form-input">
131             <input id="label"
132                    class="form-control"
133                    type="text"
134                    formControlName="label"
135                    [ngbTypeahead]="searchLabels"
136                    (focus)="labelFocus.next($any($event).target.value)"
137                    (click)="labelClick.next($any($event).target.value)">
138             <span class="invalid-feedback"
139                   *ngIf="serviceForm.showError('label', frm, 'required')"
140                   i18n>This field is required.</span>
141           </div>
142         </div>
143
144         <!-- Hosts -->
145         <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'hosts'"
146              class="form-group row">
147           <label class="cd-col-form-label"
148                  for="hosts"
149                  i18n>Hosts</label>
150           <div class="cd-col-form-input">
151             <cd-select-badges id="hosts"
152                               [data]="serviceForm.controls.hosts.value"
153                               [options]="hosts.options"
154                               [messages]="hosts.messages">
155             </cd-select-badges>
156           </div>
157         </div>
158
159         <!-- count -->
160         <div *ngIf="!serviceForm.controls.unmanaged.value"
161              class="form-group row">
162           <label class="cd-col-form-label"
163                  for="count">
164             <span i18n>Count</span>
165             <cd-helper i18n>Only that number of daemons will be created.</cd-helper>
166           </label>
167           <div class="cd-col-form-input">
168             <input id="count"
169                    class="form-control"
170                    type="number"
171                    formControlName="count"
172                    min="1">
173             <span class="invalid-feedback"
174                   *ngIf="serviceForm.showError('count', frm, 'min')"
175                   i18n>The value must be at least 1.</span>
176             <span class="invalid-feedback"
177                   *ngIf="serviceForm.showError('count', frm, 'pattern')"
178                   i18n>The entered value needs to be a number.</span>
179           </div>
180         </div>
181
182         <!-- RGW -->
183         <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'rgw'">
184           <!-- rgw_frontend_port -->
185           <div class="form-group row">
186             <label i18n
187                    class="cd-col-form-label"
188                    for="rgw_frontend_port">Port</label>
189             <div class="cd-col-form-input">
190               <input id="rgw_frontend_port"
191                      class="form-control"
192                      type="number"
193                      formControlName="rgw_frontend_port"
194                      min="1"
195                      max="65535">
196               <span class="invalid-feedback"
197                     *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'pattern')"
198                     i18n>The entered value needs to be a number.</span>
199               <span class="invalid-feedback"
200                     *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'min')"
201                     i18n>The value must be at least 1.</span>
202               <span class="invalid-feedback"
203                     *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'max')"
204                     i18n>The value cannot exceed 65535.</span>
205             </div>
206           </div>
207         </ng-container>
208
209         <!-- iSCSI -->
210         <!-- pool -->
211         <div class="form-group row"
212              *ngIf="serviceForm.controls.service_type.value === 'iscsi'">
213           <label i18n
214                  class="cd-col-form-label required"
215                  for="pool">Pool</label>
216           <div class="cd-col-form-input">
217             <select id="pool"
218                     name="pool"
219                     class="form-control"
220                     formControlName="pool">
221               <option *ngIf="pools === null"
222                       [ngValue]="null"
223                       i18n>Loading...</option>
224               <option *ngIf="pools && pools.length === 0"
225                       [ngValue]="null"
226                       i18n>-- No pools available --</option>
227               <option *ngIf="pools && pools.length > 0"
228                       [ngValue]="null"
229                       i18n>-- Select a pool --</option>
230               <option *ngFor="let pool of pools"
231                       [value]="pool.pool_name">{{ pool.pool_name }}</option>
232             </select>
233             <span class="invalid-feedback"
234                   *ngIf="serviceForm.showError('pool', frm, 'required')"
235                   i18n>This field is required.</span>
236           </div>
237         </div>
238
239         <!-- fields in iSCSI which are hidden when unmanaged is true -->
240         <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'iscsi'">
241           <!-- trusted_ip_list -->
242           <div class="form-group row">
243             <label class="cd-col-form-label"
244                    for="trusted_ip_list">
245               <span i18n>Trusted IPs</span>
246               <cd-helper>
247                 <span i18n>Comma separated list of IP addresses.</span>
248                 <br>
249                 <span i18n>Please add the <b>Ceph Manager</b> IP addresses here, otherwise the iSCSI gateways can't be reached.</span>
250               </cd-helper>
251             </label>
252             <div class="cd-col-form-input">
253               <input id="trusted_ip_list"
254                      class="form-control"
255                      type="text"
256                      formControlName="trusted_ip_list">
257             </div>
258           </div>
259
260           <!-- api_port -->
261           <div class="form-group row">
262             <label i18n
263                    class="cd-col-form-label"
264                    for="api_port">Port</label>
265             <div class="cd-col-form-input">
266               <input id="api_port"
267                      class="form-control"
268                      type="number"
269                      formControlName="api_port"
270                      min="1"
271                      max="65535">
272               <span class="invalid-feedback"
273                     *ngIf="serviceForm.showError('api_port', frm, 'pattern')"
274                     i18n>The entered value needs to be a number.</span>
275               <span class="invalid-feedback"
276                     *ngIf="serviceForm.showError('api_port', frm, 'min')"
277                     i18n>The value must be at least 1.</span>
278               <span class="invalid-feedback"
279                     *ngIf="serviceForm.showError('api_port', frm, 'max')"
280                     i18n>The value cannot exceed 65535.</span>
281             </div>
282           </div>
283
284           <!-- api_user -->
285           <div class="form-group row">
286             <label i18n
287                    class="cd-col-form-label"
288                    [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
289                    for="api_user">User</label>
290             <div class="cd-col-form-input">
291               <input id="api_user"
292                      class="form-control"
293                      type="text"
294                      formControlName="api_user">
295               <span class="invalid-feedback"
296                     *ngIf="serviceForm.showError('api_user', frm, 'required')"
297                     i18n>This field is required.</span>
298             </div>
299           </div>
300
301           <!-- api_password -->
302           <div class="form-group row">
303             <label i18n
304                    class="cd-col-form-label"
305                    [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
306                    for="api_password">Password</label>
307             <div class="cd-col-form-input">
308               <div class="input-group">
309                 <input id="api_password"
310                        class="form-control"
311                        type="password"
312                        autocomplete="new-password"
313                        formControlName="api_password">
314                 <span class="input-group-append">
315                   <button type="button"
316                           class="btn btn-light"
317                           cdPasswordButton="api_password">
318                   </button>
319                   <cd-copy-2-clipboard-button source="api_password">
320                   </cd-copy-2-clipboard-button>
321                 </span>
322                 <span class="invalid-feedback"
323                       *ngIf="serviceForm.showError('api_password', frm, 'required')"
324                       i18n>This field is required.</span>
325               </div>
326             </div>
327           </div>
328         </ng-container>
329
330         <!-- Ingress -->
331         <ng-container *ngIf="serviceForm.controls.service_type.value === 'ingress'">
332           <!-- virtual_ip -->
333           <div class="form-group row">
334             <label class="cd-col-form-label"
335                    [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
336                    for="virtual_ip">
337               <span i18n>Virtual IP</span>
338               <cd-helper>
339                 <span i18n>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</span>
340               </cd-helper>
341             </label>
342             <div class="cd-col-form-input">
343               <input id="virtual_ip"
344                      class="form-control"
345                      type="text"
346                      formControlName="virtual_ip">
347               <span class="invalid-feedback"
348                     *ngIf="serviceForm.showError('virtual_ip', frm, 'required')"
349                     i18n>This field is required.</span>
350             </div>
351           </div>
352
353           <!-- frontend_port -->
354           <div class="form-group row">
355             <label class="cd-col-form-label"
356                    [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
357                    for="frontend_port">
358               <span i18n>Frontend Port</span>
359               <cd-helper>
360                 <span i18n>The port used to access the ingress service.</span>
361               </cd-helper>
362             </label>
363             <div class="cd-col-form-input">
364               <input id="frontend_port"
365                      class="form-control"
366                      type="number"
367                      formControlName="frontend_port"
368                      min="1"
369                      max="65535">
370               <span class="invalid-feedback"
371                     *ngIf="serviceForm.showError('frontend_port', frm, 'pattern')"
372                     i18n>The entered value needs to be a number.</span>
373               <span class="invalid-feedback"
374                     *ngIf="serviceForm.showError('frontend_port', frm, 'min')"
375                     i18n>The value must be at least 1.</span>
376               <span class="invalid-feedback"
377                     *ngIf="serviceForm.showError('frontend_port', frm, 'max')"
378                     i18n>The value cannot exceed 65535.</span>
379               <span class="invalid-feedback"
380                     *ngIf="serviceForm.showError('frontend_port', frm, 'required')"
381                     i18n>This field is required.</span>
382             </div>
383           </div>
384
385           <!-- monitor_port -->
386           <div class="form-group row">
387             <label class="cd-col-form-label"
388                    [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
389                    for="monitor_port">
390               <span i18n>Monitor Port</span>
391               <cd-helper>
392                 <span i18n>The port used by haproxy for load balancer status.</span>
393               </cd-helper>
394             </label>
395             <div class="cd-col-form-input">
396               <input id="monitor_port"
397                      class="form-control"
398                      type="number"
399                      formControlName="monitor_port"
400                      min="1"
401                      max="65535">
402               <span class="invalid-feedback"
403                     *ngIf="serviceForm.showError('monitor_port', frm, 'pattern')"
404                     i18n>The entered value needs to be a number.</span>
405               <span class="invalid-feedback"
406                     *ngIf="serviceForm.showError('monitor_port', frm, 'min')"
407                     i18n>The value must be at least 1.</span>
408               <span class="invalid-feedback"
409                     *ngIf="serviceForm.showError('monitor_port', frm, 'max')"
410                     i18n>The value cannot exceed 65535.</span>
411               <span class="invalid-feedback"
412                     *ngIf="serviceForm.showError('monitor_port', frm, 'required')"
413                     i18n>This field is required.</span>
414             </div>
415           </div>
416           <!-- virtual_interface_networks -->
417           <div class="form-group row"
418                *ngIf="!serviceForm.controls.unmanaged.value">
419             <label class="cd-col-form-label"
420                    for="virtual_interface_networks">
421               <span i18n>CIDR Networks</span>
422               <cd-helper>
423                 <span i18n>A list of networks to identify which network interface to use for the virtual IP address.</span>
424               </cd-helper>
425             </label>
426             <div class="cd-col-form-input">
427               <input id="virtual_interface_networks"
428                      class="form-control"
429                      type="text"
430                      formControlName="virtual_interface_networks">
431             </div>
432           </div>
433         </ng-container>
434
435         <!-- SNMP-Gateway -->
436         <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'snmp-gateway'">
437           <!-- snmp-version -->
438           <div class="form-group row">
439             <label class="cd-col-form-label required"
440                    for="snmp_version"
441                    i18n>Version</label>
442             <div class="cd-col-form-input">
443               <select id="snmp_version"
444                       name="snmp_version"
445                       class="form-control"
446                       formControlName="snmp_version"
447                       (change)="clearValidations()">
448                 <option i18n
449                         [ngValue]="null">-- Select SNMP version --</option>
450                 <option *ngFor="let snmpVersion of ['V2c', 'V3']"
451                         [value]="snmpVersion">{{ snmpVersion }}</option>
452               </select>
453               <span class="invalid-feedback"
454                     *ngIf="serviceForm.showError('snmp_version', frm, 'required')"
455                     i18n>This field is required.</span>
456             </div>
457           </div>
458           <!-- Destination -->
459           <div class="form-group row">
460             <label class="cd-col-form-label required"
461                    for="snmp_destination">
462               <span i18n>Destination</span>
463               <cd-helper>
464                 <span i18n>Must be of the format hostname:port.</span>
465               </cd-helper>
466             </label>
467             <div class="cd-col-form-input">
468               <input id="snmp_destination"
469                      class="form-control"
470                      type="text"
471                      formControlName="snmp_destination">
472               <span class="invalid-feedback"
473                     *ngIf="serviceForm.showError('snmp_destination', frm, 'required')"
474                     i18n>This field is required.</span>
475               <span class="invalid-feedback"
476                     *ngIf="serviceForm.showError('snmp_destination', frm, 'snmpDestinationPattern')"
477                     i18n>The value does not match the pattern: <strong>hostname:port</strong></span>
478             </div>
479           </div>
480           <!-- Engine id for snmp V3 -->
481           <div class="form-group row"
482                *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
483             <label class="cd-col-form-label required"
484                    for="engine_id">
485               <span i18n>Engine Id</span>
486               <cd-helper>
487                 <span i18n>Unique identifier for the device (in hex).</span>
488               </cd-helper>
489             </label>
490             <div class="cd-col-form-input">
491               <input id="engine_id"
492                      class="form-control"
493                      type="text"
494                      formControlName="engine_id">
495               <span class="invalid-feedback"
496                     *ngIf="serviceForm.showError('engine_id', frm, 'required')"
497                     i18n>This field is required.</span>
498               <span class="invalid-feedback"
499                     *ngIf="serviceForm.showError('engine_id', frm, 'snmpEngineIdPattern')"
500                     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>
501             </div>
502           </div>
503           <!-- Auth protocol for snmp V3 -->
504           <div class="form-group row"
505                *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
506             <label class="cd-col-form-label required"
507                    for="auth_protocol"
508                    i18n>Auth Protocol</label>
509             <div class="cd-col-form-input">
510               <select id="auth_protocol"
511                       name="auth_protocol"
512                       class="form-control"
513                       formControlName="auth_protocol">
514                 <option i18n
515                         [ngValue]="null">-- Select auth protocol --</option>
516                 <option *ngFor="let authProtocol of ['SHA', 'MD5']"
517                         [value]="authProtocol">
518                   {{ authProtocol }}
519                 </option>
520               </select>
521               <span class="invalid-feedback"
522                     *ngIf="serviceForm.showError('auth_protocol', frm, 'required')"
523                     i18n>This field is required.</span>
524             </div>
525           </div>
526           <!-- Privacy protocol for snmp V3 -->
527           <div class="form-group row"
528                *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
529             <label class="cd-col-form-label"
530                    for="privacy_protocol"
531                    i18n>Privacy Protocol</label>
532             <div class="cd-col-form-input">
533               <select id="privacy_protocol"
534                       name="privacy_protocol"
535                       class="form-control"
536                       formControlName="privacy_protocol">
537                 <option i18n
538                         [ngValue]="null">-- Select privacy protocol --</option>
539                 <option *ngFor="let privacyProtocol of ['DES', 'AES']"
540                         [value]="privacyProtocol">
541                   {{ privacyProtocol }}
542                 </option>
543               </select>
544             </div>
545           </div>
546           <!-- Credentials -->
547           <fieldset>
548             <legend i18n>Credentials</legend>
549             <!-- snmp v2c snmp_community -->
550             <div class="form-group row"
551                  *ngIf="serviceForm.controls.snmp_version.value === 'V2c'">
552               <label class="cd-col-form-label required"
553                      for="snmp_community">
554                 <span i18n>SNMP Community</span>
555               </label>
556               <div class="cd-col-form-input">
557                 <input id="snmp_community"
558                        class="form-control"
559                        type="text"
560                        formControlName="snmp_community">
561                 <span class="invalid-feedback"
562                       *ngIf="serviceForm.showError('snmp_community', frm, 'required')"
563                       i18n>This field is required.</span>
564               </div>
565             </div>
566             <!-- snmp v3 auth username -->
567             <div class="form-group row"
568                  *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
569               <label class="cd-col-form-label required"
570                      for="snmp_v3_auth_username">
571                 <span i18n>Username</span>
572               </label>
573               <div class="cd-col-form-input">
574                 <input id="snmp_v3_auth_username"
575                        class="form-control"
576                        type="text"
577                        formControlName="snmp_v3_auth_username">
578                 <span class="invalid-feedback"
579                       *ngIf="serviceForm.showError('snmp_v3_auth_username', frm, 'required')"
580                       i18n>This field is required.</span>
581               </div>
582             </div>
583             <!-- snmp v3 auth password -->
584             <div class="form-group row"
585                  *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
586               <label class="cd-col-form-label required"
587                      for="snmp_v3_auth_password">
588                 <span i18n>Password</span>
589               </label>
590               <div class="cd-col-form-input">
591                 <input id="snmp_v3_auth_password"
592                        class="form-control"
593                        type="password"
594                        formControlName="snmp_v3_auth_password">
595                 <span class="invalid-feedback"
596                       *ngIf="serviceForm.showError('snmp_v3_auth_password', frm, 'required')"
597                       i18n>This field is required.</span>
598               </div>
599             </div>
600             <!-- snmp v3 priv password -->
601             <div class="form-group row"
602                  *ngIf="serviceForm.controls.snmp_version.value === 'V3' && serviceForm.controls.privacy_protocol.value !== null && serviceForm.controls.privacy_protocol.value !== undefined">
603               <label class="cd-col-form-label required"
604                      for="snmp_v3_priv_password">
605                 <span i18n>Encryption</span>
606               </label>
607               <div class="cd-col-form-input">
608                 <input id="snmp_v3_priv_password"
609                        class="form-control"
610                        type="password"
611                        formControlName="snmp_v3_priv_password">
612                 <span class="invalid-feedback"
613                       *ngIf="serviceForm.showError('snmp_v3_priv_password', frm, 'required')"
614                       i18n>This field is required.</span>
615               </div>
616             </div>
617           </fieldset>
618         </ng-container>
619         <!-- RGW, Ingress & iSCSI -->
620         <ng-container *ngIf="!serviceForm.controls.unmanaged.value && ['rgw', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)">
621           <!-- ssl -->
622           <div class="form-group row">
623             <div class="cd-col-form-offset">
624               <div class="custom-control custom-checkbox">
625                 <input class="custom-control-input"
626                        id="ssl"
627                        type="checkbox"
628                        formControlName="ssl">
629                 <label class="custom-control-label"
630                        for="ssl"
631                        i18n>SSL</label>
632               </div>
633             </div>
634           </div>
635
636           <!-- ssl_cert -->
637           <div *ngIf="serviceForm.controls.ssl.value"
638                class="form-group row">
639             <label class="cd-col-form-label"
640                    for="ssl_cert">
641               <span i18n>Certificate</span>
642               <cd-helper i18n>The SSL certificate in PEM format.</cd-helper>
643             </label>
644             <div class="cd-col-form-input">
645               <textarea id="ssl_cert"
646                         class="form-control resize-vertical text-monospace text-pre"
647                         formControlName="ssl_cert"
648                         rows="5">
649               </textarea>
650               <input type="file"
651                      (change)="fileUpload($event.target.files, 'ssl_cert')">
652               <span class="invalid-feedback"
653                     *ngIf="serviceForm.showError('ssl_cert', frm, 'required')"
654                     i18n>This field is required.</span>
655               <span class="invalid-feedback"
656                     *ngIf="serviceForm.showError('ssl_cert', frm, 'pattern')"
657                     i18n>Invalid SSL certificate.</span>
658             </div>
659           </div>
660
661           <!-- ssl_key -->
662           <div *ngIf="serviceForm.controls.ssl.value && !(['rgw', 'ingress'].includes(serviceForm.controls.service_type.value))"
663                class="form-group row">
664             <label class="cd-col-form-label"
665                    for="ssl_key">
666               <span i18n>Private key</span>
667               <cd-helper i18n>The SSL private key in PEM format.</cd-helper>
668             </label>
669             <div class="cd-col-form-input">
670               <textarea id="ssl_key"
671                         class="form-control resize-vertical text-monospace text-pre"
672                         formControlName="ssl_key"
673                         rows="5">
674               </textarea>
675               <input type="file"
676                      (change)="fileUpload($event.target.files,'ssl_key')">
677               <span class="invalid-feedback"
678                     *ngIf="serviceForm.showError('ssl_key', frm, 'required')"
679                     i18n>This field is required.</span>
680               <span class="invalid-feedback"
681                     *ngIf="serviceForm.showError('ssl_key', frm, 'pattern')"
682                     i18n>Invalid SSL private key.</span>
683             </div>
684           </div>
685         </ng-container>
686       </div>
687
688       <div class="modal-footer">
689         <div class="text-right">
690           <cd-form-button-panel (submitActionEvent)="onSubmit()"
691                                 [form]="serviceForm"
692                                 [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>
693         </div>
694       </div>
695     </form>
696   </ng-container>
697 </cd-modal>