]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.html
e2d4f01140ccef8c1032f8546215de28a9c653b5
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / ceph / cluster / services / service-form / service-form.component.html
1 <div class="cd-col-form">
2 <form #frm="ngForm"
3 [formGroup]="serviceForm"
4 novalidate>
5 <div class="card">
6 <div i18n="form title|Example: Create Pool@@formTitle"
7 class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
8
9 <div class="card-body">
10 <!-- Service type -->
11 <div class="form-group row">
12 <label class="cd-col-form-label required"
13 for="service_type"
14 i18n>Type</label>
15 <div class="cd-col-form-input">
16 <select id="service_type"
17 class="form-control custom-select"
18 formControlName="service_type">
19 <option i18n
20 [ngValue]="null">-- Select a service type --</option>
21 <option *ngFor="let serviceType of serviceTypes"
22 [value]="serviceType">
23 {{ serviceType }}
24 </option>
25 </select>
26 <span class="invalid-feedback"
27 *ngIf="serviceForm.showError('service_type', frm, 'required')"
28 i18n>This field is required.</span>
29 </div>
30 </div>
31
32 <!-- Service id -->
33 <div class="form-group row">
34 <label i18n
35 class="cd-col-form-label"
36 [ngClass]="{'required': ['mds', 'rgw', 'nfs', 'iscsi'].includes(serviceForm.controls.service_type.value)}"
37 for="service_id">Id</label>
38 <div class="cd-col-form-input">
39 <input id="service_id"
40 class="form-control"
41 type="text"
42 formControlName="service_id">
43 <span class="invalid-feedback"
44 *ngIf="serviceForm.showError('service_id', frm, 'required')"
45 i18n>This field is required.</span>
46 <span class="invalid-feedback"
47 *ngIf="serviceForm.showError('service_id', frm, 'rgwPattern')"
48 i18n>The value does not match the pattern <strong>&lt;realm_name&gt;.&lt;zone_name&gt;[.&lt;subcluster&gt;]</strong>.</span>
49 </div>
50 </div>
51
52 <!-- unmanaged -->
53 <div class="form-group row">
54 <div class="cd-col-form-offset">
55 <div class="custom-control custom-checkbox">
56 <input class="custom-control-input"
57 id="unmanaged"
58 type="checkbox"
59 formControlName="unmanaged">
60 <label class="custom-control-label"
61 for="unmanaged"
62 i18n>Unmanaged</label>
63 </div>
64 </div>
65 </div>
66
67 <!-- Placement -->
68 <div *ngIf="!serviceForm.controls.unmanaged.value"
69 class="form-group row">
70 <label class="cd-col-form-label"
71 for="placement"
72 i18n>Placement</label>
73 <div class="cd-col-form-input">
74 <select id="placement"
75 class="form-control custom-select"
76 formControlName="placement">
77 <option i18n
78 value="hosts">Hosts</option>
79 <option i18n
80 value="label">Label</option>
81 </select>
82 </div>
83 </div>
84
85 <!-- Label -->
86 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'label'"
87 class="form-group row">
88 <label i18n
89 class="cd-col-form-label"
90 for="label">Label</label>
91 <div class="cd-col-form-input">
92 <input id="label"
93 class="form-control"
94 type="text"
95 formControlName="label"
96 [ngbTypeahead]="searchLabels"
97 (focus)="labelFocus.next($any($event).target.value)"
98 (click)="labelClick.next($any($event).target.value)">
99 <span class="invalid-feedback"
100 *ngIf="serviceForm.showError('label', frm, 'required')"
101 i18n>This field is required.</span>
102 </div>
103 </div>
104
105 <!-- Hosts -->
106 <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'hosts'"
107 class="form-group row">
108 <label class="cd-col-form-label"
109 for="hosts"
110 i18n>Hosts</label>
111 <div class="cd-col-form-input">
112 <cd-select-badges id="hosts"
113 [data]="serviceForm.controls.hosts.value"
114 [options]="hosts.options"
115 [messages]="hosts.messages">
116 </cd-select-badges>
117 </div>
118 </div>
119
120 <!-- count -->
121 <div *ngIf="!serviceForm.controls.unmanaged.value"
122 class="form-group row">
123 <label class="cd-col-form-label"
124 for="count">
125 <span i18n>Count</span>
126 <cd-helper i18n>Only that number of daemons will be created.</cd-helper>
127 </label>
128 <div class="cd-col-form-input">
129 <input id="count"
130 class="form-control"
131 type="number"
132 formControlName="count"
133 min="1">
134 <span class="invalid-feedback"
135 *ngIf="serviceForm.showError('count', frm, 'min')"
136 i18n>The value must be at least 1.</span>
137 <span class="invalid-feedback"
138 *ngIf="serviceForm.showError('count', frm, 'pattern')"
139 i18n>The entered value needs to be a number.</span>
140 </div>
141 </div>
142
143 <!-- NFS -->
144 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'nfs'">
145 <!-- pool -->
146 <div class="form-group row">
147 <label i18n
148 class="cd-col-form-label required"
149 for="pool">Pool</label>
150 <div class="cd-col-form-input">
151 <select id="pool"
152 name="pool"
153 class="form-control custom-select"
154 formControlName="pool">
155 <option *ngIf="pools === null"
156 [ngValue]="null"
157 i18n>Loading...</option>
158 <option *ngIf="pools !== null && pools.length === 0"
159 [ngValue]="null"
160 i18n>-- No pools available --</option>
161 <option *ngIf="pools !== null && pools.length > 0"
162 [ngValue]="null"
163 i18n>-- Select a pool --</option>
164 <option *ngFor="let pool of pools"
165 [value]="pool.pool_name">{{ pool.pool_name }}</option>
166 </select>
167 <span class="invalid-feedback"
168 *ngIf="serviceForm.showError('pool', frm, 'required')"
169 i18n>This field is required.</span>
170 </div>
171 </div>
172
173 <!-- namespace -->
174 <div class="form-group row">
175 <label i18n
176 class="cd-col-form-label"
177 for="namespace">Namespace</label>
178 <div class="cd-col-form-input">
179 <input id="namespace"
180 class="form-control"
181 type="text"
182 formControlName="namespace">
183 </div>
184 </div>
185 </ng-container>
186
187 <!-- RGW -->
188 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'rgw'">
189 <!-- rgw_frontend_port -->
190 <div class="form-group row">
191 <label i18n
192 class="cd-col-form-label"
193 for="rgw_frontend_port">Port</label>
194 <div class="cd-col-form-input">
195 <input id="rgw_frontend_port"
196 class="form-control"
197 type="number"
198 formControlName="rgw_frontend_port"
199 min="1"
200 max="65535">
201 <span class="invalid-feedback"
202 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'pattern')"
203 i18n>The entered value needs to be a number.</span>
204 <span class="invalid-feedback"
205 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'min')"
206 i18n>The value must be at least 1.</span>
207 <span class="invalid-feedback"
208 *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'max')"
209 i18n>The value cannot exceed 65535.</span>
210 </div>
211 </div>
212 </ng-container>
213
214 <!-- iSCSI -->
215 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'iscsi'">
216 <!-- pool -->
217 <div class="form-group row">
218 <label i18n
219 class="cd-col-form-label required"
220 for="pool">Pool</label>
221 <div class="cd-col-form-input">
222 <select id="pool"
223 name="pool"
224 class="form-control custom-select"
225 formControlName="pool">
226 <option *ngIf="pools === null"
227 [ngValue]="null"
228 i18n>Loading...</option>
229 <option *ngIf="pools !== null && pools.length === 0"
230 [ngValue]="null"
231 i18n>-- No pools available --</option>
232 <option *ngIf="pools !== null && pools.length > 0"
233 [ngValue]="null"
234 i18n>-- Select a pool --</option>
235 <option *ngFor="let pool of pools"
236 [value]="pool.pool_name">{{ pool.pool_name }}</option>
237 </select>
238 <span class="invalid-feedback"
239 *ngIf="serviceForm.showError('pool', frm, 'required')"
240 i18n>This field is required.</span>
241 </div>
242 </div>
243
244 <!-- trusted_ip_list -->
245 <div class="form-group row">
246 <label class="cd-col-form-label"
247 for="trusted_ip_list">
248 <span i18n>Trusted IPs</span>
249 <cd-helper>
250 <span i18n>Comma separated list of IP addresses.</span>
251 <br>
252 <span i18n>Please add the <b>Ceph Manager</b> IP addresses here, otherwise the iSCSI gateways can't be reached.</span>
253 </cd-helper>
254 </label>
255 <div class="cd-col-form-input">
256 <input id="trusted_ip_list"
257 class="form-control"
258 type="text"
259 formControlName="trusted_ip_list">
260 </div>
261 </div>
262
263 <!-- api_port -->
264 <div class="form-group row">
265 <label i18n
266 class="cd-col-form-label"
267 for="api_port">Port</label>
268 <div class="cd-col-form-input">
269 <input id="api_port"
270 class="form-control"
271 type="number"
272 formControlName="api_port"
273 min="1"
274 max="65535">
275 <span class="invalid-feedback"
276 *ngIf="serviceForm.showError('api_port', frm, 'pattern')"
277 i18n>The entered value needs to be a number.</span>
278 <span class="invalid-feedback"
279 *ngIf="serviceForm.showError('api_port', frm, 'min')"
280 i18n>The value must be at least 1.</span>
281 <span class="invalid-feedback"
282 *ngIf="serviceForm.showError('api_port', frm, 'max')"
283 i18n>The value cannot exceed 65535.</span>
284 </div>
285 </div>
286
287 <!-- api_user -->
288 <div class="form-group row">
289 <label i18n
290 class="cd-col-form-label"
291 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
292 for="api_user">User</label>
293 <div class="cd-col-form-input">
294 <input id="api_user"
295 class="form-control"
296 type="text"
297 formControlName="api_user">
298 <span class="invalid-feedback"
299 *ngIf="serviceForm.showError('api_user', frm, 'required')"
300 i18n>This field is required.</span>
301 </div>
302 </div>
303
304 <!-- api_password -->
305 <div class="form-group row">
306 <label i18n
307 class="cd-col-form-label"
308 [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
309 for="api_password">Password</label>
310 <div class="cd-col-form-input">
311 <div class="input-group">
312 <input id="api_password"
313 class="form-control"
314 type="password"
315 autocomplete="new-password"
316 formControlName="api_password">
317 <span class="input-group-append">
318 <button type="button"
319 class="btn btn-light"
320 cdPasswordButton="api_password">
321 </button>
322 <cd-copy-2-clipboard-button source="api_password">
323 </cd-copy-2-clipboard-button>
324 </span>
325 <span class="invalid-feedback"
326 *ngIf="serviceForm.showError('api_password', frm, 'required')"
327 i18n>This field is required.</span>
328 </div>
329 </div>
330 </div>
331 </ng-container>
332
333 <!-- RGW & iSCSI -->
334 <ng-container *ngIf="!serviceForm.controls.unmanaged.value && ['rgw', 'iscsi'].includes(serviceForm.controls.service_type.value)">
335 <!-- ssl -->
336 <div class="form-group row">
337 <div class="cd-col-form-offset">
338 <div class="custom-control custom-checkbox">
339 <input class="custom-control-input"
340 id="ssl"
341 type="checkbox"
342 formControlName="ssl">
343 <label class="custom-control-label"
344 for="ssl"
345 i18n>SSL</label>
346 </div>
347 </div>
348 </div>
349
350 <!-- ssl_cert -->
351 <div *ngIf="serviceForm.controls.ssl.value"
352 class="form-group row">
353 <label class="cd-col-form-label"
354 for="ssl_cert">
355 <span i18n>Certificate</span>
356 <cd-helper i18n>The SSL certificate in PEM format.</cd-helper>
357 </label>
358 <div class="cd-col-form-input">
359 <textarea id="ssl_cert"
360 class="form-control resize-vertical text-monospace text-pre"
361 formControlName="ssl_cert"
362 rows="5">
363 </textarea>
364 <input type="file"
365 (change)="fileUpload($event.target.files, 'ssl_cert')">
366 <span class="invalid-feedback"
367 *ngIf="serviceForm.showError('ssl_cert', frm, 'required')"
368 i18n>This field is required.</span>
369 <span class="invalid-feedback"
370 *ngIf="serviceForm.showError('ssl_cert', frm, 'pattern')"
371 i18n>Invalid SSL certificate.</span>
372 </div>
373 </div>
374
375 <!-- ssl_key -->
376 <div *ngIf="serviceForm.controls.ssl.value"
377 class="form-group row">
378 <label class="cd-col-form-label"
379 for="ssl_key">
380 <span i18n>Private key</span>
381 <cd-helper i18n>The SSL private key in PEM format.</cd-helper>
382 </label>
383 <div class="cd-col-form-input">
384 <textarea id="ssl_key"
385 class="form-control resize-vertical text-monospace text-pre"
386 formControlName="ssl_key"
387 rows="5">
388 </textarea>
389 <input type="file"
390 (change)="fileUpload($event.target.files,'ssl_key')">
391 <span class="invalid-feedback"
392 *ngIf="serviceForm.showError('ssl_key', frm, 'required')"
393 i18n>This field is required.</span>
394 <span class="invalid-feedback"
395 *ngIf="serviceForm.showError('ssl_key', frm, 'pattern')"
396 i18n>Invalid SSL private key.</span>
397 </div>
398 </div>
399 </ng-container>
400 </div>
401
402 <div class="card-footer">
403 <div class="text-right">
404 <cd-form-button-panel (submitActionEvent)="onSubmit()"
405 [form]="serviceForm"
406 [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>
407 </div>
408 </div>
409 </div>
410 </form>
411 </div>