1 <div class="cd-col-form">
3 [formGroup]="serviceForm"
6 <div i18n="form title|Example: Create Pool@@formTitle"
7 class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
9 <div class="card-body">
11 <div class="form-group row">
12 <label class="cd-col-form-label required"
15 <div class="cd-col-form-input">
16 <select id="service_type"
17 class="form-control custom-select"
18 formControlName="service_type">
20 [ngValue]="null">-- Select a service type --</option>
21 <option *ngFor="let serviceType of serviceTypes"
22 [value]="serviceType">
26 <span class="invalid-feedback"
27 *ngIf="serviceForm.showError('service_type', frm, 'required')"
28 i18n>This field is required.</span>
32 <!-- backend_service -->
33 <div *ngIf="serviceForm.controls.service_type.value === 'ingress'"
34 class="form-group row">
36 class="cd-col-form-label"
37 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
38 for="backend_service">Backend Service</label>
39 <div class="cd-col-form-input">
40 <select id="backend_service"
41 name="backend_service"
42 class="form-control custom-select"
43 formControlName="backend_service">
44 <option *ngIf="services === null"
46 i18n>Loading...</option>
47 <option *ngIf="services !== null && services.length === 0"
49 i18n>-- No service available --</option>
50 <option *ngIf="services !== null && services.length > 0"
52 i18n>-- Select an existing RGW service --</option>
53 <option *ngFor="let service of services"
54 [value]="service.service_name">{{ service.service_name }}</option>
56 <span class="invalid-feedback"
57 *ngIf="serviceForm.showError('backend_service', frm, 'required')"
58 i18n>This field is required.</span>
63 <div class="form-group row">
65 class="cd-col-form-label"
66 [ngClass]="{'required': ['mds', 'rgw', 'nfs', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)}"
67 for="service_id">Id</label>
68 <div class="cd-col-form-input">
69 <input id="service_id"
72 formControlName="service_id">
73 <span class="invalid-feedback"
74 *ngIf="serviceForm.showError('service_id', frm, 'required')"
75 i18n>This field is required.</span>
76 <span class="invalid-feedback"
77 *ngIf="serviceForm.showError('service_id', frm, 'rgwPattern')"
78 i18n>The value does not match the pattern <strong><realm_name>.<zone_name>[.<subcluster>]</strong>.</span>
83 <div class="form-group row">
84 <div class="cd-col-form-offset">
85 <div class="custom-control custom-checkbox">
86 <input class="custom-control-input"
89 formControlName="unmanaged">
90 <label class="custom-control-label"
92 i18n>Unmanaged</label>
98 <div *ngIf="!serviceForm.controls.unmanaged.value"
99 class="form-group row">
100 <label class="cd-col-form-label"
102 i18n>Placement</label>
103 <div class="cd-col-form-input">
104 <select id="placement"
105 class="form-control custom-select"
106 formControlName="placement">
108 value="hosts">Hosts</option>
110 value="label">Label</option>
116 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'label'"
117 class="form-group row">
119 class="cd-col-form-label"
120 for="label">Label</label>
121 <div class="cd-col-form-input">
125 formControlName="label"
126 [ngbTypeahead]="searchLabels"
127 (focus)="labelFocus.next($any($event).target.value)"
128 (click)="labelClick.next($any($event).target.value)">
129 <span class="invalid-feedback"
130 *ngIf="serviceForm.showError('label', frm, 'required')"
131 i18n>This field is required.</span>
136 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'hosts'"
137 class="form-group row">
138 <label class="cd-col-form-label"
141 <div class="cd-col-form-input">
142 <cd-select-badges id="hosts"
143 [data]="serviceForm.controls.hosts.value"
144 [options]="hosts.options"
145 [messages]="hosts.messages">
151 <div *ngIf="!serviceForm.controls.unmanaged.value"
152 class="form-group row">
153 <label class="cd-col-form-label"
155 <span i18n>Count</span>
156 <cd-helper i18n>Only that number of daemons will be created.</cd-helper>
158 <div class="cd-col-form-input">
162 formControlName="count"
164 <span class="invalid-feedback"
165 *ngIf="serviceForm.showError('count', frm, 'min')"
166 i18n>The value must be at least 1.</span>
167 <span class="invalid-feedback"
168 *ngIf="serviceForm.showError('count', frm, 'pattern')"
169 i18n>The entered value needs to be a number.</span>
174 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'nfs'">
176 <div class="form-group row">
178 class="cd-col-form-label required"
179 for="pool">Pool</label>
180 <div class="cd-col-form-input">
183 class="form-control custom-select"
184 formControlName="pool">
185 <option *ngIf="pools === null"
187 i18n>Loading...</option>
188 <option *ngIf="pools !== null && pools.length === 0"
190 i18n>-- No pools available --</option>
191 <option *ngIf="pools !== null && pools.length > 0"
193 i18n>-- Select a pool --</option>
194 <option *ngFor="let pool of pools"
195 [value]="pool.pool_name">{{ pool.pool_name }}</option>
197 <span class="invalid-feedback"
198 *ngIf="serviceForm.showError('pool', frm, 'required')"
199 i18n>This field is required.</span>
204 <div class="form-group row">
206 class="cd-col-form-label"
207 for="namespace">Namespace</label>
208 <div class="cd-col-form-input">
209 <input id="namespace"
212 formControlName="namespace">
218 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'rgw'">
219 <!-- rgw_frontend_port -->
220 <div class="form-group row">
222 class="cd-col-form-label"
223 for="rgw_frontend_port">Port</label>
224 <div class="cd-col-form-input">
225 <input id="rgw_frontend_port"
228 formControlName="rgw_frontend_port"
231 <span class="invalid-feedback"
232 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'pattern')"
233 i18n>The entered value needs to be a number.</span>
234 <span class="invalid-feedback"
235 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'min')"
236 i18n>The value must be at least 1.</span>
237 <span class="invalid-feedback"
238 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'max')"
239 i18n>The value cannot exceed 65535.</span>
245 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'iscsi'">
247 <div class="form-group row">
249 class="cd-col-form-label required"
250 for="pool">Pool</label>
251 <div class="cd-col-form-input">
254 class="form-control custom-select"
255 formControlName="pool">
256 <option *ngIf="pools === null"
258 i18n>Loading...</option>
259 <option *ngIf="pools !== null && pools.length === 0"
261 i18n>-- No pools available --</option>
262 <option *ngIf="pools !== null && pools.length > 0"
264 i18n>-- Select a pool --</option>
265 <option *ngFor="let pool of pools"
266 [value]="pool.pool_name">{{ pool.pool_name }}</option>
268 <span class="invalid-feedback"
269 *ngIf="serviceForm.showError('pool', frm, 'required')"
270 i18n>This field is required.</span>
274 <!-- trusted_ip_list -->
275 <div class="form-group row">
276 <label class="cd-col-form-label"
277 for="trusted_ip_list">
278 <span i18n>Trusted IPs</span>
280 <span i18n>Comma separated list of IP addresses.</span>
282 <span i18n>Please add the <b>Ceph Manager</b> IP addresses here, otherwise the iSCSI gateways can't be reached.</span>
285 <div class="cd-col-form-input">
286 <input id="trusted_ip_list"
289 formControlName="trusted_ip_list">
294 <div class="form-group row">
296 class="cd-col-form-label"
297 for="api_port">Port</label>
298 <div class="cd-col-form-input">
302 formControlName="api_port"
305 <span class="invalid-feedback"
306 *ngIf="serviceForm.showError('api_port', frm, 'pattern')"
307 i18n>The entered value needs to be a number.</span>
308 <span class="invalid-feedback"
309 *ngIf="serviceForm.showError('api_port', frm, 'min')"
310 i18n>The value must be at least 1.</span>
311 <span class="invalid-feedback"
312 *ngIf="serviceForm.showError('api_port', frm, 'max')"
313 i18n>The value cannot exceed 65535.</span>
318 <div class="form-group row">
320 class="cd-col-form-label"
321 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
322 for="api_user">User</label>
323 <div class="cd-col-form-input">
327 formControlName="api_user">
328 <span class="invalid-feedback"
329 *ngIf="serviceForm.showError('api_user', frm, 'required')"
330 i18n>This field is required.</span>
334 <!-- api_password -->
335 <div class="form-group row">
337 class="cd-col-form-label"
338 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
339 for="api_password">Password</label>
340 <div class="cd-col-form-input">
341 <div class="input-group">
342 <input id="api_password"
345 autocomplete="new-password"
346 formControlName="api_password">
347 <span class="input-group-append">
348 <button type="button"
349 class="btn btn-light"
350 cdPasswordButton="api_password">
352 <cd-copy-2-clipboard-button source="api_password">
353 </cd-copy-2-clipboard-button>
355 <span class="invalid-feedback"
356 *ngIf="serviceForm.showError('api_password', frm, 'required')"
357 i18n>This field is required.</span>
364 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'ingress'">
366 <div class="form-group row">
367 <label class="cd-col-form-label"
368 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
370 <span i18n>Virtual IP</span>
372 <span i18n>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</span>
375 <div class="cd-col-form-input">
376 <input id="virtual_ip"
379 formControlName="virtual_ip">
380 <span class="invalid-feedback"
381 *ngIf="serviceForm.showError('virtual_ip', frm, 'required')"
382 i18n>This field is required.</span>
386 <!-- frontend_port -->
387 <div class="form-group row">
388 <label class="cd-col-form-label"
389 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
391 <span i18n>Frontend Port</span>
393 <span i18n>The port used to access the ingress service.</span>
396 <div class="cd-col-form-input">
397 <input id="frontend_port"
400 formControlName="frontend_port"
403 <span class="invalid-feedback"
404 *ngIf="serviceForm.showError('frontend_port', frm, 'pattern')"
405 i18n>The entered value needs to be a number.</span>
406 <span class="invalid-feedback"
407 *ngIf="serviceForm.showError('frontend_port', frm, 'min')"
408 i18n>The value must be at least 1.</span>
409 <span class="invalid-feedback"
410 *ngIf="serviceForm.showError('frontend_port', frm, 'max')"
411 i18n>The value cannot exceed 65535.</span>
412 <span class="invalid-feedback"
413 *ngIf="serviceForm.showError('frontend_port', frm, 'required')"
414 i18n>This field is required.</span>
418 <!-- monitor_port -->
419 <div class="form-group row">
420 <label class="cd-col-form-label"
421 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
423 <span i18n>Monitor Port</span>
425 <span i18n>The port used by haproxy for load balancer status.</span>
428 <div class="cd-col-form-input">
429 <input id="monitor_port"
432 formControlName="monitor_port"
435 <span class="invalid-feedback"
436 *ngIf="serviceForm.showError('monitor_port', frm, 'pattern')"
437 i18n>The entered value needs to be a number.</span>
438 <span class="invalid-feedback"
439 *ngIf="serviceForm.showError('monitor_port', frm, 'min')"
440 i18n>The value must be at least 1.</span>
441 <span class="invalid-feedback"
442 *ngIf="serviceForm.showError('monitor_port', frm, 'max')"
443 i18n>The value cannot exceed 65535.</span>
444 <span class="invalid-feedback"
445 *ngIf="serviceForm.showError('monitor_port', frm, 'required')"
446 i18n>This field is required.</span>
449 <!-- virtual_interface_networks -->
450 <div class="form-group row">
451 <label class="cd-col-form-label"
452 for="virtual_interface_networks">
453 <span i18n>CIDR Networks</span>
455 <span i18n>A list of networks to identify which network interface to use for the virtual IP address.</span>
458 <div class="cd-col-form-input">
459 <input id="virtual_interface_networks"
462 formControlName="virtual_interface_networks">
466 <!-- RGW, Ingress & iSCSI -->
467 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && ['rgw', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)">
469 <div class="form-group row">
470 <div class="cd-col-form-offset">
471 <div class="custom-control custom-checkbox">
472 <input class="custom-control-input"
475 formControlName="ssl">
476 <label class="custom-control-label"
484 <div *ngIf="serviceForm.controls.ssl.value"
485 class="form-group row">
486 <label class="cd-col-form-label"
488 <span i18n>Certificate</span>
489 <cd-helper i18n>The SSL certificate in PEM format.</cd-helper>
491 <div class="cd-col-form-input">
492 <textarea id="ssl_cert"
493 class="form-control resize-vertical text-monospace text-pre"
494 formControlName="ssl_cert"
498 (change)="fileUpload($event.target.files, 'ssl_cert')">
499 <span class="invalid-feedback"
500 *ngIf="serviceForm.showError('ssl_cert', frm, 'required')"
501 i18n>This field is required.</span>
502 <span class="invalid-feedback"
503 *ngIf="serviceForm.showError('ssl_cert', frm, 'pattern')"
504 i18n>Invalid SSL certificate.</span>
509 <div *ngIf="serviceForm.controls.ssl.value"
510 class="form-group row">
511 <label class="cd-col-form-label"
513 <span i18n>Private key</span>
514 <cd-helper i18n>The SSL private key in PEM format.</cd-helper>
516 <div class="cd-col-form-input">
517 <textarea id="ssl_key"
518 class="form-control resize-vertical text-monospace text-pre"
519 formControlName="ssl_key"
523 (change)="fileUpload($event.target.files,'ssl_key')">
524 <span class="invalid-feedback"
525 *ngIf="serviceForm.showError('ssl_key', frm, 'required')"
526 i18n>This field is required.</span>
527 <span class="invalid-feedback"
528 *ngIf="serviceForm.showError('ssl_key', frm, 'pattern')"
529 i18n>Invalid SSL private key.</span>
535 <div class="card-footer">
536 <div class="text-right">
537 <cd-form-button-panel (submitActionEvent)="onSubmit()"
539 [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>