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"
67 *ngIf="serviceForm.controls.service_type.value !== 'snmp-gateway'">
69 class="cd-col-form-label"
70 [ngClass]="{'required': ['mds', 'rgw', 'nfs', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)}"
71 for="service_id">Id</label>
72 <div class="cd-col-form-input">
73 <input id="service_id"
76 formControlName="service_id">
77 <span class="invalid-feedback"
78 *ngIf="serviceForm.showError('service_id', frm, 'required')"
79 i18n>This field is required.</span>
80 <span class="invalid-feedback"
81 *ngIf="serviceForm.showError('service_id', frm, 'rgwPattern')"
82 i18n>The value does not match the pattern <strong><service_id>[.<realm_name>.<zone_name>]</strong>.</span>
87 <div class="form-group row">
88 <div class="cd-col-form-offset">
89 <div class="custom-control custom-checkbox">
90 <input class="custom-control-input"
93 formControlName="unmanaged">
94 <label class="custom-control-label"
96 i18n>Unmanaged</label>
102 <div *ngIf="!serviceForm.controls.unmanaged.value"
103 class="form-group row">
104 <label class="cd-col-form-label"
106 i18n>Placement</label>
107 <div class="cd-col-form-input">
108 <select id="placement"
109 class="form-control custom-select"
110 formControlName="placement">
112 value="hosts">Hosts</option>
114 value="label">Label</option>
120 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'label'"
121 class="form-group row">
123 class="cd-col-form-label"
124 for="label">Label</label>
125 <div class="cd-col-form-input">
129 formControlName="label"
130 [ngbTypeahead]="searchLabels"
131 (focus)="labelFocus.next($any($event).target.value)"
132 (click)="labelClick.next($any($event).target.value)">
133 <span class="invalid-feedback"
134 *ngIf="serviceForm.showError('label', frm, 'required')"
135 i18n>This field is required.</span>
140 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'hosts'"
141 class="form-group row">
142 <label class="cd-col-form-label"
145 <div class="cd-col-form-input">
146 <cd-select-badges id="hosts"
147 [data]="serviceForm.controls.hosts.value"
148 [options]="hosts.options"
149 [messages]="hosts.messages">
155 <div *ngIf="!serviceForm.controls.unmanaged.value"
156 class="form-group row">
157 <label class="cd-col-form-label"
159 <span i18n>Count</span>
160 <cd-helper i18n>Only that number of daemons will be created.</cd-helper>
162 <div class="cd-col-form-input">
166 formControlName="count"
168 <span class="invalid-feedback"
169 *ngIf="serviceForm.showError('count', frm, 'min')"
170 i18n>The value must be at least 1.</span>
171 <span class="invalid-feedback"
172 *ngIf="serviceForm.showError('count', frm, 'pattern')"
173 i18n>The entered value needs to be a number.</span>
178 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'rgw'">
179 <!-- rgw_frontend_port -->
180 <div class="form-group row">
182 class="cd-col-form-label"
183 for="rgw_frontend_port">Port</label>
184 <div class="cd-col-form-input">
185 <input id="rgw_frontend_port"
188 formControlName="rgw_frontend_port"
191 <span class="invalid-feedback"
192 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'pattern')"
193 i18n>The entered value needs to be a number.</span>
194 <span class="invalid-feedback"
195 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'min')"
196 i18n>The value must be at least 1.</span>
197 <span class="invalid-feedback"
198 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'max')"
199 i18n>The value cannot exceed 65535.</span>
205 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'iscsi'">
207 <div class="form-group row">
209 class="cd-col-form-label required"
210 for="pool">Pool</label>
211 <div class="cd-col-form-input">
214 class="form-control custom-select"
215 formControlName="pool">
216 <option *ngIf="pools === null"
218 i18n>Loading...</option>
219 <option *ngIf="pools && pools.length === 0"
221 i18n>-- No pools available --</option>
222 <option *ngIf="pools && pools.length > 0"
224 i18n>-- Select a pool --</option>
225 <option *ngFor="let pool of pools"
226 [value]="pool.pool_name">{{ pool.pool_name }}</option>
228 <span class="invalid-feedback"
229 *ngIf="serviceForm.showError('pool', frm, 'required')"
230 i18n>This field is required.</span>
234 <!-- trusted_ip_list -->
235 <div class="form-group row">
236 <label class="cd-col-form-label"
237 for="trusted_ip_list">
238 <span i18n>Trusted IPs</span>
240 <span i18n>Comma separated list of IP addresses.</span>
242 <span i18n>Please add the <b>Ceph Manager</b> IP addresses here, otherwise the iSCSI gateways can't be reached.</span>
245 <div class="cd-col-form-input">
246 <input id="trusted_ip_list"
249 formControlName="trusted_ip_list">
254 <div class="form-group row">
256 class="cd-col-form-label"
257 for="api_port">Port</label>
258 <div class="cd-col-form-input">
262 formControlName="api_port"
265 <span class="invalid-feedback"
266 *ngIf="serviceForm.showError('api_port', frm, 'pattern')"
267 i18n>The entered value needs to be a number.</span>
268 <span class="invalid-feedback"
269 *ngIf="serviceForm.showError('api_port', frm, 'min')"
270 i18n>The value must be at least 1.</span>
271 <span class="invalid-feedback"
272 *ngIf="serviceForm.showError('api_port', frm, 'max')"
273 i18n>The value cannot exceed 65535.</span>
278 <div class="form-group row">
280 class="cd-col-form-label"
281 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
282 for="api_user">User</label>
283 <div class="cd-col-form-input">
287 formControlName="api_user">
288 <span class="invalid-feedback"
289 *ngIf="serviceForm.showError('api_user', frm, 'required')"
290 i18n>This field is required.</span>
294 <!-- api_password -->
295 <div class="form-group row">
297 class="cd-col-form-label"
298 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
299 for="api_password">Password</label>
300 <div class="cd-col-form-input">
301 <div class="input-group">
302 <input id="api_password"
305 autocomplete="new-password"
306 formControlName="api_password">
307 <span class="input-group-append">
308 <button type="button"
309 class="btn btn-light"
310 cdPasswordButton="api_password">
312 <cd-copy-2-clipboard-button source="api_password">
313 </cd-copy-2-clipboard-button>
315 <span class="invalid-feedback"
316 *ngIf="serviceForm.showError('api_password', frm, 'required')"
317 i18n>This field is required.</span>
324 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'ingress'">
326 <div class="form-group row">
327 <label class="cd-col-form-label"
328 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
330 <span i18n>Virtual IP</span>
332 <span i18n>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</span>
335 <div class="cd-col-form-input">
336 <input id="virtual_ip"
339 formControlName="virtual_ip">
340 <span class="invalid-feedback"
341 *ngIf="serviceForm.showError('virtual_ip', frm, 'required')"
342 i18n>This field is required.</span>
346 <!-- frontend_port -->
347 <div class="form-group row">
348 <label class="cd-col-form-label"
349 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
351 <span i18n>Frontend Port</span>
353 <span i18n>The port used to access the ingress service.</span>
356 <div class="cd-col-form-input">
357 <input id="frontend_port"
360 formControlName="frontend_port"
363 <span class="invalid-feedback"
364 *ngIf="serviceForm.showError('frontend_port', frm, 'pattern')"
365 i18n>The entered value needs to be a number.</span>
366 <span class="invalid-feedback"
367 *ngIf="serviceForm.showError('frontend_port', frm, 'min')"
368 i18n>The value must be at least 1.</span>
369 <span class="invalid-feedback"
370 *ngIf="serviceForm.showError('frontend_port', frm, 'max')"
371 i18n>The value cannot exceed 65535.</span>
372 <span class="invalid-feedback"
373 *ngIf="serviceForm.showError('frontend_port', frm, 'required')"
374 i18n>This field is required.</span>
378 <!-- monitor_port -->
379 <div class="form-group row">
380 <label class="cd-col-form-label"
381 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
383 <span i18n>Monitor Port</span>
385 <span i18n>The port used by haproxy for load balancer status.</span>
388 <div class="cd-col-form-input">
389 <input id="monitor_port"
392 formControlName="monitor_port"
395 <span class="invalid-feedback"
396 *ngIf="serviceForm.showError('monitor_port', frm, 'pattern')"
397 i18n>The entered value needs to be a number.</span>
398 <span class="invalid-feedback"
399 *ngIf="serviceForm.showError('monitor_port', frm, 'min')"
400 i18n>The value must be at least 1.</span>
401 <span class="invalid-feedback"
402 *ngIf="serviceForm.showError('monitor_port', frm, 'max')"
403 i18n>The value cannot exceed 65535.</span>
404 <span class="invalid-feedback"
405 *ngIf="serviceForm.showError('monitor_port', frm, 'required')"
406 i18n>This field is required.</span>
409 <!-- virtual_interface_networks -->
410 <div class="form-group row">
411 <label class="cd-col-form-label"
412 for="virtual_interface_networks">
413 <span i18n>CIDR Networks</span>
415 <span i18n>A list of networks to identify which network interface to use for the virtual IP address.</span>
418 <div class="cd-col-form-input">
419 <input id="virtual_interface_networks"
422 formControlName="virtual_interface_networks">
427 <!-- SNMP-Gateway -->
428 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'snmp-gateway'">
429 <!-- snmp-version -->
430 <div class="form-group row">
431 <label class="cd-col-form-label required"
434 <div class="cd-col-form-input">
435 <select id="snmp_version"
437 class="form-control custom-select"
438 formControlName="snmp_version"
439 (change)="clearValidations()">
441 [ngValue]="null">-- Select SNMP version --</option>
442 <option *ngFor="let snmpVersion of ['V2c', 'V3']"
443 [value]="snmpVersion">{{ snmpVersion }}</option>
445 <span class="invalid-feedback"
446 *ngIf="serviceForm.showError('snmp_version', frm, 'required')"
447 i18n>This field is required.</span>
451 <div class="form-group row">
452 <label class="cd-col-form-label required"
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"
477 <span i18n>Engine Id</span>
479 <span i18n>Unique identifier for the device (in hex).</span>
482 <div class="cd-col-form-input">
483 <input id="engine_id"
486 formControlName="engine_id">
487 <span class="invalid-feedback"
488 *ngIf="serviceForm.showError('engine_id', frm, 'required')"
489 i18n>This field is required.</span>
492 <!-- Auth protocol for snmp V3 -->
493 <div class="form-group row"
494 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
495 <label class="cd-col-form-label required"
497 i18n>Auth Protocol</label>
498 <div class="cd-col-form-input">
499 <select id="auth_protocol"
501 class="form-control custom-select"
502 formControlName="auth_protocol">
504 [ngValue]="null">-- Select auth protocol --</option>
505 <option *ngFor="let authProtocol of ['SHA', 'MD5']"
506 [value]="authProtocol">
510 <span class="invalid-feedback"
511 *ngIf="serviceForm.showError('auth_protocol', frm, 'required')"
512 i18n>This field is required.</span>
515 <!-- Privacy protocol for snmp V3 -->
516 <div class="form-group row"
517 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
518 <label class="cd-col-form-label"
519 for="privacy_protocol"
520 i18n>Privacy Protocol</label>
521 <div class="cd-col-form-input">
522 <select id="privacy_protocol"
523 name="privacy_protocol"
524 class="form-control custom-select"
525 formControlName="privacy_protocol">
527 [ngValue]="null">-- Select privacy protocol --</option>
528 <option *ngFor="let privacyProtocol of ['DES', 'AES']"
529 [value]="privacyProtocol">
530 {{ privacyProtocol }}
537 <legend i18n>Credentials</legend>
538 <!-- snmp v2c snmp_community -->
539 <div class="form-group row"
540 *ngIf="serviceForm.controls.snmp_version.value === 'V2c'">
541 <label class="cd-col-form-label required"
542 for="snmp_community">
543 <span i18n>SNMP Community</span>
545 <div class="cd-col-form-input">
546 <input id="snmp_community"
549 formControlName="snmp_community">
550 <span class="invalid-feedback"
551 *ngIf="serviceForm.showError('snmp_community', frm, 'required')"
552 i18n>This field is required.</span>
555 <!-- snmp v3 auth username -->
556 <div class="form-group row"
557 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
558 <label class="cd-col-form-label required"
559 for="snmp_v3_auth_username">
560 <span i18n>Username</span>
562 <div class="cd-col-form-input">
563 <input id="snmp_v3_auth_username"
566 formControlName="snmp_v3_auth_username">
567 <span class="invalid-feedback"
568 *ngIf="serviceForm.showError('snmp_v3_auth_username', frm, 'required')"
569 i18n>This field is required.</span>
572 <!-- snmp v3 auth password -->
573 <div class="form-group row"
574 *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
575 <label class="cd-col-form-label required"
576 for="snmp_v3_auth_password">
577 <span i18n>Password</span>
579 <div class="cd-col-form-input">
580 <input id="snmp_v3_auth_password"
583 formControlName="snmp_v3_auth_password">
584 <span class="invalid-feedback"
585 *ngIf="serviceForm.showError('snmp_v3_auth_password', frm, 'required')"
586 i18n>This field is required.</span>
589 <!-- snmp v3 priv password -->
590 <div class="form-group row"
591 *ngIf="serviceForm.controls.snmp_version.value === 'V3' && serviceForm.controls.privacy_protocol.value !== null && serviceForm.controls.privacy_protocol.value !== undefined">
592 <label class="cd-col-form-label required"
593 for="snmp_v3_priv_password">
594 <span i18n>Encryption</span>
596 <div class="cd-col-form-input">
597 <input id="snmp_v3_priv_password"
600 formControlName="snmp_v3_priv_password">
601 <span class="invalid-feedback"
602 *ngIf="serviceForm.showError('snmp_v3_priv_password', frm, 'required')"
603 i18n>This field is required.</span>
608 <!-- RGW, Ingress & iSCSI -->
609 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && ['rgw', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)">
611 <div class="form-group row">
612 <div class="cd-col-form-offset">
613 <div class="custom-control custom-checkbox">
614 <input class="custom-control-input"
617 formControlName="ssl">
618 <label class="custom-control-label"
626 <div *ngIf="serviceForm.controls.ssl.value"
627 class="form-group row">
628 <label class="cd-col-form-label"
630 <span i18n>Certificate</span>
631 <cd-helper i18n>The SSL certificate in PEM format.</cd-helper>
633 <div class="cd-col-form-input">
634 <textarea id="ssl_cert"
635 class="form-control resize-vertical text-monospace text-pre"
636 formControlName="ssl_cert"
640 (change)="fileUpload($event.target.files, 'ssl_cert')">
641 <span class="invalid-feedback"
642 *ngIf="serviceForm.showError('ssl_cert', frm, 'required')"
643 i18n>This field is required.</span>
644 <span class="invalid-feedback"
645 *ngIf="serviceForm.showError('ssl_cert', frm, 'pattern')"
646 i18n>Invalid SSL certificate.</span>
651 <div *ngIf="serviceForm.controls.ssl.value && serviceForm.controls.service_type.value !== 'rgw'"
652 class="form-group row">
653 <label class="cd-col-form-label"
655 <span i18n>Private key</span>
656 <cd-helper i18n>The SSL private key in PEM format.</cd-helper>
658 <div class="cd-col-form-input">
659 <textarea id="ssl_key"
660 class="form-control resize-vertical text-monospace text-pre"
661 formControlName="ssl_key"
665 (change)="fileUpload($event.target.files,'ssl_key')">
666 <span class="invalid-feedback"
667 *ngIf="serviceForm.showError('ssl_key', frm, 'required')"
668 i18n>This field is required.</span>
669 <span class="invalid-feedback"
670 *ngIf="serviceForm.showError('ssl_key', frm, 'pattern')"
671 i18n>Invalid SSL private key.</span>
677 <div class="modal-footer">
678 <div class="text-right">
679 <cd-form-button-panel (submitActionEvent)="onSubmit()"
681 [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>