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
20 <div class="form-group row">
21 <label class="cd-col-form-label required"
24 <div class="cd-col-form-input">
25 <select id="service_type"
28 formControlName="service_type"
29 (change)="onServiceTypeChange($event.target.value)">
31 [ngValue]="null">-- Select a service type --</option>
32 <option *ngFor="let serviceType of serviceTypes"
33 [value]="serviceType">
37 <span class="invalid-feedback"
38 *ngIf="serviceForm.showError('service_type', frm, 'required')"
39 i18n>This field is required.</span>
43 <!-- backend_service -->
44 <div *ngIf="serviceForm.controls.service_type.value === 'ingress'"
45 class="form-group row">
47 class="cd-col-form-label"
48 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
49 for="backend_service">Backend Service</label>
50 <div class="cd-col-form-input">
51 <select id="backend_service"
52 name="backend_service"
54 formControlName="backend_service"
55 (change)="prePopulateId()">
56 <option *ngIf="services === null"
58 i18n>Loading...</option>
59 <option *ngIf="services !== null && services.length === 0"
61 i18n>-- No service available --</option>
62 <option *ngIf="services !== null && services.length > 0"
64 i18n>-- Select an existing service --</option>
65 <option *ngFor="let service of services"
66 [value]="service.service_name">{{ service.service_name }}</option>
68 <span class="invalid-feedback"
69 *ngIf="serviceForm.showError('backend_service', frm, 'required')"
70 i18n>This field is required.</span>
76 <div class="form-group row"
77 *ngIf="serviceForm.controls.service_type.value === 'nvmeof'">
79 class="cd-col-form-label required"
80 for="pool">Block Pool</label>
81 <div class="cd-col-form-input">
85 formControlName="pool"
86 (change)="onBlockPoolChange()">
87 <option *ngIf="rbdPools === null"
89 i18n>Loading...</option>
90 <option *ngIf="rbdPools && rbdPools.length === 0"
92 i18n>-- No block pools available --</option>
93 <option *ngIf="rbdPools && rbdPools.length > 0"
95 i18n>-- Select a pool --</option>
96 <option *ngFor="let pool of rbdPools"
97 [value]="pool.pool_name">{{ pool.pool_name }}</option>
100 A pool in which the gateway configuration can be managed.
102 <span class="invalid-feedback"
103 *ngIf="serviceForm.showError('pool', frm, 'required')"
104 i18n>This field is required.</span>
109 <div class="form-group row"
110 *ngIf="serviceForm.controls.service_type.value !== 'snmp-gateway'">
111 <label class="cd-col-form-label"
112 [ngClass]="{'required': ['mds', 'rgw', 'nfs', 'iscsi', 'nvmeof', 'smb', 'ingress'].includes(serviceForm.controls.service_type.value)}"
114 <span i18n>Service Name</span>
116 <div class="cd-col-form-input">
117 <div class="input-group">
118 <span class="input-group-text"
119 *ngIf="serviceForm.controls.service_type.value && ['mds', 'rgw', 'nfs', 'iscsi', 'nvmeof', 'smb', 'ingress'].includes(serviceForm.controls.service_type.value)"
121 i18n>{{serviceForm.controls.service_type.value}}.
123 <input id="service_id"
126 formControlName="service_id">
128 <span class="invalid-feedback"
129 *ngIf="serviceForm.showError('service_id', frm, 'required')"
130 i18n>This field is required.</span>
131 <span class="invalid-feedback"
132 *ngIf="serviceForm.showError('service_id', frm, 'uniqueName')"
133 i18n>This service id is already in use.</span>
134 <span class="invalid-feedback"
135 *ngIf="serviceForm.showError('service_id', frm, 'mdsPattern')"
136 i18n>MDS service id must start with a letter and contain alphanumeric characters or '.', '-', and '_'</span>
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="realm_name"
150 [attr.disabled]="realmList.length === 0 || editing ? true : null">
151 <option *ngIf="realmList.length === 0"
153 selected>-- No realm available --</option>
154 <option *ngFor="let realm of realmList"
155 [value]="realm.name">
162 <div class="form-group row"
163 *ngIf="serviceForm.controls.service_type.value === 'rgw'">
164 <label class="cd-col-form-label"
166 i18n>Zone Group</label>
167 <div class="cd-col-form-input">
168 <select class="form-select"
170 formControlName="zonegroup_name"
171 name="zonegroup_name"
172 [attr.disabled]="zonegroupList.length === 0 || editing ? true : null">
173 <option *ngFor="let zonegroup of zonegroupList"
174 [value]="zonegroup.name">
181 <div class="form-group row"
182 *ngIf="serviceForm.controls.service_type.value === 'rgw'">
183 <label class="cd-col-form-label"
186 <div class="cd-col-form-input">
187 <select class="form-select"
189 formControlName="zone_name"
191 [attr.disabled]="zoneList.length === 0 || editing ? true : null">
192 <option *ngFor="let zone of zoneList"
201 <div class="form-group row">
202 <div class="cd-col-form-offset">
203 <div class="custom-control custom-checkbox">
204 <input class="custom-control-input"
207 formControlName="unmanaged">
208 <label class="custom-control-label m-0"
210 i18n>Unmanaged</label>
211 <cd-help-text i18n>If Unmanaged is selected, the orchestrator will not stop or stop any daemons associated with this service. Placement and all other properties will be ignored.</cd-help-text>
217 <div *ngIf="!serviceForm.controls.unmanaged.value"
218 class="form-group row">
219 <label class="cd-col-form-label"
221 i18n>Placement</label>
222 <div class="cd-col-form-input">
223 <select id="placement"
225 formControlName="placement"
226 (change)="onServiceTypeChange($event.target.value)">
228 value="hosts">Hosts</option>
230 value="label">Label</option>
236 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'label'"
237 class="form-group row">
239 class="cd-col-form-label"
240 for="label">Label</label>
241 <div class="cd-col-form-input">
245 formControlName="label"
246 [ngbTypeahead]="searchLabels"
247 (focus)="labelFocus.next($any($event).target.value)"
248 (click)="labelClick.next($any($event).target.value)">
249 <span class="invalid-feedback"
250 *ngIf="serviceForm.showError('label', frm, 'required')"
251 i18n>This field is required.</span>
256 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'hosts'"
257 class="form-group row">
258 <label class="cd-col-form-label"
261 <div class="cd-col-form-input">
262 <cd-select-badges id="hosts"
263 [data]="serviceForm.controls.hosts.value"
264 [options]="hosts.options"
265 [messages]="hosts.messages">
271 <div *ngIf="!serviceForm.controls.unmanaged.value"
272 class="form-group row">
273 <label class="cd-col-form-label"
275 <span i18n>Count</span>
277 <div class="cd-col-form-input">
281 formControlName="count"
283 <cd-help-text i18n>Number of deamons that will be deployed</cd-help-text>
284 <span class="invalid-feedback"
285 *ngIf="serviceForm.showError('count', frm, 'min')"
286 i18n>The value must be at least 1.</span>
287 <span class="invalid-feedback"
288 *ngIf="serviceForm.showError('count', frm, 'pattern')"
289 i18n>The entered value needs to be a number.</span>
294 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'rgw'">
295 <!-- rgw_frontend_port -->
296 <div class="form-group row">
298 class="cd-col-form-label"
299 for="rgw_frontend_port">Port</label>
300 <div class="cd-col-form-input">
301 <input id="rgw_frontend_port"
304 formControlName="rgw_frontend_port"
307 <span class="invalid-feedback"
308 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'pattern')"
309 i18n>The entered value needs to be a number.</span>
310 <span class="invalid-feedback"
311 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'min')"
312 i18n>The value must be at least 1.</span>
313 <span class="invalid-feedback"
314 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'max')"
315 i18n>The value cannot exceed 65535.</span>
322 <div class="form-group row"
323 *ngIf="serviceForm.controls.service_type.value === 'iscsi'">
325 class="cd-col-form-label required"
326 for="pool">Pool</label>
327 <div class="cd-col-form-input">
331 formControlName="pool">
332 <option *ngIf="pools === null"
334 i18n>Loading...</option>
335 <option *ngIf="pools && pools.length === 0"
337 i18n>-- No pools available --</option>
338 <option *ngIf="pools && pools.length > 0"
340 i18n>-- Select a pool --</option>
341 <option *ngFor="let pool of pools"
342 [value]="pool.pool_name">{{ pool.pool_name }}</option>
344 <span class="invalid-feedback"
345 *ngIf="serviceForm.showError('pool', frm, 'required')"
346 i18n>This field is required.</span>
350 <!-- fields in iSCSI which are hidden when unmanaged is true -->
351 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'iscsi'">
352 <!-- trusted_ip_list -->
353 <div class="form-group row">
354 <label class="cd-col-form-label"
355 for="trusted_ip_list">
356 <span i18n>Trusted IPs</span>
358 <span i18n>Comma separated list of IP addresses.</span>
360 <span i18n>Please add the <b>Ceph Manager</b> IP addresses here, otherwise the iSCSI gateways can't be reached.</span>
363 <div class="cd-col-form-input">
364 <input id="trusted_ip_list"
367 formControlName="trusted_ip_list">
372 <div class="form-group row">
374 class="cd-col-form-label"
375 for="api_port">Port</label>
376 <div class="cd-col-form-input">
380 formControlName="api_port"
383 <span class="invalid-feedback"
384 *ngIf="serviceForm.showError('api_port', frm, 'pattern')"
385 i18n>The entered value needs to be a number.</span>
386 <span class="invalid-feedback"
387 *ngIf="serviceForm.showError('api_port', frm, 'min')"
388 i18n>The value must be at least 1.</span>
389 <span class="invalid-feedback"
390 *ngIf="serviceForm.showError('api_port', frm, 'max')"
391 i18n>The value cannot exceed 65535.</span>
396 <div class="form-group row">
398 class="cd-col-form-label"
399 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
400 for="api_user">User</label>
401 <div class="cd-col-form-input">
405 formControlName="api_user">
406 <span class="invalid-feedback"
407 *ngIf="serviceForm.showError('api_user', frm, 'required')"
408 i18n>This field is required.</span>
412 <!-- api_password -->
413 <div class="form-group row">
415 class="cd-col-form-label"
416 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
417 for="api_password">Password</label>
418 <div class="cd-col-form-input">
419 <div class="input-group">
420 <input id="api_password"
423 autocomplete="new-password"
424 formControlName="api_password">
425 <button type="button"
426 class="btn btn-light"
427 cdPasswordButton="api_password">
429 <cd-copy-2-clipboard-button source="api_password">
430 </cd-copy-2-clipboard-button>
431 <span class="invalid-feedback"
432 *ngIf="serviceForm.showError('api_password', frm, 'required')"
433 i18n>This field is required.</span>
440 <ng-container *ngIf="serviceForm.controls.service_type.value === 'smb'">
441 <div class="form-group row">
442 <label class="cd-col-form-label required"
447 <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,
448 and may not provide actual clustering or availability mechanisms.</span>
451 <div class="cd-col-form-input">
452 <input id="cluster_id"
455 formControlName="cluster_id"
458 <span class="invalid-feedback"
459 *ngIf="serviceForm.showError('cluster_id', frm, 'required')"
460 i18n>This field is required.</span>
464 <div class="form-group row">
465 <label class="cd-col-form-label required"
467 <span i18n>Config URI</span>
469 Configuration source that should be loaded by the samba-container as the primary configuration file.
472 <div class="cd-col-form-input">
473 <input id="config_uri"
476 formControlName="config_uri"
477 placeholder="rados://.smb/foo/scc.toml"
479 <span class="invalid-feedback"
480 *ngIf="serviceForm.showError('config_uri', frm, 'required')"
481 i18n>This field is required.</span>
482 <span class="invalid-feedback"
483 *ngIf="serviceForm.showError('config_uri', frm, 'configUriPattern')"
484 i18n>The value must start with either 'http:', 'https:', 'rados:' or 'rados:mon-config-key:'</span>
488 <div class="form-group row"
489 formGroupName="features">
490 <label class="cd-col-form-label"
494 <span>Pre-defined terms enabling specific deployment characteristics.</span>
497 <div class="cd-col-form-input">
498 <div class="custom-control custom-checkbox"
499 *ngFor="let feature of smbFeaturesList">
500 <input class="custom-control-input"
504 formControlName="{{feature}}">
505 <label class="custom-control-label"
513 <div class="form-group row">
514 <label class="cd-col-form-label"
516 <span i18n>Custom DNS</span>
518 <span>Comma separated list of DNSs.</span>
520 <span>A list of IP addresses that will be used as the DNS servers for a Samba container.</span>
523 <div class="cd-col-form-input">
524 <input id="custom_dns"
527 formControlName="custom_dns"
528 placeholder="192.168.76.204"
533 <div class="form-group row">
534 <label class="cd-col-form-label"
536 <span i18n>Join sources</span>
538 <span>Comma separated list of URIs.</span>
540 <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>
543 <div class="cd-col-form-input">
544 <input id="join_sources"
547 formControlName="join_sources"
548 placeholder="rados:mon-config-key:smb/config/foo/join1.json"
553 <div class="form-group row">
554 <label class="cd-col-form-label"
556 <span i18n>User sources</span>
558 <span>Comma separated list of URIs.</span>
560 <span>A list of pseudo-uris containing data the samba-container can use to create users (and/or
561 groups). A ceph based samba container may typically use a rados uri
562 or a mon config-key store uri </span>
565 <div class="cd-col-form-input">
566 <input id="user_sources"
569 formControlName="user_sources"
570 placeholder="rados:mon-config-key:smb/config/foo/join2.json"
575 <div class="form-group row">
576 <label class="cd-col-form-label"
577 for="include_ceph_users">
578 <span i18n>Ceph users</span>
580 <span>Comma separated list of Ceph users.</span>
582 <span>A list of cephx user names that the Samba Containers may use.</span>
585 <div class="cd-col-form-input">
586 <input id="include_ceph_users"
589 formControlName="include_ceph_users"
590 placeholder="client.smb.fs.cluster.foo"
598 <ng-container *ngIf="serviceForm.controls.service_type.value === 'ingress'">
600 <div class="form-group row">
601 <label class="cd-col-form-label"
602 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
604 <span i18n>Virtual IP</span>
606 <span i18n>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</span>
609 <div class="cd-col-form-input">
610 <input id="virtual_ip"
613 formControlName="virtual_ip">
614 <span class="invalid-feedback"
615 *ngIf="serviceForm.showError('virtual_ip', frm, 'required')"
616 i18n>This field is required.</span>
620 <!-- frontend_port -->
621 <div class="form-group row">
622 <label class="cd-col-form-label"
623 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
625 <span i18n>Frontend Port</span>
627 <span i18n>The port used to access the ingress service.</span>
630 <div class="cd-col-form-input">
631 <input id="frontend_port"
634 formControlName="frontend_port"
637 <span class="invalid-feedback"
638 *ngIf="serviceForm.showError('frontend_port', frm, 'pattern')"
639 i18n>The entered value needs to be a number.</span>
640 <span class="invalid-feedback"
641 *ngIf="serviceForm.showError('frontend_port', frm, 'min')"
642 i18n>The value must be at least 1.</span>
643 <span class="invalid-feedback"
644 *ngIf="serviceForm.showError('frontend_port', frm, 'max')"
645 i18n>The value cannot exceed 65535.</span>
646 <span class="invalid-feedback"
647 *ngIf="serviceForm.showError('frontend_port', frm, 'required')"
648 i18n>This field is required.</span>
652 <!-- monitor_port -->
653 <div class="form-group row">
654 <label class="cd-col-form-label"
655 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
657 <span i18n>Monitor Port</span>
659 <span i18n>The port used by haproxy for load balancer status.</span>
662 <div class="cd-col-form-input">
663 <input id="monitor_port"
666 formControlName="monitor_port"
669 <span class="invalid-feedback"
670 *ngIf="serviceForm.showError('monitor_port', frm, 'pattern')"
671 i18n>The entered value needs to be a number.</span>
672 <span class="invalid-feedback"
673 *ngIf="serviceForm.showError('monitor_port', frm, 'min')"
674 i18n>The value must be at least 1.</span>
675 <span class="invalid-feedback"
676 *ngIf="serviceForm.showError('monitor_port', frm, 'max')"
677 i18n>The value cannot exceed 65535.</span>
678 <span class="invalid-feedback"
679 *ngIf="serviceForm.showError('monitor_port', frm, 'required')"
680 i18n>This field is required.</span>
683 <!-- virtual_interface_networks -->
684 <div class="form-group row"
685 *ngIf="!serviceForm.controls.unmanaged.value">
686 <label class="cd-col-form-label"
687 for="virtual_interface_networks">
688 <span i18n>CIDR Networks</span>
690 <span i18n>A list of networks to identify which network interface to use for the virtual IP address.</span>
693 <div class="cd-col-form-input">
694 <input id="virtual_interface_networks"
697 formControlName="virtual_interface_networks">
702 <!-- SNMP-Gateway -->
703 <ng-container *ngIf="serviceForm.controls.service_type.value === 'snmp-gateway'">
704 <!-- snmp-version -->
705 <div class="form-group row">
706 <label class="cd-col-form-label required"
709 <div class="cd-col-form-input">
710 <select id="snmp_version"
713 formControlName="snmp_version"
714 (change)="clearValidations()">
716 [ngValue]="null">-- Select SNMP version --</option>
717 <option *ngFor="let snmpVersion of ['V2c', 'V3']"
718 [value]="snmpVersion">{{ snmpVersion }}</option>
720 <span class="invalid-feedback"
721 *ngIf="serviceForm.showError('snmp_version', frm, 'required')"
722 i18n>This field is required.</span>
726 <div class="form-group row">
727 <label class="cd-col-form-label required"
728 for="snmp_destination">
729 <span i18n>Destination</span>
731 <span i18n>Must be of the format hostname:port.</span>
734 <div class="cd-col-form-input">
735 <input id="snmp_destination"
738 formControlName="snmp_destination">
739 <span class="invalid-feedback"
740 *ngIf="serviceForm.showError('snmp_destination', frm, 'required')"
741 i18n>This field is required.</span>
742 <span class="invalid-feedback"
743 *ngIf="serviceForm.showError('snmp_destination', frm, 'snmpDestinationPattern')"
744 i18n>The value does not match the pattern: <strong>hostname:port</strong></span>
747 <!-- Engine id for snmp V3 -->
748 <div class="form-group row"
749 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
750 <label class="cd-col-form-label required"
752 <span i18n>Engine Id</span>
754 <span i18n>Unique identifier for the device (in hex).</span>
757 <div class="cd-col-form-input">
758 <input id="engine_id"
761 formControlName="engine_id">
762 <span class="invalid-feedback"
763 *ngIf="serviceForm.showError('engine_id', frm, 'required')"
764 i18n>This field is required.</span>
765 <span class="invalid-feedback"
766 *ngIf="serviceForm.showError('engine_id', frm, 'snmpEngineIdPattern')"
767 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>
770 <!-- Auth protocol for snmp V3 -->
771 <div class="form-group row"
772 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
773 <label class="cd-col-form-label required"
775 i18n>Auth Protocol</label>
776 <div class="cd-col-form-input">
777 <select id="auth_protocol"
780 formControlName="auth_protocol">
782 [ngValue]="null">-- Select auth protocol --</option>
783 <option *ngFor="let authProtocol of ['SHA', 'MD5']"
784 [value]="authProtocol">
788 <span class="invalid-feedback"
789 *ngIf="serviceForm.showError('auth_protocol', frm, 'required')"
790 i18n>This field is required.</span>
793 <!-- Privacy protocol for snmp V3 -->
794 <div class="form-group row"
795 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
796 <label class="cd-col-form-label"
797 for="privacy_protocol"
798 i18n>Privacy Protocol</label>
799 <div class="cd-col-form-input">
800 <select id="privacy_protocol"
801 name="privacy_protocol"
803 formControlName="privacy_protocol">
805 [ngValue]="null">-- Select privacy protocol --</option>
806 <option *ngFor="let privacyProtocol of ['DES', 'AES']"
807 [value]="privacyProtocol">
808 {{ privacyProtocol }}
815 <legend i18n>Credentials</legend>
816 <!-- snmp v2c snmp_community -->
817 <div class="form-group row"
818 *ngIf="serviceForm.controls.snmp_version.value === 'V2c'">
819 <label class="cd-col-form-label required"
820 for="snmp_community">
821 <span i18n>SNMP Community</span>
823 <div class="cd-col-form-input">
824 <input id="snmp_community"
827 formControlName="snmp_community">
828 <span class="invalid-feedback"
829 *ngIf="serviceForm.showError('snmp_community', frm, 'required')"
830 i18n>This field is required.</span>
833 <!-- snmp v3 auth username -->
834 <div class="form-group row"
835 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
836 <label class="cd-col-form-label required"
837 for="snmp_v3_auth_username">
838 <span i18n>Username</span>
840 <div class="cd-col-form-input">
841 <input id="snmp_v3_auth_username"
844 formControlName="snmp_v3_auth_username">
845 <span class="invalid-feedback"
846 *ngIf="serviceForm.showError('snmp_v3_auth_username', frm, 'required')"
847 i18n>This field is required.</span>
850 <!-- snmp v3 auth password -->
851 <div class="form-group row"
852 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
853 <label class="cd-col-form-label required"
854 for="snmp_v3_auth_password">
855 <span i18n>Password</span>
857 <div class="cd-col-form-input">
858 <input id="snmp_v3_auth_password"
861 formControlName="snmp_v3_auth_password">
862 <span class="invalid-feedback"
863 *ngIf="serviceForm.showError('snmp_v3_auth_password', frm, 'required')"
864 i18n>This field is required.</span>
867 <!-- snmp v3 priv password -->
868 <div class="form-group row"
869 *ngIf="serviceForm.controls.snmp_version.value === 'V3' && serviceForm.controls.privacy_protocol.value !== null && serviceForm.controls.privacy_protocol.value !== undefined">
870 <label class="cd-col-form-label required"
871 for="snmp_v3_priv_password">
872 <span i18n>Encryption</span>
874 <div class="cd-col-form-input">
875 <input id="snmp_v3_priv_password"
878 formControlName="snmp_v3_priv_password">
879 <span class="invalid-feedback"
880 *ngIf="serviceForm.showError('snmp_v3_priv_password', frm, 'required')"
881 i18n>This field is required.</span>
886 <!-- RGW, Ingress & iSCSI -->
887 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && ['rgw', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)">
889 <div class="form-group row">
890 <div class="cd-col-form-offset">
891 <div class="custom-control custom-checkbox">
892 <input class="custom-control-input"
895 formControlName="ssl">
896 <label class="custom-control-label"
904 <div *ngIf="serviceForm.controls.ssl.value"
905 class="form-group row">
906 <label class="cd-col-form-label"
908 <span i18n>Certificate</span>
909 <cd-helper i18n>The SSL certificate in PEM format.</cd-helper>
911 <div class="cd-col-form-input">
912 <textarea id="ssl_cert"
913 class="form-control resize-vertical text-monospace text-pre"
914 formControlName="ssl_cert"
918 (change)="fileUpload($event.target.files, 'ssl_cert')">
919 <span class="invalid-feedback"
920 *ngIf="serviceForm.showError('ssl_cert', frm, 'required')"
921 i18n>This field is required.</span>
922 <span class="invalid-feedback"
923 *ngIf="serviceForm.showError('ssl_cert', frm, 'pattern')"
924 i18n>Invalid SSL certificate.</span>
929 <div *ngIf="serviceForm.controls.ssl.value && !(['rgw', 'ingress'].includes(serviceForm.controls.service_type.value))"
930 class="form-group row">
931 <label class="cd-col-form-label"
933 <span i18n>Private key</span>
934 <cd-helper i18n>The SSL private key in PEM format.</cd-helper>
936 <div class="cd-col-form-input">
937 <textarea id="ssl_key"
938 class="form-control resize-vertical text-monospace text-pre"
939 formControlName="ssl_key"
943 (change)="fileUpload($event.target.files,'ssl_key')">
944 <span class="invalid-feedback"
945 *ngIf="serviceForm.showError('ssl_key', frm, 'required')"
946 i18n>This field is required.</span>
947 <span class="invalid-feedback"
948 *ngIf="serviceForm.showError('ssl_key', frm, 'pattern')"
949 i18n>Invalid SSL private key.</span>
954 <ng-container *ngIf="serviceForm.controls.service_type.value === 'grafana'">
955 <div class="form-group row">
956 <label class="cd-col-form-label"
958 <span i18n>Grafana Port</span>
960 <span i18n>The default port used by grafana.</span>
963 <div class="cd-col-form-input">
964 <input id="grafana_port"
967 formControlName="grafana_port"
970 <span class="invalid-feedback"
971 *ngIf="serviceForm.showError('grafana_port', frm, 'pattern')"
972 i18n>The entered value needs to be a number.</span>
973 <span class="invalid-feedback"
974 *ngIf="serviceForm.showError('grafana_port', frm, 'min')"
975 i18n>The value must be at least 1.</span>
976 <span class="invalid-feedback"
977 *ngIf="serviceForm.showError('grafana_port', frm, 'max')"
978 i18n>The value cannot exceed 65535.</span>
979 <span class="invalid-feedback"
980 *ngIf="serviceForm.showError('grafana_port', frm, 'required')"
981 i18n>This field is required.</span>
985 <div class="form-group row">
987 class="cd-col-form-label"
988 for="grafana_admin_password">
989 <span>Grafana Password</span>
990 <cd-helper>The password of the default Grafana Admin. Set once on first-run.</cd-helper>
992 <div class="cd-col-form-input">
993 <div class="input-group">
994 <input id="grafana_admin_password"
997 autocomplete="new-password"
998 [attr.disabled]="editing ? true:null"
999 formControlName="grafana_admin_password">
1000 <span class="input-group-append">
1001 <button type="button"
1002 class="btn btn-light"
1003 cdPasswordButton="grafana_admin_password">
1005 <cd-copy-2-clipboard-button source="grafana_admin_password">
1006 </cd-copy-2-clipboard-button>
1014 <div class="modal-footer">
1015 <div class="text-right">
1016 <cd-form-button-panel (submitActionEvent)="onSubmit()"
1017 [form]="serviceForm"
1018 [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>