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">
7 [formGroup]="serviceForm"
9 <div class="modal-body">
10 <cd-alert-panel *ngIf="serviceForm.controls.service_type.value === 'rgw' && showRealmCreationForm"
14 <a class="text-decoration-underline"
15 (click)="createMultisiteSetup()">
16 Click here</a> to create a new Realm/Zone Group/Zone
19 <div class="form-group row">
20 <label class="cd-col-form-label required"
23 <div class="cd-col-form-input">
24 <select id="service_type"
27 formControlName="service_type"
28 (change)="getServiceIds($event.target.value)">
30 [ngValue]="null">-- Select a service type --</option>
31 <option *ngFor="let serviceType of serviceTypes"
32 [value]="serviceType">
36 <span class="invalid-feedback"
37 *ngIf="serviceForm.showError('service_type', frm, 'required')"
38 i18n>This field is required.</span>
42 <!-- backend_service -->
43 <div *ngIf="serviceForm.controls.service_type.value === 'ingress'"
44 class="form-group row">
46 class="cd-col-form-label"
47 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
48 for="backend_service">Backend Service</label>
49 <div class="cd-col-form-input">
50 <select id="backend_service"
51 name="backend_service"
53 formControlName="backend_service"
54 (change)="prePopulateId()">
55 <option *ngIf="services === null"
57 i18n>Loading...</option>
58 <option *ngIf="services !== null && services.length === 0"
60 i18n>-- No service available --</option>
61 <option *ngIf="services !== null && services.length > 0"
63 i18n>-- Select an existing service --</option>
64 <option *ngFor="let service of services"
65 [value]="service.service_name">{{ service.service_name }}</option>
67 <span class="invalid-feedback"
68 *ngIf="serviceForm.showError('backend_service', frm, 'required')"
69 i18n>This field is required.</span>
74 <div class="form-group row"
75 *ngIf="serviceForm.controls.service_type.value !== 'snmp-gateway'">
76 <label class="cd-col-form-label"
77 [ngClass]="{'required': ['mds', 'rgw', 'nfs', 'iscsi', 'smb', 'ingress'].includes(serviceForm.controls.service_type.value)}"
80 <cd-helper i18n>Used in the service name which is <service_type.service_id></cd-helper>
82 <div class="cd-col-form-input">
83 <input id="service_id"
86 formControlName="service_id">
87 <span class="invalid-feedback"
88 *ngIf="serviceForm.showError('service_id', frm, 'required')"
89 i18n>This field is required.</span>
90 <span class="invalid-feedback"
91 *ngIf="serviceForm.showError('service_id', frm, 'uniqueName')"
92 i18n>This service id is already in use.</span>
93 <span class="invalid-feedback"
94 *ngIf="serviceForm.showError('service_id', frm, 'mdsPattern')"
95 i18n>MDS service id must start with a letter and contain alphanumeric characters or '.', '-', and '_'</span>
99 <div class="form-group row"
100 *ngIf="serviceForm.controls.service_type.value === 'rgw'">
101 <label class="cd-col-form-label"
104 <div class="cd-col-form-input">
105 <select class="form-select"
107 formControlName="realm_name"
109 [attr.disabled]="realmList.length === 0 || editing ? true : null">
110 <option *ngIf="realmList.length === 0"
112 selected>-- No realm available --</option>
113 <option *ngFor="let realm of realmList"
114 [value]="realm.name">
121 <div class="form-group row"
122 *ngIf="serviceForm.controls.service_type.value === 'rgw'">
123 <label class="cd-col-form-label"
125 i18n>Zone Group</label>
126 <div class="cd-col-form-input">
127 <select class="form-select"
129 formControlName="zonegroup_name"
130 name="zonegroup_name"
131 [attr.disabled]="zonegroupList.length === 0 || editing ? true : null">
132 <option *ngFor="let zonegroup of zonegroupList"
133 [value]="zonegroup.name">
140 <div class="form-group row"
141 *ngIf="serviceForm.controls.service_type.value === 'rgw'">
142 <label class="cd-col-form-label"
145 <div class="cd-col-form-input">
146 <select class="form-select"
148 formControlName="zone_name"
150 [attr.disabled]="zoneList.length === 0 || editing ? true : null">
151 <option *ngFor="let zone of zoneList"
160 <div class="form-group row">
161 <div class="cd-col-form-offset">
162 <div class="custom-control custom-checkbox">
163 <input class="custom-control-input"
166 formControlName="unmanaged">
167 <label class="custom-control-label"
169 i18n>Unmanaged</label>
170 <cd-helper i18n>If set to true, the orchestrator will not start nor stop any daemon associated with this service.
171 Placement and all other properties will be ignored.</cd-helper>
177 <div *ngIf="!serviceForm.controls.unmanaged.value"
178 class="form-group row">
179 <label class="cd-col-form-label"
181 i18n>Placement</label>
182 <div class="cd-col-form-input">
183 <select id="placement"
185 formControlName="placement">
187 value="hosts">Hosts</option>
189 value="label">Label</option>
195 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'label'"
196 class="form-group row">
198 class="cd-col-form-label"
199 for="label">Label</label>
200 <div class="cd-col-form-input">
204 formControlName="label"
205 [ngbTypeahead]="searchLabels"
206 (focus)="labelFocus.next($any($event).target.value)"
207 (click)="labelClick.next($any($event).target.value)">
208 <span class="invalid-feedback"
209 *ngIf="serviceForm.showError('label', frm, 'required')"
210 i18n>This field is required.</span>
215 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'hosts'"
216 class="form-group row">
217 <label class="cd-col-form-label"
220 <div class="cd-col-form-input">
221 <cd-select-badges id="hosts"
222 [data]="serviceForm.controls.hosts.value"
223 [options]="hosts.options"
224 [messages]="hosts.messages">
230 <div *ngIf="!serviceForm.controls.unmanaged.value"
231 class="form-group row">
232 <label class="cd-col-form-label"
234 <span i18n>Count</span>
235 <cd-helper i18n>Only that number of daemons will be created.</cd-helper>
237 <div class="cd-col-form-input">
241 formControlName="count"
243 <span class="invalid-feedback"
244 *ngIf="serviceForm.showError('count', frm, 'min')"
245 i18n>The value must be at least 1.</span>
246 <span class="invalid-feedback"
247 *ngIf="serviceForm.showError('count', frm, 'pattern')"
248 i18n>The entered value needs to be a number.</span>
253 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'rgw'">
254 <!-- rgw_frontend_port -->
255 <div class="form-group row">
257 class="cd-col-form-label"
258 for="rgw_frontend_port">Port</label>
259 <div class="cd-col-form-input">
260 <input id="rgw_frontend_port"
263 formControlName="rgw_frontend_port"
266 <span class="invalid-feedback"
267 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'pattern')"
268 i18n>The entered value needs to be a number.</span>
269 <span class="invalid-feedback"
270 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'min')"
271 i18n>The value must be at least 1.</span>
272 <span class="invalid-feedback"
273 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'max')"
274 i18n>The value cannot exceed 65535.</span>
281 <div class="form-group row"
282 *ngIf="serviceForm.controls.service_type.value === 'iscsi'">
284 class="cd-col-form-label required"
285 for="pool">Pool</label>
286 <div class="cd-col-form-input">
290 formControlName="pool">
291 <option *ngIf="pools === null"
293 i18n>Loading...</option>
294 <option *ngIf="pools && pools.length === 0"
296 i18n>-- No pools available --</option>
297 <option *ngIf="pools && pools.length > 0"
299 i18n>-- Select a pool --</option>
300 <option *ngFor="let pool of pools"
301 [value]="pool.pool_name">{{ pool.pool_name }}</option>
303 <span class="invalid-feedback"
304 *ngIf="serviceForm.showError('pool', frm, 'required')"
305 i18n>This field is required.</span>
309 <!-- fields in iSCSI which are hidden when unmanaged is true -->
310 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'iscsi'">
311 <!-- trusted_ip_list -->
312 <div class="form-group row">
313 <label class="cd-col-form-label"
314 for="trusted_ip_list">
315 <span i18n>Trusted IPs</span>
317 <span i18n>Comma separated list of IP addresses.</span>
319 <span i18n>Please add the <b>Ceph Manager</b> IP addresses here, otherwise the iSCSI gateways can't be reached.</span>
322 <div class="cd-col-form-input">
323 <input id="trusted_ip_list"
326 formControlName="trusted_ip_list">
331 <div class="form-group row">
333 class="cd-col-form-label"
334 for="api_port">Port</label>
335 <div class="cd-col-form-input">
339 formControlName="api_port"
342 <span class="invalid-feedback"
343 *ngIf="serviceForm.showError('api_port', frm, 'pattern')"
344 i18n>The entered value needs to be a number.</span>
345 <span class="invalid-feedback"
346 *ngIf="serviceForm.showError('api_port', frm, 'min')"
347 i18n>The value must be at least 1.</span>
348 <span class="invalid-feedback"
349 *ngIf="serviceForm.showError('api_port', frm, 'max')"
350 i18n>The value cannot exceed 65535.</span>
355 <div class="form-group row">
357 class="cd-col-form-label"
358 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
359 for="api_user">User</label>
360 <div class="cd-col-form-input">
364 formControlName="api_user">
365 <span class="invalid-feedback"
366 *ngIf="serviceForm.showError('api_user', frm, 'required')"
367 i18n>This field is required.</span>
371 <!-- api_password -->
372 <div class="form-group row">
374 class="cd-col-form-label"
375 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
376 for="api_password">Password</label>
377 <div class="cd-col-form-input">
378 <div class="input-group">
379 <input id="api_password"
382 autocomplete="new-password"
383 formControlName="api_password">
384 <button type="button"
385 class="btn btn-light"
386 cdPasswordButton="api_password">
388 <cd-copy-2-clipboard-button source="api_password">
389 </cd-copy-2-clipboard-button>
390 <span class="invalid-feedback"
391 *ngIf="serviceForm.showError('api_password', frm, 'required')"
392 i18n>This field is required.</span>
399 <ng-container *ngIf="serviceForm.controls.service_type.value === 'smb'">
400 <div class="form-group row">
401 <label class="cd-col-form-label required"
406 <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,
407 and may not provide actual clustering or availability mechanisms.</span>
410 <div class="cd-col-form-input">
411 <input id="cluster_id"
414 formControlName="cluster_id"
417 <span class="invalid-feedback"
418 *ngIf="serviceForm.showError('cluster_id', frm, 'required')"
419 i18n>This field is required.</span>
423 <div class="form-group row">
424 <label class="cd-col-form-label required"
426 <span i18n>Config URI</span>
428 Configuration source that should be loaded by the samba-container as the primary configuration file.
431 <div class="cd-col-form-input">
432 <input id="config_uri"
435 formControlName="config_uri"
436 placeholder="rados://.smb/foo/scc.toml"
438 <span class="invalid-feedback"
439 *ngIf="serviceForm.showError('config_uri', frm, 'required')"
440 i18n>This field is required.</span>
441 <span class="invalid-feedback"
442 *ngIf="serviceForm.showError('config_uri', frm, 'configUriPattern')"
443 i18n>The value must start with either 'http:', 'https:', 'rados:' or 'rados:mon-config-key:'</span>
447 <div class="form-group row"
448 formGroupName="features">
449 <label class="cd-col-form-label"
453 <span>Pre-defined terms enabling specific deployment characteristics.</span>
456 <div class="cd-col-form-input">
457 <div class="custom-control custom-checkbox"
458 *ngFor="let feature of smbFeaturesList">
459 <input class="custom-control-input"
463 formControlName="{{feature}}">
464 <label class="custom-control-label"
472 <div class="form-group row">
473 <label class="cd-col-form-label"
475 <span i18n>Custom DNS</span>
477 <span>Comma separated list of DNSs.</span>
479 <span>A list of IP addresses that will be used as the DNS servers for a Samba container.</span>
482 <div class="cd-col-form-input">
483 <input id="custom_dns"
486 formControlName="custom_dns"
487 placeholder="192.168.76.204"
492 <div class="form-group row">
493 <label class="cd-col-form-label"
495 <span i18n>Join sources</span>
497 <span>Comma separated list of URIs.</span>
499 <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>
502 <div class="cd-col-form-input">
503 <input id="join_sources"
506 formControlName="join_sources"
507 placeholder="rados:mon-config-key:smb/config/foo/join1.json"
512 <div class="form-group row">
513 <label class="cd-col-form-label"
515 <span i18n>User sources</span>
517 <span>Comma separated list of URIs.</span>
519 <span>A list of pseudo-uris containing data the samba-container can use to create users (and/or
520 groups). A ceph based samba container may typically use a rados uri
521 or a mon config-key store uri </span>
524 <div class="cd-col-form-input">
525 <input id="user_sources"
528 formControlName="user_sources"
529 placeholder="rados:mon-config-key:smb/config/foo/join2.json"
534 <div class="form-group row">
535 <label class="cd-col-form-label"
536 for="include_ceph_users">
537 <span i18n>Ceph users</span>
539 <span>Comma separated list of Ceph users.</span>
541 <span>A list of cephx user names that the Samba Containers may use.</span>
544 <div class="cd-col-form-input">
545 <input id="include_ceph_users"
548 formControlName="include_ceph_users"
549 placeholder="client.smb.fs.cluster.foo"
557 <ng-container *ngIf="serviceForm.controls.service_type.value === 'ingress'">
559 <div class="form-group row">
560 <label class="cd-col-form-label"
561 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
563 <span i18n>Virtual IP</span>
565 <span i18n>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</span>
568 <div class="cd-col-form-input">
569 <input id="virtual_ip"
572 formControlName="virtual_ip">
573 <span class="invalid-feedback"
574 *ngIf="serviceForm.showError('virtual_ip', frm, 'required')"
575 i18n>This field is required.</span>
579 <!-- frontend_port -->
580 <div class="form-group row">
581 <label class="cd-col-form-label"
582 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
584 <span i18n>Frontend Port</span>
586 <span i18n>The port used to access the ingress service.</span>
589 <div class="cd-col-form-input">
590 <input id="frontend_port"
593 formControlName="frontend_port"
596 <span class="invalid-feedback"
597 *ngIf="serviceForm.showError('frontend_port', frm, 'pattern')"
598 i18n>The entered value needs to be a number.</span>
599 <span class="invalid-feedback"
600 *ngIf="serviceForm.showError('frontend_port', frm, 'min')"
601 i18n>The value must be at least 1.</span>
602 <span class="invalid-feedback"
603 *ngIf="serviceForm.showError('frontend_port', frm, 'max')"
604 i18n>The value cannot exceed 65535.</span>
605 <span class="invalid-feedback"
606 *ngIf="serviceForm.showError('frontend_port', frm, 'required')"
607 i18n>This field is required.</span>
611 <!-- monitor_port -->
612 <div class="form-group row">
613 <label class="cd-col-form-label"
614 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
616 <span i18n>Monitor Port</span>
618 <span i18n>The port used by haproxy for load balancer status.</span>
621 <div class="cd-col-form-input">
622 <input id="monitor_port"
625 formControlName="monitor_port"
628 <span class="invalid-feedback"
629 *ngIf="serviceForm.showError('monitor_port', frm, 'pattern')"
630 i18n>The entered value needs to be a number.</span>
631 <span class="invalid-feedback"
632 *ngIf="serviceForm.showError('monitor_port', frm, 'min')"
633 i18n>The value must be at least 1.</span>
634 <span class="invalid-feedback"
635 *ngIf="serviceForm.showError('monitor_port', frm, 'max')"
636 i18n>The value cannot exceed 65535.</span>
637 <span class="invalid-feedback"
638 *ngIf="serviceForm.showError('monitor_port', frm, 'required')"
639 i18n>This field is required.</span>
642 <!-- virtual_interface_networks -->
643 <div class="form-group row"
644 *ngIf="!serviceForm.controls.unmanaged.value">
645 <label class="cd-col-form-label"
646 for="virtual_interface_networks">
647 <span i18n>CIDR Networks</span>
649 <span i18n>A list of networks to identify which network interface to use for the virtual IP address.</span>
652 <div class="cd-col-form-input">
653 <input id="virtual_interface_networks"
656 formControlName="virtual_interface_networks">
661 <!-- SNMP-Gateway -->
662 <ng-container *ngIf="serviceForm.controls.service_type.value === 'snmp-gateway'">
663 <!-- snmp-version -->
664 <div class="form-group row">
665 <label class="cd-col-form-label required"
668 <div class="cd-col-form-input">
669 <select id="snmp_version"
672 formControlName="snmp_version"
673 (change)="clearValidations()">
675 [ngValue]="null">-- Select SNMP version --</option>
676 <option *ngFor="let snmpVersion of ['V2c', 'V3']"
677 [value]="snmpVersion">{{ snmpVersion }}</option>
679 <span class="invalid-feedback"
680 *ngIf="serviceForm.showError('snmp_version', frm, 'required')"
681 i18n>This field is required.</span>
685 <div class="form-group row">
686 <label class="cd-col-form-label required"
687 for="snmp_destination">
688 <span i18n>Destination</span>
690 <span i18n>Must be of the format hostname:port.</span>
693 <div class="cd-col-form-input">
694 <input id="snmp_destination"
697 formControlName="snmp_destination">
698 <span class="invalid-feedback"
699 *ngIf="serviceForm.showError('snmp_destination', frm, 'required')"
700 i18n>This field is required.</span>
701 <span class="invalid-feedback"
702 *ngIf="serviceForm.showError('snmp_destination', frm, 'snmpDestinationPattern')"
703 i18n>The value does not match the pattern: <strong>hostname:port</strong></span>
706 <!-- Engine id for snmp V3 -->
707 <div class="form-group row"
708 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
709 <label class="cd-col-form-label required"
711 <span i18n>Engine Id</span>
713 <span i18n>Unique identifier for the device (in hex).</span>
716 <div class="cd-col-form-input">
717 <input id="engine_id"
720 formControlName="engine_id">
721 <span class="invalid-feedback"
722 *ngIf="serviceForm.showError('engine_id', frm, 'required')"
723 i18n>This field is required.</span>
724 <span class="invalid-feedback"
725 *ngIf="serviceForm.showError('engine_id', frm, 'snmpEngineIdPattern')"
726 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>
729 <!-- Auth protocol for snmp V3 -->
730 <div class="form-group row"
731 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
732 <label class="cd-col-form-label required"
734 i18n>Auth Protocol</label>
735 <div class="cd-col-form-input">
736 <select id="auth_protocol"
739 formControlName="auth_protocol">
741 [ngValue]="null">-- Select auth protocol --</option>
742 <option *ngFor="let authProtocol of ['SHA', 'MD5']"
743 [value]="authProtocol">
747 <span class="invalid-feedback"
748 *ngIf="serviceForm.showError('auth_protocol', frm, 'required')"
749 i18n>This field is required.</span>
752 <!-- Privacy protocol for snmp V3 -->
753 <div class="form-group row"
754 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
755 <label class="cd-col-form-label"
756 for="privacy_protocol"
757 i18n>Privacy Protocol</label>
758 <div class="cd-col-form-input">
759 <select id="privacy_protocol"
760 name="privacy_protocol"
762 formControlName="privacy_protocol">
764 [ngValue]="null">-- Select privacy protocol --</option>
765 <option *ngFor="let privacyProtocol of ['DES', 'AES']"
766 [value]="privacyProtocol">
767 {{ privacyProtocol }}
774 <legend i18n>Credentials</legend>
775 <!-- snmp v2c snmp_community -->
776 <div class="form-group row"
777 *ngIf="serviceForm.controls.snmp_version.value === 'V2c'">
778 <label class="cd-col-form-label required"
779 for="snmp_community">
780 <span i18n>SNMP Community</span>
782 <div class="cd-col-form-input">
783 <input id="snmp_community"
786 formControlName="snmp_community">
787 <span class="invalid-feedback"
788 *ngIf="serviceForm.showError('snmp_community', frm, 'required')"
789 i18n>This field is required.</span>
792 <!-- snmp v3 auth username -->
793 <div class="form-group row"
794 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
795 <label class="cd-col-form-label required"
796 for="snmp_v3_auth_username">
797 <span i18n>Username</span>
799 <div class="cd-col-form-input">
800 <input id="snmp_v3_auth_username"
803 formControlName="snmp_v3_auth_username">
804 <span class="invalid-feedback"
805 *ngIf="serviceForm.showError('snmp_v3_auth_username', frm, 'required')"
806 i18n>This field is required.</span>
809 <!-- snmp v3 auth password -->
810 <div class="form-group row"
811 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
812 <label class="cd-col-form-label required"
813 for="snmp_v3_auth_password">
814 <span i18n>Password</span>
816 <div class="cd-col-form-input">
817 <input id="snmp_v3_auth_password"
820 formControlName="snmp_v3_auth_password">
821 <span class="invalid-feedback"
822 *ngIf="serviceForm.showError('snmp_v3_auth_password', frm, 'required')"
823 i18n>This field is required.</span>
826 <!-- snmp v3 priv password -->
827 <div class="form-group row"
828 *ngIf="serviceForm.controls.snmp_version.value === 'V3' && serviceForm.controls.privacy_protocol.value !== null && serviceForm.controls.privacy_protocol.value !== undefined">
829 <label class="cd-col-form-label required"
830 for="snmp_v3_priv_password">
831 <span i18n>Encryption</span>
833 <div class="cd-col-form-input">
834 <input id="snmp_v3_priv_password"
837 formControlName="snmp_v3_priv_password">
838 <span class="invalid-feedback"
839 *ngIf="serviceForm.showError('snmp_v3_priv_password', frm, 'required')"
840 i18n>This field is required.</span>
845 <!-- RGW, Ingress & iSCSI -->
846 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && ['rgw', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)">
848 <div class="form-group row">
849 <div class="cd-col-form-offset">
850 <div class="custom-control custom-checkbox">
851 <input class="custom-control-input"
854 formControlName="ssl">
855 <label class="custom-control-label"
863 <div *ngIf="serviceForm.controls.ssl.value"
864 class="form-group row">
865 <label class="cd-col-form-label"
867 <span i18n>Certificate</span>
868 <cd-helper i18n>The SSL certificate in PEM format.</cd-helper>
870 <div class="cd-col-form-input">
871 <textarea id="ssl_cert"
872 class="form-control resize-vertical text-monospace text-pre"
873 formControlName="ssl_cert"
877 (change)="fileUpload($event.target.files, 'ssl_cert')">
878 <span class="invalid-feedback"
879 *ngIf="serviceForm.showError('ssl_cert', frm, 'required')"
880 i18n>This field is required.</span>
881 <span class="invalid-feedback"
882 *ngIf="serviceForm.showError('ssl_cert', frm, 'pattern')"
883 i18n>Invalid SSL certificate.</span>
888 <div *ngIf="serviceForm.controls.ssl.value && !(['rgw', 'ingress'].includes(serviceForm.controls.service_type.value))"
889 class="form-group row">
890 <label class="cd-col-form-label"
892 <span i18n>Private key</span>
893 <cd-helper i18n>The SSL private key in PEM format.</cd-helper>
895 <div class="cd-col-form-input">
896 <textarea id="ssl_key"
897 class="form-control resize-vertical text-monospace text-pre"
898 formControlName="ssl_key"
902 (change)="fileUpload($event.target.files,'ssl_key')">
903 <span class="invalid-feedback"
904 *ngIf="serviceForm.showError('ssl_key', frm, 'required')"
905 i18n>This field is required.</span>
906 <span class="invalid-feedback"
907 *ngIf="serviceForm.showError('ssl_key', frm, 'pattern')"
908 i18n>Invalid SSL private key.</span>
913 <ng-container *ngIf="serviceForm.controls.service_type.value === 'grafana'">
914 <div class="form-group row">
915 <label class="cd-col-form-label"
917 <span i18n>Grafana Port</span>
919 <span i18n>The default port used by grafana.</span>
922 <div class="cd-col-form-input">
923 <input id="grafana_port"
926 formControlName="grafana_port"
929 <span class="invalid-feedback"
930 *ngIf="serviceForm.showError('grafana_port', frm, 'pattern')"
931 i18n>The entered value needs to be a number.</span>
932 <span class="invalid-feedback"
933 *ngIf="serviceForm.showError('grafana_port', frm, 'min')"
934 i18n>The value must be at least 1.</span>
935 <span class="invalid-feedback"
936 *ngIf="serviceForm.showError('grafana_port', frm, 'max')"
937 i18n>The value cannot exceed 65535.</span>
938 <span class="invalid-feedback"
939 *ngIf="serviceForm.showError('grafana_port', frm, 'required')"
940 i18n>This field is required.</span>
944 <div class="form-group row">
946 class="cd-col-form-label"
947 for="grafana_admin_password">
948 <span>Grafana Password</span>
949 <cd-helper>The password of the default Grafana Admin. Set once on first-run.</cd-helper>
951 <div class="cd-col-form-input">
952 <div class="input-group">
953 <input id="grafana_admin_password"
956 autocomplete="new-password"
957 [attr.disabled]="editing ? true:null"
958 formControlName="grafana_admin_password">
959 <span class="input-group-append">
960 <button type="button"
961 class="btn btn-light"
962 cdPasswordButton="grafana_admin_password">
964 <cd-copy-2-clipboard-button source="grafana_admin_password">
965 </cd-copy-2-clipboard-button>
973 <div class="modal-footer">
974 <div class="text-right">
975 <cd-form-button-panel (submitActionEvent)="onSubmit()"
977 [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>