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>
211 <div class="form-group row"
212 *ngIf="serviceForm.controls.service_type.value === 'iscsi'">
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 <!-- fields in iSCSI which are hidden when unmanaged is true -->
240 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'iscsi'">
241 <!-- trusted_ip_list -->
242 <div class="form-group row">
243 <label class="cd-col-form-label"
244 for="trusted_ip_list">
245 <span i18n>Trusted IPs</span>
247 <span i18n>Comma separated list of IP addresses.</span>
249 <span i18n>Please add the <b>Ceph Manager</b> IP addresses here, otherwise the iSCSI gateways can't be reached.</span>
252 <div class="cd-col-form-input">
253 <input id="trusted_ip_list"
256 formControlName="trusted_ip_list">
261 <div class="form-group row">
263 class="cd-col-form-label"
264 for="api_port">Port</label>
265 <div class="cd-col-form-input">
269 formControlName="api_port"
272 <span class="invalid-feedback"
273 *ngIf="serviceForm.showError('api_port', frm, 'pattern')"
274 i18n>The entered value needs to be a number.</span>
275 <span class="invalid-feedback"
276 *ngIf="serviceForm.showError('api_port', frm, 'min')"
277 i18n>The value must be at least 1.</span>
278 <span class="invalid-feedback"
279 *ngIf="serviceForm.showError('api_port', frm, 'max')"
280 i18n>The value cannot exceed 65535.</span>
285 <div class="form-group row">
287 class="cd-col-form-label"
288 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
289 for="api_user">User</label>
290 <div class="cd-col-form-input">
294 formControlName="api_user">
295 <span class="invalid-feedback"
296 *ngIf="serviceForm.showError('api_user', frm, 'required')"
297 i18n>This field is required.</span>
301 <!-- api_password -->
302 <div class="form-group row">
304 class="cd-col-form-label"
305 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
306 for="api_password">Password</label>
307 <div class="cd-col-form-input">
308 <div class="input-group">
309 <input id="api_password"
312 autocomplete="new-password"
313 formControlName="api_password">
314 <span class="input-group-append">
315 <button type="button"
316 class="btn btn-light"
317 cdPasswordButton="api_password">
319 <cd-copy-2-clipboard-button source="api_password">
320 </cd-copy-2-clipboard-button>
322 <span class="invalid-feedback"
323 *ngIf="serviceForm.showError('api_password', frm, 'required')"
324 i18n>This field is required.</span>
331 <ng-container *ngIf="serviceForm.controls.service_type.value === 'ingress'">
333 <div class="form-group row">
334 <label class="cd-col-form-label"
335 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
337 <span i18n>Virtual IP</span>
339 <span i18n>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</span>
342 <div class="cd-col-form-input">
343 <input id="virtual_ip"
346 formControlName="virtual_ip">
347 <span class="invalid-feedback"
348 *ngIf="serviceForm.showError('virtual_ip', frm, 'required')"
349 i18n>This field is required.</span>
353 <!-- frontend_port -->
354 <div class="form-group row">
355 <label class="cd-col-form-label"
356 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
358 <span i18n>Frontend Port</span>
360 <span i18n>The port used to access the ingress service.</span>
363 <div class="cd-col-form-input">
364 <input id="frontend_port"
367 formControlName="frontend_port"
370 <span class="invalid-feedback"
371 *ngIf="serviceForm.showError('frontend_port', frm, 'pattern')"
372 i18n>The entered value needs to be a number.</span>
373 <span class="invalid-feedback"
374 *ngIf="serviceForm.showError('frontend_port', frm, 'min')"
375 i18n>The value must be at least 1.</span>
376 <span class="invalid-feedback"
377 *ngIf="serviceForm.showError('frontend_port', frm, 'max')"
378 i18n>The value cannot exceed 65535.</span>
379 <span class="invalid-feedback"
380 *ngIf="serviceForm.showError('frontend_port', frm, 'required')"
381 i18n>This field is required.</span>
385 <!-- monitor_port -->
386 <div class="form-group row">
387 <label class="cd-col-form-label"
388 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
390 <span i18n>Monitor Port</span>
392 <span i18n>The port used by haproxy for load balancer status.</span>
395 <div class="cd-col-form-input">
396 <input id="monitor_port"
399 formControlName="monitor_port"
402 <span class="invalid-feedback"
403 *ngIf="serviceForm.showError('monitor_port', frm, 'pattern')"
404 i18n>The entered value needs to be a number.</span>
405 <span class="invalid-feedback"
406 *ngIf="serviceForm.showError('monitor_port', frm, 'min')"
407 i18n>The value must be at least 1.</span>
408 <span class="invalid-feedback"
409 *ngIf="serviceForm.showError('monitor_port', frm, 'max')"
410 i18n>The value cannot exceed 65535.</span>
411 <span class="invalid-feedback"
412 *ngIf="serviceForm.showError('monitor_port', frm, 'required')"
413 i18n>This field is required.</span>
416 <!-- virtual_interface_networks -->
417 <div class="form-group row"
418 *ngIf="!serviceForm.controls.unmanaged.value">
419 <label class="cd-col-form-label"
420 for="virtual_interface_networks">
421 <span i18n>CIDR Networks</span>
423 <span i18n>A list of networks to identify which network interface to use for the virtual IP address.</span>
426 <div class="cd-col-form-input">
427 <input id="virtual_interface_networks"
430 formControlName="virtual_interface_networks">
435 <!-- SNMP-Gateway -->
436 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'snmp-gateway'">
437 <!-- snmp-version -->
438 <div class="form-group row">
439 <label class="cd-col-form-label required"
442 <div class="cd-col-form-input">
443 <select id="snmp_version"
446 formControlName="snmp_version"
447 (change)="clearValidations()">
449 [ngValue]="null">-- Select SNMP version --</option>
450 <option *ngFor="let snmpVersion of ['V2c', 'V3']"
451 [value]="snmpVersion">{{ snmpVersion }}</option>
453 <span class="invalid-feedback"
454 *ngIf="serviceForm.showError('snmp_version', frm, 'required')"
455 i18n>This field is required.</span>
459 <div class="form-group row">
460 <label class="cd-col-form-label required"
461 for="snmp_destination">
462 <span i18n>Destination</span>
464 <span i18n>Must be of the format hostname:port.</span>
467 <div class="cd-col-form-input">
468 <input id="snmp_destination"
471 formControlName="snmp_destination">
472 <span class="invalid-feedback"
473 *ngIf="serviceForm.showError('snmp_destination', frm, 'required')"
474 i18n>This field is required.</span>
475 <span class="invalid-feedback"
476 *ngIf="serviceForm.showError('snmp_destination', frm, 'snmpDestinationPattern')"
477 i18n>The value does not match the pattern: <strong>hostname:port</strong></span>
480 <!-- Engine id for snmp V3 -->
481 <div class="form-group row"
482 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
483 <label class="cd-col-form-label required"
485 <span i18n>Engine Id</span>
487 <span i18n>Unique identifier for the device (in hex).</span>
490 <div class="cd-col-form-input">
491 <input id="engine_id"
494 formControlName="engine_id">
495 <span class="invalid-feedback"
496 *ngIf="serviceForm.showError('engine_id', frm, 'required')"
497 i18n>This field is required.</span>
498 <span class="invalid-feedback"
499 *ngIf="serviceForm.showError('engine_id', frm, 'snmpEngineIdPattern')"
500 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>
503 <!-- Auth protocol for snmp V3 -->
504 <div class="form-group row"
505 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
506 <label class="cd-col-form-label required"
508 i18n>Auth Protocol</label>
509 <div class="cd-col-form-input">
510 <select id="auth_protocol"
513 formControlName="auth_protocol">
515 [ngValue]="null">-- Select auth protocol --</option>
516 <option *ngFor="let authProtocol of ['SHA', 'MD5']"
517 [value]="authProtocol">
521 <span class="invalid-feedback"
522 *ngIf="serviceForm.showError('auth_protocol', frm, 'required')"
523 i18n>This field is required.</span>
526 <!-- Privacy protocol for snmp V3 -->
527 <div class="form-group row"
528 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
529 <label class="cd-col-form-label"
530 for="privacy_protocol"
531 i18n>Privacy Protocol</label>
532 <div class="cd-col-form-input">
533 <select id="privacy_protocol"
534 name="privacy_protocol"
536 formControlName="privacy_protocol">
538 [ngValue]="null">-- Select privacy protocol --</option>
539 <option *ngFor="let privacyProtocol of ['DES', 'AES']"
540 [value]="privacyProtocol">
541 {{ privacyProtocol }}
548 <legend i18n>Credentials</legend>
549 <!-- snmp v2c snmp_community -->
550 <div class="form-group row"
551 *ngIf="serviceForm.controls.snmp_version.value === 'V2c'">
552 <label class="cd-col-form-label required"
553 for="snmp_community">
554 <span i18n>SNMP Community</span>
556 <div class="cd-col-form-input">
557 <input id="snmp_community"
560 formControlName="snmp_community">
561 <span class="invalid-feedback"
562 *ngIf="serviceForm.showError('snmp_community', frm, 'required')"
563 i18n>This field is required.</span>
566 <!-- snmp v3 auth username -->
567 <div class="form-group row"
568 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
569 <label class="cd-col-form-label required"
570 for="snmp_v3_auth_username">
571 <span i18n>Username</span>
573 <div class="cd-col-form-input">
574 <input id="snmp_v3_auth_username"
577 formControlName="snmp_v3_auth_username">
578 <span class="invalid-feedback"
579 *ngIf="serviceForm.showError('snmp_v3_auth_username', frm, 'required')"
580 i18n>This field is required.</span>
583 <!-- snmp v3 auth password -->
584 <div class="form-group row"
585 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
586 <label class="cd-col-form-label required"
587 for="snmp_v3_auth_password">
588 <span i18n>Password</span>
590 <div class="cd-col-form-input">
591 <input id="snmp_v3_auth_password"
594 formControlName="snmp_v3_auth_password">
595 <span class="invalid-feedback"
596 *ngIf="serviceForm.showError('snmp_v3_auth_password', frm, 'required')"
597 i18n>This field is required.</span>
600 <!-- snmp v3 priv password -->
601 <div class="form-group row"
602 *ngIf="serviceForm.controls.snmp_version.value === 'V3' && serviceForm.controls.privacy_protocol.value !== null && serviceForm.controls.privacy_protocol.value !== undefined">
603 <label class="cd-col-form-label required"
604 for="snmp_v3_priv_password">
605 <span i18n>Encryption</span>
607 <div class="cd-col-form-input">
608 <input id="snmp_v3_priv_password"
611 formControlName="snmp_v3_priv_password">
612 <span class="invalid-feedback"
613 *ngIf="serviceForm.showError('snmp_v3_priv_password', frm, 'required')"
614 i18n>This field is required.</span>
619 <!-- RGW, Ingress & iSCSI -->
620 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && ['rgw', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)">
622 <div class="form-group row">
623 <div class="cd-col-form-offset">
624 <div class="custom-control custom-checkbox">
625 <input class="custom-control-input"
628 formControlName="ssl">
629 <label class="custom-control-label"
637 <div *ngIf="serviceForm.controls.ssl.value"
638 class="form-group row">
639 <label class="cd-col-form-label"
641 <span i18n>Certificate</span>
642 <cd-helper i18n>The SSL certificate in PEM format.</cd-helper>
644 <div class="cd-col-form-input">
645 <textarea id="ssl_cert"
646 class="form-control resize-vertical text-monospace text-pre"
647 formControlName="ssl_cert"
651 (change)="fileUpload($event.target.files, 'ssl_cert')">
652 <span class="invalid-feedback"
653 *ngIf="serviceForm.showError('ssl_cert', frm, 'required')"
654 i18n>This field is required.</span>
655 <span class="invalid-feedback"
656 *ngIf="serviceForm.showError('ssl_cert', frm, 'pattern')"
657 i18n>Invalid SSL certificate.</span>
662 <div *ngIf="serviceForm.controls.ssl.value && !(['rgw', 'ingress'].includes(serviceForm.controls.service_type.value))"
663 class="form-group row">
664 <label class="cd-col-form-label"
666 <span i18n>Private key</span>
667 <cd-helper i18n>The SSL private key in PEM format.</cd-helper>
669 <div class="cd-col-form-input">
670 <textarea id="ssl_key"
671 class="form-control resize-vertical text-monospace text-pre"
672 formControlName="ssl_key"
676 (change)="fileUpload($event.target.files,'ssl_key')">
677 <span class="invalid-feedback"
678 *ngIf="serviceForm.showError('ssl_key', frm, 'required')"
679 i18n>This field is required.</span>
680 <span class="invalid-feedback"
681 *ngIf="serviceForm.showError('ssl_key', frm, 'pattern')"
682 i18n>Invalid SSL private key.</span>
688 <div class="modal-footer">
689 <div class="text-right">
690 <cd-form-button-panel (submitActionEvent)="onSubmit()"
692 [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>