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