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"
18 class="form-control custom-select"
19 formControlName="service_type">
21 [ngValue]="null">-- Select a service type --</option>
22 <option *ngFor="let serviceType of serviceTypes"
23 [value]="serviceType">
27 <span class="invalid-feedback"
28 *ngIf="serviceForm.showError('service_type', frm, 'required')"
29 i18n>This field is required.</span>
33 <!-- backend_service -->
34 <div *ngIf="serviceForm.controls.service_type.value === 'ingress'"
35 class="form-group row">
37 class="cd-col-form-label"
38 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
39 for="backend_service">Backend Service</label>
40 <div class="cd-col-form-input">
41 <select id="backend_service"
42 name="backend_service"
43 class="form-control custom-select"
44 formControlName="backend_service">
45 <option *ngIf="services === null"
47 i18n>Loading...</option>
48 <option *ngIf="services !== null && services.length === 0"
50 i18n>-- No service available --</option>
51 <option *ngIf="services !== null && services.length > 0"
53 i18n>-- Select an existing RGW service --</option>
54 <option *ngFor="let service of services"
55 [value]="service.service_name">{{ service.service_name }}</option>
57 <span class="invalid-feedback"
58 *ngIf="serviceForm.showError('backend_service', frm, 'required')"
59 i18n>This field is required.</span>
64 <div class="form-group row">
66 class="cd-col-form-label"
67 [ngClass]="{'required': ['mds', 'rgw', 'nfs', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)}"
68 for="service_id">Id</label>
69 <div class="cd-col-form-input">
70 <input id="service_id"
73 formControlName="service_id">
74 <span class="invalid-feedback"
75 *ngIf="serviceForm.showError('service_id', frm, 'required')"
76 i18n>This field is required.</span>
77 <span class="invalid-feedback"
78 *ngIf="serviceForm.showError('service_id', frm, 'rgwPattern')"
79 i18n>The value does not match the pattern <strong><realm_name>.<zone_name>[.<subcluster>]</strong>.</span>
84 <div class="form-group row">
85 <div class="cd-col-form-offset">
86 <div class="custom-control custom-checkbox">
87 <input class="custom-control-input"
90 formControlName="unmanaged">
91 <label class="custom-control-label"
93 i18n>Unmanaged</label>
99 <div *ngIf="!serviceForm.controls.unmanaged.value"
100 class="form-group row">
101 <label class="cd-col-form-label"
103 i18n>Placement</label>
104 <div class="cd-col-form-input">
105 <select id="placement"
106 class="form-control custom-select"
107 formControlName="placement">
109 value="hosts">Hosts</option>
111 value="label">Label</option>
117 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'label'"
118 class="form-group row">
120 class="cd-col-form-label"
121 for="label">Label</label>
122 <div class="cd-col-form-input">
126 formControlName="label"
127 [ngbTypeahead]="searchLabels"
128 (focus)="labelFocus.next($any($event).target.value)"
129 (click)="labelClick.next($any($event).target.value)">
130 <span class="invalid-feedback"
131 *ngIf="serviceForm.showError('label', frm, 'required')"
132 i18n>This field is required.</span>
137 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'hosts'"
138 class="form-group row">
139 <label class="cd-col-form-label"
142 <div class="cd-col-form-input">
143 <cd-select-badges id="hosts"
144 [data]="serviceForm.controls.hosts.value"
145 [options]="hosts.options"
146 [messages]="hosts.messages">
152 <div *ngIf="!serviceForm.controls.unmanaged.value"
153 class="form-group row">
154 <label class="cd-col-form-label"
156 <span i18n>Count</span>
157 <cd-helper i18n>Only that number of daemons will be created.</cd-helper>
159 <div class="cd-col-form-input">
163 formControlName="count"
165 <span class="invalid-feedback"
166 *ngIf="serviceForm.showError('count', frm, 'min')"
167 i18n>The value must be at least 1.</span>
168 <span class="invalid-feedback"
169 *ngIf="serviceForm.showError('count', frm, 'pattern')"
170 i18n>The entered value needs to be a number.</span>
175 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'nfs'">
177 <div class="form-group row">
179 class="cd-col-form-label required"
180 for="pool">Pool</label>
181 <div class="cd-col-form-input">
184 class="form-control custom-select"
185 formControlName="pool">
186 <option *ngIf="pools === null"
188 i18n>Loading...</option>
189 <option *ngIf="pools !== null && pools.length === 0"
191 i18n>-- No pools available --</option>
192 <option *ngIf="pools !== null && pools.length > 0"
194 i18n>-- Select a pool --</option>
195 <option *ngFor="let pool of pools"
196 [value]="pool.pool_name">{{ pool.pool_name }}</option>
198 <span class="invalid-feedback"
199 *ngIf="serviceForm.showError('pool', frm, 'required')"
200 i18n>This field is required.</span>
205 <div class="form-group row">
207 class="cd-col-form-label"
208 for="namespace">Namespace</label>
209 <div class="cd-col-form-input">
210 <input id="namespace"
213 formControlName="namespace">
219 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'rgw'">
220 <!-- rgw_frontend_port -->
221 <div class="form-group row">
223 class="cd-col-form-label"
224 for="rgw_frontend_port">Port</label>
225 <div class="cd-col-form-input">
226 <input id="rgw_frontend_port"
229 formControlName="rgw_frontend_port"
232 <span class="invalid-feedback"
233 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'pattern')"
234 i18n>The entered value needs to be a number.</span>
235 <span class="invalid-feedback"
236 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'min')"
237 i18n>The value must be at least 1.</span>
238 <span class="invalid-feedback"
239 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'max')"
240 i18n>The value cannot exceed 65535.</span>
246 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'iscsi'">
248 <div class="form-group row">
250 class="cd-col-form-label required"
251 for="pool">Pool</label>
252 <div class="cd-col-form-input">
255 class="form-control custom-select"
256 formControlName="pool">
257 <option *ngIf="pools === null"
259 i18n>Loading...</option>
260 <option *ngIf="pools !== null && pools.length === 0"
262 i18n>-- No pools available --</option>
263 <option *ngIf="pools !== null && pools.length > 0"
265 i18n>-- Select a pool --</option>
266 <option *ngFor="let pool of pools"
267 [value]="pool.pool_name">{{ pool.pool_name }}</option>
269 <span class="invalid-feedback"
270 *ngIf="serviceForm.showError('pool', frm, 'required')"
271 i18n>This field is required.</span>
275 <!-- trusted_ip_list -->
276 <div class="form-group row">
277 <label class="cd-col-form-label"
278 for="trusted_ip_list">
279 <span i18n>Trusted IPs</span>
281 <span i18n>Comma separated list of IP addresses.</span>
283 <span i18n>Please add the <b>Ceph Manager</b> IP addresses here, otherwise the iSCSI gateways can't be reached.</span>
286 <div class="cd-col-form-input">
287 <input id="trusted_ip_list"
290 formControlName="trusted_ip_list">
295 <div class="form-group row">
297 class="cd-col-form-label"
298 for="api_port">Port</label>
299 <div class="cd-col-form-input">
303 formControlName="api_port"
306 <span class="invalid-feedback"
307 *ngIf="serviceForm.showError('api_port', frm, 'pattern')"
308 i18n>The entered value needs to be a number.</span>
309 <span class="invalid-feedback"
310 *ngIf="serviceForm.showError('api_port', frm, 'min')"
311 i18n>The value must be at least 1.</span>
312 <span class="invalid-feedback"
313 *ngIf="serviceForm.showError('api_port', frm, 'max')"
314 i18n>The value cannot exceed 65535.</span>
319 <div class="form-group row">
321 class="cd-col-form-label"
322 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
323 for="api_user">User</label>
324 <div class="cd-col-form-input">
328 formControlName="api_user">
329 <span class="invalid-feedback"
330 *ngIf="serviceForm.showError('api_user', frm, 'required')"
331 i18n>This field is required.</span>
335 <!-- api_password -->
336 <div class="form-group row">
338 class="cd-col-form-label"
339 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
340 for="api_password">Password</label>
341 <div class="cd-col-form-input">
342 <div class="input-group">
343 <input id="api_password"
346 autocomplete="new-password"
347 formControlName="api_password">
348 <span class="input-group-append">
349 <button type="button"
350 class="btn btn-light"
351 cdPasswordButton="api_password">
353 <cd-copy-2-clipboard-button source="api_password">
354 </cd-copy-2-clipboard-button>
356 <span class="invalid-feedback"
357 *ngIf="serviceForm.showError('api_password', frm, 'required')"
358 i18n>This field is required.</span>
365 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'ingress'">
367 <div class="form-group row">
368 <label class="cd-col-form-label"
369 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
371 <span i18n>Virtual IP</span>
373 <span i18n>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</span>
376 <div class="cd-col-form-input">
377 <input id="virtual_ip"
380 formControlName="virtual_ip">
381 <span class="invalid-feedback"
382 *ngIf="serviceForm.showError('virtual_ip', frm, 'required')"
383 i18n>This field is required.</span>
387 <!-- frontend_port -->
388 <div class="form-group row">
389 <label class="cd-col-form-label"
390 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
392 <span i18n>Frontend Port</span>
394 <span i18n>The port used to access the ingress service.</span>
397 <div class="cd-col-form-input">
398 <input id="frontend_port"
401 formControlName="frontend_port"
404 <span class="invalid-feedback"
405 *ngIf="serviceForm.showError('frontend_port', frm, 'pattern')"
406 i18n>The entered value needs to be a number.</span>
407 <span class="invalid-feedback"
408 *ngIf="serviceForm.showError('frontend_port', frm, 'min')"
409 i18n>The value must be at least 1.</span>
410 <span class="invalid-feedback"
411 *ngIf="serviceForm.showError('frontend_port', frm, 'max')"
412 i18n>The value cannot exceed 65535.</span>
413 <span class="invalid-feedback"
414 *ngIf="serviceForm.showError('frontend_port', frm, 'required')"
415 i18n>This field is required.</span>
419 <!-- monitor_port -->
420 <div class="form-group row">
421 <label class="cd-col-form-label"
422 [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
424 <span i18n>Monitor Port</span>
426 <span i18n>The port used by haproxy for load balancer status.</span>
429 <div class="cd-col-form-input">
430 <input id="monitor_port"
433 formControlName="monitor_port"
436 <span class="invalid-feedback"
437 *ngIf="serviceForm.showError('monitor_port', frm, 'pattern')"
438 i18n>The entered value needs to be a number.</span>
439 <span class="invalid-feedback"
440 *ngIf="serviceForm.showError('monitor_port', frm, 'min')"
441 i18n>The value must be at least 1.</span>
442 <span class="invalid-feedback"
443 *ngIf="serviceForm.showError('monitor_port', frm, 'max')"
444 i18n>The value cannot exceed 65535.</span>
445 <span class="invalid-feedback"
446 *ngIf="serviceForm.showError('monitor_port', frm, 'required')"
447 i18n>This field is required.</span>
450 <!-- virtual_interface_networks -->
451 <div class="form-group row">
452 <label class="cd-col-form-label"
453 for="virtual_interface_networks">
454 <span i18n>CIDR Networks</span>
456 <span i18n>A list of networks to identify which network interface to use for the virtual IP address.</span>
459 <div class="cd-col-form-input">
460 <input id="virtual_interface_networks"
463 formControlName="virtual_interface_networks">
467 <!-- RGW, Ingress & iSCSI -->
468 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && ['rgw', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)">
470 <div class="form-group row">
471 <div class="cd-col-form-offset">
472 <div class="custom-control custom-checkbox">
473 <input class="custom-control-input"
476 formControlName="ssl">
477 <label class="custom-control-label"
485 <div *ngIf="serviceForm.controls.ssl.value"
486 class="form-group row">
487 <label class="cd-col-form-label"
489 <span i18n>Certificate</span>
490 <cd-helper i18n>The SSL certificate in PEM format.</cd-helper>
492 <div class="cd-col-form-input">
493 <textarea id="ssl_cert"
494 class="form-control resize-vertical text-monospace text-pre"
495 formControlName="ssl_cert"
499 (change)="fileUpload($event.target.files, 'ssl_cert')">
500 <span class="invalid-feedback"
501 *ngIf="serviceForm.showError('ssl_cert', frm, 'required')"
502 i18n>This field is required.</span>
503 <span class="invalid-feedback"
504 *ngIf="serviceForm.showError('ssl_cert', frm, 'pattern')"
505 i18n>Invalid SSL certificate.</span>
510 <div *ngIf="serviceForm.controls.ssl.value"
511 class="form-group row">
512 <label class="cd-col-form-label"
514 <span i18n>Private key</span>
515 <cd-helper i18n>The SSL private key in PEM format.</cd-helper>
517 <div class="cd-col-form-input">
518 <textarea id="ssl_key"
519 class="form-control resize-vertical text-monospace text-pre"
520 formControlName="ssl_key"
524 (change)="fileUpload($event.target.files,'ssl_key')">
525 <span class="invalid-feedback"
526 *ngIf="serviceForm.showError('ssl_key', frm, 'required')"
527 i18n>This field is required.</span>
528 <span class="invalid-feedback"
529 *ngIf="serviceForm.showError('ssl_key', frm, 'pattern')"
530 i18n>Invalid SSL private key.</span>
536 <div class="card-footer">
537 <div class="text-right">
538 <cd-form-button-panel (submitActionEvent)="onSubmit()"
540 [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>