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">
12 <div class="form-group row">
13 <label class="cd-col-form-label required"
16 <div class="cd-col-form-input">
17 <select id="service_type"
19 class="form-control custom-select"
20 formControlName="service_type">
22 [ngValue]="null">-- Select a service type --</option>
23 <option *ngFor="let serviceType of serviceTypes"
24 [value]="serviceType">
28 <span class="invalid-feedback"
29 *ngIf="serviceForm.showError('service_type', frm, 'required')"
30 i18n>This field is required.</span>
34 <!-- backend_service -->
35 <div *ngIf="serviceForm.controls.service_type.value === 'ingress'"
36 class="form-group row">
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 custom-select"
45 formControlName="backend_service"
46 (change)="prePopulateId()">
47 <option *ngIf="services === null"
49 i18n>Loading...</option>
50 <option *ngIf="services !== null && services.length === 0"
52 i18n>-- No service available --</option>
53 <option *ngIf="services !== null && services.length > 0"
55 i18n>-- Select an existing RGW service --</option>
56 <option *ngFor="let service of services"
57 [value]="service.service_name">{{ service.service_name }}</option>
59 <span class="invalid-feedback"
60 *ngIf="serviceForm.showError('backend_service', frm, 'required')"
61 i18n>This field is required.</span>
66 <div class="form-group row">
68 class="cd-col-form-label"
69 [ngClass]="{'required': ['mds', 'rgw', 'nfs', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)}"
70 for="service_id">Id</label>
71 <div class="cd-col-form-input">
72 <input id="service_id"
75 formControlName="service_id">
76 <span class="invalid-feedback"
77 *ngIf="serviceForm.showError('service_id', frm, 'required')"
78 i18n>This field is required.</span>
79 <span class="invalid-feedback"
80 *ngIf="serviceForm.showError('service_id', frm, 'rgwPattern')"
81 i18n>The value does not match the pattern <strong><service_id>[.<realm_name>.<zone_name>]</strong>.</span>
86 <div class="form-group row">
87 <div class="cd-col-form-offset">
88 <div class="custom-control custom-checkbox">
89 <input class="custom-control-input"
92 formControlName="unmanaged">
93 <label class="custom-control-label"
95 i18n>Unmanaged</label>
101 <div *ngIf="!serviceForm.controls.unmanaged.value"
102 class="form-group row">
103 <label class="cd-col-form-label"
105 i18n>Placement</label>
106 <div class="cd-col-form-input">
107 <select id="placement"
108 class="form-control custom-select"
109 formControlName="placement">
111 value="hosts">Hosts</option>
113 value="label">Label</option>
119 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'label'"
120 class="form-group row">
122 class="cd-col-form-label"
123 for="label">Label</label>
124 <div class="cd-col-form-input">
128 formControlName="label"
129 [ngbTypeahead]="searchLabels"
130 (focus)="labelFocus.next($any($event).target.value)"
131 (click)="labelClick.next($any($event).target.value)">
132 <span class="invalid-feedback"
133 *ngIf="serviceForm.showError('label', frm, 'required')"
134 i18n>This field is required.</span>
139 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'hosts'"
140 class="form-group row">
141 <label class="cd-col-form-label"
144 <div class="cd-col-form-input">
145 <cd-select-badges id="hosts"
146 [data]="serviceForm.controls.hosts.value"
147 [options]="hosts.options"
148 [messages]="hosts.messages">
154 <div *ngIf="!serviceForm.controls.unmanaged.value"
155 class="form-group row">
156 <label class="cd-col-form-label"
158 <span i18n>Count</span>
159 <cd-helper i18n>Only that number of daemons will be created.</cd-helper>
161 <div class="cd-col-form-input">
165 formControlName="count"
167 <span class="invalid-feedback"
168 *ngIf="serviceForm.showError('count', frm, 'min')"
169 i18n>The value must be at least 1.</span>
170 <span class="invalid-feedback"
171 *ngIf="serviceForm.showError('count', frm, 'pattern')"
172 i18n>The entered value needs to be a number.</span>
177 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'rgw'">
178 <!-- rgw_frontend_port -->
179 <div class="form-group row">
181 class="cd-col-form-label"
182 for="rgw_frontend_port">Port</label>
183 <div class="cd-col-form-input">
184 <input id="rgw_frontend_port"
187 formControlName="rgw_frontend_port"
190 <span class="invalid-feedback"
191 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'pattern')"
192 i18n>The entered value needs to be a number.</span>
193 <span class="invalid-feedback"
194 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'min')"
195 i18n>The value must be at least 1.</span>
196 <span class="invalid-feedback"
197 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'max')"
198 i18n>The value cannot exceed 65535.</span>
204 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'iscsi'">
206 <div class="form-group row">
208 class="cd-col-form-label required"
209 for="pool">Pool</label>
210 <div class="cd-col-form-input">
213 class="form-control custom-select"
214 formControlName="pool">
215 <option *ngIf="pools === null"
217 i18n>Loading...</option>
218 <option *ngIf="pools && pools.length === 0"
220 i18n>-- No pools available --</option>
221 <option *ngIf="pools && pools.length > 0"
223 i18n>-- Select a pool --</option>
224 <option *ngFor="let pool of pools"
225 [value]="pool.pool_name">{{ pool.pool_name }}</option>
227 <span class="invalid-feedback"
228 *ngIf="serviceForm.showError('pool', frm, 'required')"
229 i18n>This field is required.</span>
233 <!-- trusted_ip_list -->
234 <div class="form-group row">
235 <label class="cd-col-form-label"
236 for="trusted_ip_list">
237 <span i18n>Trusted IPs</span>
239 <span i18n>Comma separated list of IP addresses.</span>
241 <span i18n>Please add the <b>Ceph Manager</b> IP addresses here, otherwise the iSCSI gateways can't be reached.</span>
244 <div class="cd-col-form-input">
245 <input id="trusted_ip_list"
248 formControlName="trusted_ip_list">
253 <div class="form-group row">
255 class="cd-col-form-label"
256 for="api_port">Port</label>
257 <div class="cd-col-form-input">
261 formControlName="api_port"
264 <span class="invalid-feedback"
265 *ngIf="serviceForm.showError('api_port', frm, 'pattern')"
266 i18n>The entered value needs to be a number.</span>
267 <span class="invalid-feedback"
268 *ngIf="serviceForm.showError('api_port', frm, 'min')"
269 i18n>The value must be at least 1.</span>
270 <span class="invalid-feedback"
271 *ngIf="serviceForm.showError('api_port', frm, 'max')"
272 i18n>The value cannot exceed 65535.</span>
277 <div class="form-group row">
279 class="cd-col-form-label"
280 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
281 for="api_user">User</label>
282 <div class="cd-col-form-input">
286 formControlName="api_user">
287 <span class="invalid-feedback"
288 *ngIf="serviceForm.showError('api_user', frm, 'required')"
289 i18n>This field is required.</span>
293 <!-- api_password -->
294 <div class="form-group row">
296 class="cd-col-form-label"
297 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
298 for="api_password">Password</label>
299 <div class="cd-col-form-input">
300 <div class="input-group">
301 <input id="api_password"
304 autocomplete="new-password"
305 formControlName="api_password">
306 <span class="input-group-append">
307 <button type="button"
308 class="btn btn-light"
309 cdPasswordButton="api_password">
311 <cd-copy-2-clipboard-button source="api_password">
312 </cd-copy-2-clipboard-button>
314 <span class="invalid-feedback"
315 *ngIf="serviceForm.showError('api_password', frm, 'required')"
316 i18n>This field is required.</span>
323 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'ingress'">
325 <div class="form-group row">
326 <label class="cd-col-form-label"
327 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
329 <span i18n>Virtual IP</span>
331 <span i18n>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</span>
334 <div class="cd-col-form-input">
335 <input id="virtual_ip"
338 formControlName="virtual_ip">
339 <span class="invalid-feedback"
340 *ngIf="serviceForm.showError('virtual_ip', frm, 'required')"
341 i18n>This field is required.</span>
345 <!-- frontend_port -->
346 <div class="form-group row">
347 <label class="cd-col-form-label"
348 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
350 <span i18n>Frontend Port</span>
352 <span i18n>The port used to access the ingress service.</span>
355 <div class="cd-col-form-input">
356 <input id="frontend_port"
359 formControlName="frontend_port"
362 <span class="invalid-feedback"
363 *ngIf="serviceForm.showError('frontend_port', frm, 'pattern')"
364 i18n>The entered value needs to be a number.</span>
365 <span class="invalid-feedback"
366 *ngIf="serviceForm.showError('frontend_port', frm, 'min')"
367 i18n>The value must be at least 1.</span>
368 <span class="invalid-feedback"
369 *ngIf="serviceForm.showError('frontend_port', frm, 'max')"
370 i18n>The value cannot exceed 65535.</span>
371 <span class="invalid-feedback"
372 *ngIf="serviceForm.showError('frontend_port', frm, 'required')"
373 i18n>This field is required.</span>
377 <!-- monitor_port -->
378 <div class="form-group row">
379 <label class="cd-col-form-label"
380 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
382 <span i18n>Monitor Port</span>
384 <span i18n>The port used by haproxy for load balancer status.</span>
387 <div class="cd-col-form-input">
388 <input id="monitor_port"
391 formControlName="monitor_port"
394 <span class="invalid-feedback"
395 *ngIf="serviceForm.showError('monitor_port', frm, 'pattern')"
396 i18n>The entered value needs to be a number.</span>
397 <span class="invalid-feedback"
398 *ngIf="serviceForm.showError('monitor_port', frm, 'min')"
399 i18n>The value must be at least 1.</span>
400 <span class="invalid-feedback"
401 *ngIf="serviceForm.showError('monitor_port', frm, 'max')"
402 i18n>The value cannot exceed 65535.</span>
403 <span class="invalid-feedback"
404 *ngIf="serviceForm.showError('monitor_port', frm, 'required')"
405 i18n>This field is required.</span>
408 <!-- virtual_interface_networks -->
409 <div class="form-group row">
410 <label class="cd-col-form-label"
411 for="virtual_interface_networks">
412 <span i18n>CIDR Networks</span>
414 <span i18n>A list of networks to identify which network interface to use for the virtual IP address.</span>
417 <div class="cd-col-form-input">
418 <input id="virtual_interface_networks"
421 formControlName="virtual_interface_networks">
426 <!-- SNMP-Gateway -->
427 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'snmp-gateway'">
428 <!-- snmp-version -->
429 <div class="form-group row">
430 <label class="cd-col-form-label required"
433 <div class="cd-col-form-input">
434 <select id="snmp_version"
436 class="form-control custom-select"
437 formControlName="snmp_version"
438 (change)="clearValidations()">
440 [ngValue]="null">-- Select SNMP version --</option>
441 <option *ngFor="let snmpVersion of ['V2c', 'V3']"
442 [value]="snmpVersion">{{ snmpVersion }}</option>
444 <span class="invalid-feedback"
445 *ngIf="serviceForm.showError('snmp_version', frm, 'required')"
446 i18n>This field is required.</span>
450 <div class="form-group row">
451 <label class="cd-col-form-label required"
452 [ngClass]="{'required': ['snmp-gateway'].includes(serviceForm.controls.service_type.value)}"
453 for="snmp_destination">
454 <span i18n>Destination</span>
456 <span i18n>Must be of the format hostname:port.</span>
459 <div class="cd-col-form-input">
460 <input id="snmp_destination"
463 formControlName="snmp_destination">
464 <span class="invalid-feedback"
465 *ngIf="serviceForm.showError('snmp_destination', frm, 'required')"
466 i18n>This field is required.</span>
467 <span class="invalid-feedback"
468 *ngIf="serviceForm.showError('snmp_destination', frm, 'snmpDestinationPattern')"
469 i18n>The value does not match the pattern: <strong>hostname:port</strong></span>
472 <!-- Engine id for snmp V3 -->
473 <div class="form-group row"
474 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
475 <label class="cd-col-form-label required"
476 [ngClass]="{'required': ['snmp-gateway'].includes(serviceForm.controls.service_type.value)}"
478 <span i18n>Engine Id</span>
480 <span i18n>Unique identifier for the device (in hex).</span>
483 <div class="cd-col-form-input">
484 <input id="engine_id"
487 formControlName="engine_id">
488 <span class="invalid-feedback"
489 *ngIf="serviceForm.showError('engine_id', frm, 'required')"
490 i18n>This field is required.</span>
493 <!-- Auth protocol for snmp V3 -->
494 <div class="form-group row"
495 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
496 <label class="cd-col-form-label required"
498 i18n>Auth Protocol</label>
499 <div class="cd-col-form-input">
500 <select id="auth_protocol"
502 class="form-control custom-select"
503 formControlName="auth_protocol">
505 [ngValue]="null">-- Select auth protocol --</option>
506 <option *ngFor="let authProtocol of ['SHA', 'MD5']"
507 [value]="authProtocol">
511 <span class="invalid-feedback"
512 *ngIf="serviceForm.showError('auth_protocol', frm, 'required')"
513 i18n>This field is required.</span>
516 <!-- Privacy protocol for snmp V3 -->
517 <div class="form-group row"
518 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
519 <label class="cd-col-form-label"
520 for="privacy_protocol"
521 i18n>Privacy Protocol</label>
522 <div class="cd-col-form-input">
523 <select id="privacy_protocol"
524 name="privacy_protocol"
525 class="form-control custom-select"
526 formControlName="privacy_protocol">
528 [ngValue]="null">-- Select privacy protocol --</option>
529 <option *ngFor="let privacyProtocol of ['DES', 'AES']"
530 [value]="privacyProtocol">
531 {{ privacyProtocol }}
538 <legend i18n>Credentials</legend>
539 <!-- snmp v2c snmp_community -->
540 <div class="form-group row"
541 *ngIf="serviceForm.controls.snmp_version.value === 'V2c'">
542 <label class="cd-col-form-label required"
543 [ngClass]="{'required': ['snmp-gateway'].includes(serviceForm.controls.service_type.value)}"
544 for="snmp_community">
545 <span i18n>SNMP Community</span>
547 <div class="cd-col-form-input">
548 <input id="snmp_community"
551 formControlName="snmp_community">
552 <span class="invalid-feedback"
553 *ngIf="serviceForm.showError('snmp_community', frm, 'required')"
554 i18n>This field is required.</span>
557 <!-- snmp v3 auth username -->
558 <div class="form-group row"
559 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
560 <label class="cd-col-form-label required"
561 [ngClass]="{'required': ['snmp-gateway'].includes(serviceForm.controls.service_type.value)}"
562 for="snmp_v3_auth_username">
563 <span i18n>Username</span>
565 <div class="cd-col-form-input">
566 <input id="snmp_v3_auth_username"
569 formControlName="snmp_v3_auth_username">
570 <span class="invalid-feedback"
571 *ngIf="serviceForm.showError('snmp_v3_auth_username', frm, 'required')"
572 i18n>This field is required.</span>
575 <!-- snmp v3 auth password -->
576 <div class="form-group row"
577 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
578 <label class="cd-col-form-label required"
579 [ngClass]="{'required': ['snmp-gateway'].includes(serviceForm.controls.service_type.value)}"
580 for="snmp_v3_auth_password">
581 <span i18n>Password</span>
583 <div class="cd-col-form-input">
584 <input id="snmp_v3_auth_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>
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 [ngClass]="{'required': ['snmp-gateway'].includes(serviceForm.controls.service_type.value)}"
598 for="snmp_v3_priv_password">
599 <span i18n>Encryption</span>
601 <div class="cd-col-form-input">
602 <input id="snmp_v3_priv_password"
605 formControlName="snmp_v3_priv_password">
606 <span class="invalid-feedback"
607 *ngIf="serviceForm.showError('snmp_v3_priv_password', frm, 'required')"
608 i18n>This field is required.</span>
613 <!-- RGW, Ingress & iSCSI -->
614 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && ['rgw', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)">
616 <div class="form-group row">
617 <div class="cd-col-form-offset">
618 <div class="custom-control custom-checkbox">
619 <input class="custom-control-input"
622 formControlName="ssl">
623 <label class="custom-control-label"
631 <div *ngIf="serviceForm.controls.ssl.value"
632 class="form-group row">
633 <label class="cd-col-form-label"
635 <span i18n>Certificate</span>
636 <cd-helper i18n>The SSL certificate in PEM format.</cd-helper>
638 <div class="cd-col-form-input">
639 <textarea id="ssl_cert"
640 class="form-control resize-vertical text-monospace text-pre"
641 formControlName="ssl_cert"
645 (change)="fileUpload($event.target.files, 'ssl_cert')">
646 <span class="invalid-feedback"
647 *ngIf="serviceForm.showError('ssl_cert', frm, 'required')"
648 i18n>This field is required.</span>
649 <span class="invalid-feedback"
650 *ngIf="serviceForm.showError('ssl_cert', frm, 'pattern')"
651 i18n>Invalid SSL certificate.</span>
656 <div *ngIf="serviceForm.controls.ssl.value && serviceForm.controls.service_type.value !== 'rgw'"
657 class="form-group row">
658 <label class="cd-col-form-label"
660 <span i18n>Private key</span>
661 <cd-helper i18n>The SSL private key in PEM format.</cd-helper>
663 <div class="cd-col-form-input">
664 <textarea id="ssl_key"
665 class="form-control resize-vertical text-monospace text-pre"
666 formControlName="ssl_key"
670 (change)="fileUpload($event.target.files,'ssl_key')">
671 <span class="invalid-feedback"
672 *ngIf="serviceForm.showError('ssl_key', frm, 'required')"
673 i18n>This field is required.</span>
674 <span class="invalid-feedback"
675 *ngIf="serviceForm.showError('ssl_key', frm, 'pattern')"
676 i18n>Invalid SSL private key.</span>
682 <div class="modal-footer">
683 <div class="text-right">
684 <cd-form-button-panel (submitActionEvent)="onSubmit()"
686 [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>