1 <div class=
"cd-col-form">
2 <form name=
"targetForm"
4 [formGroup]=
"targetForm"
8 <div i18n=
"form title|Example: Create Pool@@formTitle"
9 class=
"card-header">{{ action | titlecase }} {{ resource | upperFirst }}
</div>
11 <div class=
"card-body">
13 <div class=
"form-group row">
14 <label class=
"cd-col-form-label required"
16 i18n
>Target IQN
</label>
17 <div class=
"cd-col-form-input">
18 <div class=
"input-group">
19 <input class=
"form-control"
23 formControlName=
"target_iqn"
25 <span class=
"input-group-append">
26 <button class=
"btn btn-light"
29 (click)=
"targetSettingsModal()">
30 <i [ngClass]=
"[icons.deepCheck]"
31 aria-hidden=
"true"></i>
36 <span class=
"invalid-feedback"
37 *
ngIf=
"targetForm.showError('target_iqn', formDir, 'required')"
38 i18n
>This field is required.
</span>
40 <span class=
"invalid-feedback"
41 *
ngIf=
"targetForm.showError('target_iqn', formDir, 'pattern')"
42 i18n
>IQN has wrong pattern.
</span>
44 <span class=
"invalid-feedback"
45 *
ngIf=
"targetForm.showError('target_iqn', formDir, 'iqn')">
46 <ng-container i18n
>An IQN has the following notation
47 'iqn.$year-$month.$reversedAddress:$definedName'
</ng-container>
49 <ng-container i18n
>For example: iqn
.2016-
06.org.dashboard:storage:disk.sn-a8675309
</ng-container>
52 href=
"https://en.wikipedia.org/wiki/ISCSI#Addressing"
53 i18n
>More information
</a>
56 <span class=
"form-text text-muted"
57 *
ngIf=
"hasAdvancedSettings(targetForm.getValue('target_controls'))"
58 i18n
>This target has modified advanced settings.
</span>
64 <div class=
"form-group row">
65 <label class=
"cd-col-form-label required"
68 <div class=
"cd-col-form-input">
70 <ng-container *
ngFor=
"let portal of portals.value; let i = index">
71 <div class=
"input-group cd-mb">
72 <input class=
"cd-form-control"
76 <span class=
"input-group-append">
77 <button class=
"btn btn-light"
79 (click)=
"removePortal(i, portal)">
80 <i [ngClass]=
"[icons.destroy]"
81 aria-hidden=
"true"></i>
88 <div class=
"col-md-12">
89 <cd-select [data]=
"portals.value"
90 [options]=
"portalsSelections"
91 [messages]=
"messages.portals"
92 (selection)=
"onPortalSelection($event)"
93 elemClass=
"btn btn-light float-right">
94 <i [ngClass]=
"[icons.add]"></i>
95 <ng-container i18n
>Add portal
</ng-container>
100 <input class=
"form-control"
104 formControlName=
"portals" />
106 <span class=
"invalid-feedback"
107 *
ngIf=
"targetForm.showError('portals', formDir, 'minGateways')"
108 i18n
>At least {{ minimum_gateways }} gateways are required.
</span>
115 <div class=
"form-group row">
116 <label class=
"cd-col-form-label"
119 <div class=
"cd-col-form-input">
120 <ng-container *
ngFor=
"let image of targetForm.getValue('disks'); let i = index">
121 <div class=
"input-group cd-mb">
122 <input class=
"cd-form-control"
126 <span class=
"input-group-append">
127 <div class=
"input-group-text"
128 *
ngIf=
"api_version >= 1">lun: {{ imagesSettings[image]['lun'] }}
</div>
129 <button class=
"btn btn-light"
131 (click)=
"imageSettingsModal(image)">
132 <i [ngClass]=
"[icons.deepCheck]"
133 aria-hidden=
"true"></i>
135 <button class=
"btn btn-light"
137 (click)=
"removeImage(i, image)">
138 <i [ngClass]=
"[icons.destroy]"
139 aria-hidden=
"true"></i>
145 <span class=
"form-text text-muted">
146 <ng-container *
ngIf=
"backstores.length > 1"
147 i18n
>Backstore: {{ imagesSettings[image].backstore | iscsiBackstore }}.
</ng-container>
149 <ng-container *
ngIf=
"hasAdvancedSettings(imagesSettings[image][imagesSettings[image].backstore])"
150 i18n
>This image has modified settings.
</ng-container>
154 <input class=
"form-control"
158 formControlName=
"disks" />
160 <span class=
"invalid-feedback"
161 *
ngIf=
"targetForm.showError('disks', formDir, 'dupLunId')"
162 i18n
>Duplicated LUN numbers.
</span>
164 <span class=
"invalid-feedback"
165 *
ngIf=
"targetForm.showError('disks', formDir, 'dupWwn')"
166 i18n
>Duplicated WWN.
</span>
169 <div class=
"col-md-12">
170 <cd-select [data]=
"disks.value"
171 [options]=
"imagesSelections"
172 [messages]=
"messages.images"
173 (selection)=
"onImageSelection($event)"
174 elemClass=
"btn btn-light float-right">
175 <i [ngClass]=
"[icons.add]"></i>
176 <ng-container i18n
>Add image
</ng-container>
186 <div class=
"form-group row">
187 <div class=
"cd-col-form-offset">
188 <div class=
"custom-control custom-checkbox">
189 <input type=
"checkbox"
190 class=
"custom-control-input"
191 formControlName=
"acl_enabled"
194 <label for=
"acl_enabled"
195 class=
"custom-control-label"
196 i18n
>ACL authentication
</label>
203 <!-- Target level authentication was introduced in ceph-iscsi config v11 -->
204 <div formGroupName=
"auth"
205 *
ngIf=
"cephIscsiConfigVersion > 10 && !targetForm.getValue('acl_enabled')">
208 <div class=
"form-group row">
209 <label class=
"cd-col-form-label"
211 <ng-container i18n
>User
</ng-container>
213 <div class=
"cd-col-form-input">
214 <input class=
"form-control"
218 formControlName=
"user" />
220 <span class=
"invalid-feedback"
221 *
ngIf=
"targetForm.showError('user', formDir, 'required')"
222 i18n
>This field is required.
</span>
224 <span class=
"invalid-feedback"
225 *
ngIf=
"targetForm.showError('user', formDir, 'pattern')"
226 i18n
>Usernames must have a length of
8 to
64 characters and
227 can only contain letters, '.', '@', '-', '_' or ':'.
</span>
231 <!-- Target password -->
232 <div class=
"form-group row">
233 <label class=
"cd-col-form-label"
234 for=
"target_password">
235 <ng-container i18n
>Password
</ng-container>
237 <div class=
"cd-col-form-input">
238 <div class=
"input-group">
239 <input class=
"form-control"
241 autocomplete=
"new-password"
243 name=
"target_password"
244 formControlName=
"password" />
245 <span class=
"input-group-append">
246 <button type=
"button"
247 class=
"btn btn-light"
248 cdPasswordButton=
"target_password">
250 <button type=
"button"
251 class=
"btn btn-light"
252 cdCopy2ClipboardButton=
"target_password">
257 <span class=
"invalid-feedback"
258 *
ngIf=
"targetForm.showError('password', formDir, 'required')"
259 i18n
>This field is required.
</span>
261 <span class=
"invalid-feedback"
262 *
ngIf=
"targetForm.showError('password', formDir, 'pattern')"
263 i18n
>Passwords must have a length of
12 to
16 characters
264 and can only contain letters, '@', '-', '_' or '/'.
</span>
268 <!-- Target mutual_user -->
269 <div class=
"form-group row">
270 <label class=
"cd-col-form-label"
271 for=
"target_mutual_user">
272 <ng-container i18n
>Mutual User
</ng-container>
274 <div class=
"cd-col-form-input">
275 <input class=
"form-control"
277 id=
"target_mutual_user"
278 name=
"target_mutual_user"
279 formControlName=
"mutual_user" />
281 <span class=
"invalid-feedback"
282 *
ngIf=
"targetForm.showError('mutual_user', formDir, 'required')"
283 i18n
>This field is required.
</span>
285 <span class=
"invalid-feedback"
286 *
ngIf=
"targetForm.showError('mutual_user', formDir, 'pattern')"
287 i18n
>Usernames must have a length of
8 to
64 characters and
288 can only contain letters, '.', '@', '-', '_' or ':'.
</span>
292 <!-- Target mutual_password -->
293 <div class=
"form-group row">
294 <label class=
"cd-col-form-label"
295 for=
"target_mutual_password">
296 <ng-container i18n
>Mutual Password
</ng-container>
298 <div class=
"cd-col-form-input">
299 <div class=
"input-group">
300 <input class=
"form-control"
302 autocomplete=
"new-password"
303 id=
"target_mutual_password"
304 name=
"target_mutual_password"
305 formControlName=
"mutual_password" />
307 <span class=
"input-group-append">
308 <button type=
"button"
309 class=
"btn btn-light"
310 cdPasswordButton=
"target_mutual_password">
312 <button type=
"button"
313 class=
"btn btn-light"
314 cdCopy2ClipboardButton=
"target_mutual_password">
319 <span class=
"invalid-feedback"
320 *
ngIf=
"targetForm.showError('mutual_password', formDir, 'required')"
321 i18n
>This field is required.
</span>
323 <span class=
"invalid-feedback"
324 *
ngIf=
"targetForm.showError('mutual_password', formDir, 'pattern')"
325 i18n
>Passwords must have a length of
12 to
16 characters
326 and can only contain letters, '@', '-', '_' or '/'.
</span>
333 <div class=
"form-group row"
334 *
ngIf=
"targetForm.getValue('acl_enabled')">
335 <label class=
"cd-col-form-label"
337 i18n
>Initiators
</label>
338 <div class=
"cd-col-form-input"
339 formArrayName=
"initiators">
340 <div class=
"card mb-2"
341 *
ngFor=
"let initiator of initiators.controls; let ii = index"
342 [formGroupName]=
"ii">
343 <div class=
"card-header">
344 <ng-container i18n
>Initiator
</ng-container>: {{ initiator.getValue('client_iqn') }}
345 <button type=
"button"
347 (click)=
"removeInitiator(ii)">
348 <i [ngClass]=
"[icons.destroy]"></i>
351 <div class=
"card-body">
352 <!-- Initiator: Name -->
353 <div class=
"form-group row">
354 <label class=
"cd-col-form-label required"
356 i18n
>Client IQN
</label>
357 <div class=
"cd-col-form-input">
358 <input class=
"form-control"
360 formControlName=
"client_iqn"
362 (blur)=
"updatedInitiatorSelector()">
364 <span class=
"invalid-feedback"
365 *
ngIf=
"initiator.showError('client_iqn', formDir, 'notUnique')"
366 i18n
>Initiator IQN needs to be unique.
</span>
368 <span class=
"invalid-feedback"
369 *
ngIf=
"initiator.showError('client_iqn', formDir, 'required')"
370 i18n
>This field is required.
</span>
372 <span class=
"invalid-feedback"
373 *
ngIf=
"initiator.showError('client_iqn', formDir, 'pattern')"
374 i18n
>IQN has wrong pattern.
</span>
378 <ng-container formGroupName=
"auth">
379 <!-- Initiator: User -->
380 <div class=
"form-group row">
381 <label class=
"cd-col-form-label"
384 <div class=
"cd-col-form-input">
385 <input [id]=
"'user' + ii"
387 formControlName=
"user"
389 <span class=
"invalid-feedback"
390 *
ngIf=
"initiator.showError('user', formDir, 'required')"
391 i18n
>This field is required.
</span>
393 <span class=
"invalid-feedback"
394 *
ngIf=
"initiator.showError('user', formDir, 'pattern')"
395 i18n
>Usernames must have a length of
8 to
64 characters and
396 can only contain letters, '.', '@', '-', '_' or ':'.
</span>
400 <!-- Initiator: Password -->
401 <div class=
"form-group row">
402 <label class=
"cd-col-form-label"
404 i18n
>Password
</label>
405 <div class=
"cd-col-form-input">
406 <div class=
"input-group">
407 <input [id]=
"'password' + ii"
409 formControlName=
"password"
412 <span class=
"input-group-append">
413 <button type=
"button"
414 class=
"btn btn-light"
415 [cdPasswordButton]=
"'password' + ii">
417 <button type=
"button"
418 class=
"btn btn-light"
419 [cdCopy2ClipboardButton]=
"'password' + ii">
423 <span class=
"invalid-feedback"
424 *
ngIf=
"initiator.showError('password', formDir, 'required')"
425 i18n
>This field is required.
</span>
427 <span class=
"invalid-feedback"
428 *
ngIf=
"initiator.showError('password', formDir, 'pattern')"
429 i18n
>Passwords must have a length of
12 to
16 characters
430 and can only contain letters, '@', '-', '_' or '/'.
</span>
435 <!-- Initiator: mutual_user -->
436 <div class=
"form-group row">
437 <label class=
"cd-col-form-label"
439 <ng-container i18n
>Mutual User
</ng-container>
441 <div class=
"cd-col-form-input">
442 <input [id]=
"'mutual_user' + ii"
444 formControlName=
"mutual_user"
447 <span class=
"invalid-feedback"
448 *
ngIf=
"initiator.showError('mutual_user', formDir, 'required')"
449 i18n
>This field is required.
</span>
451 <span class=
"invalid-feedback"
452 *
ngIf=
"initiator.showError('mutual_user', formDir, 'pattern')"
453 i18n
>Usernames must have a length of
8 to
64 characters and
454 can only contain letters, '.', '@', '-', '_' or ':'.
</span>
458 <!-- Initiator: mutual_password -->
459 <div class=
"form-group row">
460 <label class=
"cd-col-form-label"
461 for=
"mutual_password"
462 i18n
>Mutual Password
</label>
463 <div class=
"cd-col-form-input">
464 <div class=
"input-group">
465 <input [id]=
"'mutual_password' + ii"
467 formControlName=
"mutual_password"
470 <span class=
"input-group-append">
471 <button type=
"button"
472 class=
"btn btn-light"
473 [cdPasswordButton]=
"'mutual_password' + ii">
475 <button type=
"button"
476 class=
"btn btn-light"
477 [cdCopy2ClipboardButton]=
"'mutual_password' + ii">
481 <span class=
"invalid-feedback"
482 *
ngIf=
"initiator.showError('mutual_password', formDir, 'required')"
483 i18n
>This field is required.
</span>
485 <span class=
"invalid-feedback"
486 *
ngIf=
"initiator.showError('mutual_password', formDir, 'pattern')"
487 i18n
>Passwords must have a length of
12 to
16 characters and
488 can only contain letters, '@', '-', '_' or '/'.
</span>
493 <!-- Initiator: Images -->
494 <div class=
"form-group row">
495 <label class=
"cd-col-form-label"
498 <div class=
"cd-col-form-input">
499 <ng-container *
ngFor=
"let image of initiator.getValue('luns'); let li = index">
500 <div class=
"input-group cd-mb">
501 <input class=
"cd-form-control"
505 <span class=
"input-group-append">
506 <button class=
"btn btn-light"
508 (click)=
"removeInitiatorImage(initiator, li, ii, image)">
509 <i [ngClass]=
"[icons.destroy]"
510 aria-hidden=
"true"></i>
516 <span *
ngIf=
"initiator.getValue('cdIsInGroup')"
517 i18n
>Initiator belongs to a group. Images will be configure in the group.
</span>
520 *
ngIf=
"!initiator.getValue('cdIsInGroup')">
521 <div class=
"col-md-12">
522 <cd-select [data]=
"initiator.getValue('luns')"
523 [options]=
"imagesInitiatorSelections[ii]"
524 [messages]=
"messages.initiatorImage"
525 elemClass=
"btn btn-light float-right">
526 <i [ngClass]=
"[icons.add]"></i>
527 <ng-container i18n
>Add image
</ng-container>
537 <div class=
"col-md-12">
538 <span class=
"form-text text-muted"
539 *
ngIf=
"initiators.controls.length === 0"
540 i18n
>No items added.
</span>
542 <button (click)=
"addInitiator(); false"
543 class=
"btn btn-light float-right">
544 <i [ngClass]=
"[icons.add]"></i>
545 <ng-container i18n
>Add initiator
</ng-container>
555 <div class=
"form-group row"
556 *
ngIf=
"targetForm.getValue('acl_enabled')">
557 <label class=
"cd-col-form-label"
560 <div class=
"cd-col-form-input"
561 formArrayName=
"groups">
562 <div class=
"card mb-2"
563 *
ngFor=
"let group of groups.controls; let gi = index"
564 [formGroupName]=
"gi">
565 <div class=
"card-header">
566 <ng-container i18n
>Group
</ng-container>: {{ group.getValue('group_id') }}
567 <button type=
"button"
569 (click)=
"groups.removeAt(gi)">
570 <i [ngClass]=
"[icons.destroy]"></i>
573 <div class=
"card-body">
574 <!-- Group: group_id -->
575 <div class=
"form-group row">
576 <label class=
"cd-col-form-label required"
579 <div class=
"cd-col-form-input">
580 <input class=
"form-control"
582 formControlName=
"group_id">
586 <!-- Group: members -->
587 <div class=
"form-group row">
588 <label class=
"cd-col-form-label"
590 <ng-container i18n
>Initiators
</ng-container>
592 <div class=
"cd-col-form-input">
593 <ng-container *
ngFor=
"let member of group.getValue('members'); let i = index">
594 <div class=
"input-group cd-mb">
595 <input class=
"cd-form-control"
599 <span class=
"input-group-append">
600 <button class=
"btn btn-light"
602 (click)=
"removeGroupInitiator(group, i, gi)">
603 <i [ngClass]=
"[icons.destroy]"
604 aria-hidden=
"true"></i>
611 <div class=
"col-md-12">
612 <cd-select [data]=
"group.getValue('members')"
613 [options]=
"groupMembersSelections[gi]"
614 [messages]=
"messages.groupInitiator"
615 (selection)=
"onGroupMemberSelection($event)"
616 elemClass=
"btn btn-light float-right">
617 <i [ngClass]=
"[icons.add]"></i>
618 <ng-container i18n
>Add initiator
</ng-container>
627 <!-- Group: disks -->
628 <div class=
"form-group row">
629 <label class=
"cd-col-form-label"
631 <ng-container i18n
>Images
</ng-container>
633 <div class=
"cd-col-form-input">
634 <ng-container *
ngFor=
"let disk of group.getValue('disks'); let i = index">
635 <div class=
"input-group cd-mb">
636 <input class=
"cd-form-control"
640 <span class=
"input-group-append">
641 <button class=
"btn btn-light"
643 (click)=
"removeGroupDisk(group, i, gi)">
644 <i [ngClass]=
"[icons.destroy]"
645 aria-hidden=
"true"></i>
652 <div class=
"col-md-12">
653 <cd-select [data]=
"group.getValue('disks')"
654 [options]=
"groupDiskSelections[gi]"
655 [messages]=
"messages.initiatorImage"
656 elemClass=
"btn btn-light float-right">
657 <i [ngClass]=
"[icons.add]"></i>
658 <ng-container i18n
>Add image
</ng-container>
670 <div class=
"col-md-12">
671 <span class=
"form-text text-muted"
672 *
ngIf=
"groups.controls.length === 0"
673 i18n
>No items added.
</span>
675 <button (click)=
"addGroup(); false"
676 class=
"btn btn-light float-right">
677 <i [ngClass]=
"[icons.add]"></i>
678 <ng-container i18n
>Add group
</ng-container>
686 <div class=
"card-footer">
687 <div class=
"button-group text-right">
688 <cd-submit-button (submitAction)=
"submit()"
689 i18n=
"form action button|Example: Create Pool@@formActionButton"
690 [form]=
"formDir">{{ action | titlecase }} {{ resource | upperFirst }}
</cd-submit-button>
691 <cd-back-button></cd-back-button>