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"
20 formControlName="service_type"
21 (change)="getServiceIds($event.target.value)">
23 [ngValue]="null">-- Select a service type --</option>
24 <option *ngFor="let serviceType of serviceTypes"
25 [value]="serviceType">
29 <span class="invalid-feedback"
30 *ngIf="serviceForm.showError('service_type', frm, 'required')"
31 i18n>This field is required.</span>
35 <!-- backend_service -->
36 <div *ngIf="serviceForm.controls.service_type.value === 'ingress'"
37 class="form-group row">
39 class="cd-col-form-label"
40 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
41 for="backend_service">Backend Service</label>
42 <div class="cd-col-form-input">
43 <select id="backend_service"
44 name="backend_service"
46 formControlName="backend_service"
47 (change)="prePopulateId()">
48 <option *ngIf="services === null"
50 i18n>Loading...</option>
51 <option *ngIf="services !== null && services.length === 0"
53 i18n>-- No service available --</option>
54 <option *ngIf="services !== null && services.length > 0"
56 i18n>-- Select an existing service --</option>
57 <option *ngFor="let service of services"
58 [value]="service.service_name">{{ service.service_name }}</option>
60 <span class="invalid-feedback"
61 *ngIf="serviceForm.showError('backend_service', frm, 'required')"
62 i18n>This field is required.</span>
67 <div class="form-group row"
68 *ngIf="serviceForm.controls.service_type.value !== 'snmp-gateway'">
70 class="cd-col-form-label"
71 [ngClass]="{'required': ['mds', 'rgw', 'nfs', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)}"
72 for="service_id">Id</label>
73 <div class="cd-col-form-input">
74 <input id="service_id"
77 formControlName="service_id">
78 <span class="invalid-feedback"
79 *ngIf="serviceForm.showError('service_id', frm, 'required')"
80 i18n>This field is required.</span>
81 <span class="invalid-feedback"
82 *ngIf="serviceForm.showError('service_id', frm, 'uniqueName')"
83 i18n>This service id is already in use.</span>
84 <span class="invalid-feedback"
85 *ngIf="serviceForm.showError('service_id', frm, 'rgwPattern')"
86 i18n>The value does not match the pattern <strong><service_id>[.<realm_name>.<zone_name>]</strong>.</span>
91 <div class="form-group row"
92 *ngIf="serviceForm.controls.service_type.value !== 'snmp-gateway'">
93 <div class="cd-col-form-offset">
94 <div class="custom-control custom-checkbox">
95 <input class="custom-control-input"
98 formControlName="unmanaged">
99 <label class="custom-control-label"
101 i18n>Unmanaged</label>
107 <div *ngIf="!serviceForm.controls.unmanaged.value"
108 class="form-group row">
109 <label class="cd-col-form-label"
111 i18n>Placement</label>
112 <div class="cd-col-form-input">
113 <select id="placement"
115 formControlName="placement">
117 value="hosts">Hosts</option>
119 value="label">Label</option>
125 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'label'"
126 class="form-group row">
128 class="cd-col-form-label"
129 for="label">Label</label>
130 <div class="cd-col-form-input">
134 formControlName="label"
135 [ngbTypeahead]="searchLabels"
136 (focus)="labelFocus.next($any($event).target.value)"
137 (click)="labelClick.next($any($event).target.value)">
138 <span class="invalid-feedback"
139 *ngIf="serviceForm.showError('label', frm, 'required')"
140 i18n>This field is required.</span>
145 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'hosts'"
146 class="form-group row">
147 <label class="cd-col-form-label"
150 <div class="cd-col-form-input">
151 <cd-select-badges id="hosts"
152 [data]="serviceForm.controls.hosts.value"
153 [options]="hosts.options"
154 [messages]="hosts.messages">
160 <div *ngIf="!serviceForm.controls.unmanaged.value"
161 class="form-group row">
162 <label class="cd-col-form-label"
164 <span i18n>Count</span>
165 <cd-helper i18n>Only that number of daemons will be created.</cd-helper>
167 <div class="cd-col-form-input">
171 formControlName="count"
173 <span class="invalid-feedback"
174 *ngIf="serviceForm.showError('count', frm, 'min')"
175 i18n>The value must be at least 1.</span>
176 <span class="invalid-feedback"
177 *ngIf="serviceForm.showError('count', frm, 'pattern')"
178 i18n>The entered value needs to be a number.</span>
183 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'rgw'">
184 <!-- rgw_frontend_port -->
185 <div class="form-group row">
187 class="cd-col-form-label"
188 for="rgw_frontend_port">Port</label>
189 <div class="cd-col-form-input">
190 <input id="rgw_frontend_port"
193 formControlName="rgw_frontend_port"
196 <span class="invalid-feedback"
197 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'pattern')"
198 i18n>The entered value needs to be a number.</span>
199 <span class="invalid-feedback"
200 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'min')"
201 i18n>The value must be at least 1.</span>
202 <span class="invalid-feedback"
203 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'max')"
204 i18n>The value cannot exceed 65535.</span>
210 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'iscsi'">
212 <div class="form-group row">
214 class="cd-col-form-label required"
215 for="pool">Pool</label>
216 <div class="cd-col-form-input">
220 formControlName="pool">
221 <option *ngIf="pools === null"
223 i18n>Loading...</option>
224 <option *ngIf="pools && pools.length === 0"
226 i18n>-- No pools available --</option>
227 <option *ngIf="pools && pools.length > 0"
229 i18n>-- Select a pool --</option>
230 <option *ngFor="let pool of pools"
231 [value]="pool.pool_name">{{ pool.pool_name }}</option>
233 <span class="invalid-feedback"
234 *ngIf="serviceForm.showError('pool', frm, 'required')"
235 i18n>This field is required.</span>
239 <!-- trusted_ip_list -->
240 <div class="form-group row">
241 <label class="cd-col-form-label"
242 for="trusted_ip_list">
243 <span i18n>Trusted IPs</span>
245 <span i18n>Comma separated list of IP addresses.</span>
247 <span i18n>Please add the <b>Ceph Manager</b> IP addresses here, otherwise the iSCSI gateways can't be reached.</span>
250 <div class="cd-col-form-input">
251 <input id="trusted_ip_list"
254 formControlName="trusted_ip_list">
259 <div class="form-group row">
261 class="cd-col-form-label"
262 for="api_port">Port</label>
263 <div class="cd-col-form-input">
267 formControlName="api_port"
270 <span class="invalid-feedback"
271 *ngIf="serviceForm.showError('api_port', frm, 'pattern')"
272 i18n>The entered value needs to be a number.</span>
273 <span class="invalid-feedback"
274 *ngIf="serviceForm.showError('api_port', frm, 'min')"
275 i18n>The value must be at least 1.</span>
276 <span class="invalid-feedback"
277 *ngIf="serviceForm.showError('api_port', frm, 'max')"
278 i18n>The value cannot exceed 65535.</span>
283 <div class="form-group row">
285 class="cd-col-form-label"
286 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
287 for="api_user">User</label>
288 <div class="cd-col-form-input">
292 formControlName="api_user">
293 <span class="invalid-feedback"
294 *ngIf="serviceForm.showError('api_user', frm, 'required')"
295 i18n>This field is required.</span>
299 <!-- api_password -->
300 <div class="form-group row">
302 class="cd-col-form-label"
303 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
304 for="api_password">Password</label>
305 <div class="cd-col-form-input">
306 <div class="input-group">
307 <input id="api_password"
310 autocomplete="new-password"
311 formControlName="api_password">
312 <span class="input-group-append">
313 <button type="button"
314 class="btn btn-light"
315 cdPasswordButton="api_password">
317 <cd-copy-2-clipboard-button source="api_password">
318 </cd-copy-2-clipboard-button>
320 <span class="invalid-feedback"
321 *ngIf="serviceForm.showError('api_password', frm, 'required')"
322 i18n>This field is required.</span>
329 <ng-container *ngIf="serviceForm.controls.service_type.value === 'ingress'">
331 <div class="form-group row">
332 <label class="cd-col-form-label"
333 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
335 <span i18n>Virtual IP</span>
337 <span i18n>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</span>
340 <div class="cd-col-form-input">
341 <input id="virtual_ip"
344 formControlName="virtual_ip">
345 <span class="invalid-feedback"
346 *ngIf="serviceForm.showError('virtual_ip', frm, 'required')"
347 i18n>This field is required.</span>
351 <!-- frontend_port -->
352 <div class="form-group row">
353 <label class="cd-col-form-label"
354 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
356 <span i18n>Frontend Port</span>
358 <span i18n>The port used to access the ingress service.</span>
361 <div class="cd-col-form-input">
362 <input id="frontend_port"
365 formControlName="frontend_port"
368 <span class="invalid-feedback"
369 *ngIf="serviceForm.showError('frontend_port', frm, 'pattern')"
370 i18n>The entered value needs to be a number.</span>
371 <span class="invalid-feedback"
372 *ngIf="serviceForm.showError('frontend_port', frm, 'min')"
373 i18n>The value must be at least 1.</span>
374 <span class="invalid-feedback"
375 *ngIf="serviceForm.showError('frontend_port', frm, 'max')"
376 i18n>The value cannot exceed 65535.</span>
377 <span class="invalid-feedback"
378 *ngIf="serviceForm.showError('frontend_port', frm, 'required')"
379 i18n>This field is required.</span>
383 <!-- monitor_port -->
384 <div class="form-group row">
385 <label class="cd-col-form-label"
386 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
388 <span i18n>Monitor Port</span>
390 <span i18n>The port used by haproxy for load balancer status.</span>
393 <div class="cd-col-form-input">
394 <input id="monitor_port"
397 formControlName="monitor_port"
400 <span class="invalid-feedback"
401 *ngIf="serviceForm.showError('monitor_port', frm, 'pattern')"
402 i18n>The entered value needs to be a number.</span>
403 <span class="invalid-feedback"
404 *ngIf="serviceForm.showError('monitor_port', frm, 'min')"
405 i18n>The value must be at least 1.</span>
406 <span class="invalid-feedback"
407 *ngIf="serviceForm.showError('monitor_port', frm, 'max')"
408 i18n>The value cannot exceed 65535.</span>
409 <span class="invalid-feedback"
410 *ngIf="serviceForm.showError('monitor_port', frm, 'required')"
411 i18n>This field is required.</span>
414 <!-- virtual_interface_networks -->
415 <div class="form-group row"
416 *ngIf="!serviceForm.controls.unmanaged.value">
417 <label class="cd-col-form-label"
418 for="virtual_interface_networks">
419 <span i18n>CIDR Networks</span>
421 <span i18n>A list of networks to identify which network interface to use for the virtual IP address.</span>
424 <div class="cd-col-form-input">
425 <input id="virtual_interface_networks"
428 formControlName="virtual_interface_networks">
433 <!-- SNMP-Gateway -->
434 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'snmp-gateway'">
435 <!-- snmp-version -->
436 <div class="form-group row">
437 <label class="cd-col-form-label required"
440 <div class="cd-col-form-input">
441 <select id="snmp_version"
444 formControlName="snmp_version"
445 (change)="clearValidations()">
447 [ngValue]="null">-- Select SNMP version --</option>
448 <option *ngFor="let snmpVersion of ['V2c', 'V3']"
449 [value]="snmpVersion">{{ snmpVersion }}</option>
451 <span class="invalid-feedback"
452 *ngIf="serviceForm.showError('snmp_version', frm, 'required')"
453 i18n>This field is required.</span>
457 <div class="form-group row">
458 <label class="cd-col-form-label required"
459 for="snmp_destination">
460 <span i18n>Destination</span>
462 <span i18n>Must be of the format hostname:port.</span>
465 <div class="cd-col-form-input">
466 <input id="snmp_destination"
469 formControlName="snmp_destination">
470 <span class="invalid-feedback"
471 *ngIf="serviceForm.showError('snmp_destination', frm, 'required')"
472 i18n>This field is required.</span>
473 <span class="invalid-feedback"
474 *ngIf="serviceForm.showError('snmp_destination', frm, 'snmpDestinationPattern')"
475 i18n>The value does not match the pattern: <strong>hostname:port</strong></span>
478 <!-- Engine id for snmp V3 -->
479 <div class="form-group row"
480 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
481 <label class="cd-col-form-label required"
483 <span i18n>Engine Id</span>
485 <span i18n>Unique identifier for the device (in hex).</span>
488 <div class="cd-col-form-input">
489 <input id="engine_id"
492 formControlName="engine_id">
493 <span class="invalid-feedback"
494 *ngIf="serviceForm.showError('engine_id', frm, 'required')"
495 i18n>This field is required.</span>
496 <span class="invalid-feedback"
497 *ngIf="serviceForm.showError('engine_id', frm, 'snmpEngineIdPattern')"
498 i18n>The value does not match the pattern: <strong>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.</strong></span>
501 <!-- Auth protocol for snmp V3 -->
502 <div class="form-group row"
503 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
504 <label class="cd-col-form-label required"
506 i18n>Auth Protocol</label>
507 <div class="cd-col-form-input">
508 <select id="auth_protocol"
511 formControlName="auth_protocol">
513 [ngValue]="null">-- Select auth protocol --</option>
514 <option *ngFor="let authProtocol of ['SHA', 'MD5']"
515 [value]="authProtocol">
519 <span class="invalid-feedback"
520 *ngIf="serviceForm.showError('auth_protocol', frm, 'required')"
521 i18n>This field is required.</span>
524 <!-- Privacy protocol for snmp V3 -->
525 <div class="form-group row"
526 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
527 <label class="cd-col-form-label"
528 for="privacy_protocol"
529 i18n>Privacy Protocol</label>
530 <div class="cd-col-form-input">
531 <select id="privacy_protocol"
532 name="privacy_protocol"
534 formControlName="privacy_protocol">
536 [ngValue]="null">-- Select privacy protocol --</option>
537 <option *ngFor="let privacyProtocol of ['DES', 'AES']"
538 [value]="privacyProtocol">
539 {{ privacyProtocol }}
546 <legend i18n>Credentials</legend>
547 <!-- snmp v2c snmp_community -->
548 <div class="form-group row"
549 *ngIf="serviceForm.controls.snmp_version.value === 'V2c'">
550 <label class="cd-col-form-label required"
551 for="snmp_community">
552 <span i18n>SNMP Community</span>
554 <div class="cd-col-form-input">
555 <input id="snmp_community"
558 formControlName="snmp_community">
559 <span class="invalid-feedback"
560 *ngIf="serviceForm.showError('snmp_community', frm, 'required')"
561 i18n>This field is required.</span>
564 <!-- snmp v3 auth username -->
565 <div class="form-group row"
566 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
567 <label class="cd-col-form-label required"
568 for="snmp_v3_auth_username">
569 <span i18n>Username</span>
571 <div class="cd-col-form-input">
572 <input id="snmp_v3_auth_username"
575 formControlName="snmp_v3_auth_username">
576 <span class="invalid-feedback"
577 *ngIf="serviceForm.showError('snmp_v3_auth_username', frm, 'required')"
578 i18n>This field is required.</span>
581 <!-- snmp v3 auth password -->
582 <div class="form-group row"
583 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
584 <label class="cd-col-form-label required"
585 for="snmp_v3_auth_password">
586 <span i18n>Password</span>
588 <div class="cd-col-form-input">
589 <input id="snmp_v3_auth_password"
592 formControlName="snmp_v3_auth_password">
593 <span class="invalid-feedback"
594 *ngIf="serviceForm.showError('snmp_v3_auth_password', frm, 'required')"
595 i18n>This field is required.</span>
598 <!-- snmp v3 priv password -->
599 <div class="form-group row"
600 *ngIf="serviceForm.controls.snmp_version.value === 'V3' && serviceForm.controls.privacy_protocol.value !== null && serviceForm.controls.privacy_protocol.value !== undefined">
601 <label class="cd-col-form-label required"
602 for="snmp_v3_priv_password">
603 <span i18n>Encryption</span>
605 <div class="cd-col-form-input">
606 <input id="snmp_v3_priv_password"
609 formControlName="snmp_v3_priv_password">
610 <span class="invalid-feedback"
611 *ngIf="serviceForm.showError('snmp_v3_priv_password', frm, 'required')"
612 i18n>This field is required.</span>
617 <!-- RGW, Ingress & iSCSI -->
618 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && ['rgw', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)">
620 <div class="form-group row">
621 <div class="cd-col-form-offset">
622 <div class="custom-control custom-checkbox">
623 <input class="custom-control-input"
626 formControlName="ssl">
627 <label class="custom-control-label"
635 <div *ngIf="serviceForm.controls.ssl.value"
636 class="form-group row">
637 <label class="cd-col-form-label"
639 <span i18n>Certificate</span>
640 <cd-helper i18n>The SSL certificate in PEM format.</cd-helper>
642 <div class="cd-col-form-input">
643 <textarea id="ssl_cert"
644 class="form-control resize-vertical text-monospace text-pre"
645 formControlName="ssl_cert"
649 (change)="fileUpload($event.target.files, 'ssl_cert')">
650 <span class="invalid-feedback"
651 *ngIf="serviceForm.showError('ssl_cert', frm, 'required')"
652 i18n>This field is required.</span>
653 <span class="invalid-feedback"
654 *ngIf="serviceForm.showError('ssl_cert', frm, 'pattern')"
655 i18n>Invalid SSL certificate.</span>
660 <div *ngIf="serviceForm.controls.ssl.value && !(['rgw', 'ingress'].includes(serviceForm.controls.service_type.value))"
661 class="form-group row">
662 <label class="cd-col-form-label"
664 <span i18n>Private key</span>
665 <cd-helper i18n>The SSL private key in PEM format.</cd-helper>
667 <div class="cd-col-form-input">
668 <textarea id="ssl_key"
669 class="form-control resize-vertical text-monospace text-pre"
670 formControlName="ssl_key"
674 (change)="fileUpload($event.target.files,'ssl_key')">
675 <span class="invalid-feedback"
676 *ngIf="serviceForm.showError('ssl_key', frm, 'required')"
677 i18n>This field is required.</span>
678 <span class="invalid-feedback"
679 *ngIf="serviceForm.showError('ssl_key', frm, 'pattern')"
680 i18n>Invalid SSL private key.</span>
686 <div class="modal-footer">
687 <div class="text-right">
688 <cd-form-button-panel (submitActionEvent)="onSubmit()"
690 [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>