1 <div class=
"col-sm-12 col-lg-6">
2 <form name=
"targetForm"
3 class=
"form-horizontal"
5 [formGroup]=
"targetForm"
8 <div class=
"panel panel-default">
9 <div class=
"panel-heading">
10 <h3 i18n=
"form title|Example: Create Pool@@formTitle"
11 class=
"panel-title">{{ action | titlecase }} {{ resource | upperFirst }}
</h3>
14 <div class=
"panel-body">
16 <div class=
"form-group"
17 [ngClass]=
"{'has-error': targetForm.showError('target_iqn', formDir)}">
18 <label class=
"control-label col-sm-3"
20 <ng-container i18n
>Target IQN
</ng-container>
21 <span class=
"required"></span>
23 <div class=
"col-sm-9">
24 <div class=
"input-group">
25 <input class=
"form-control"
29 formControlName=
"target_iqn"
31 <span class=
"input-group-btn">
32 <button class=
"btn btn-default"
35 (click)=
"targetSettingsModal()">
36 <i class=
"fa fa-cogs fa-fw"
37 aria-hidden=
"true"></i>
42 <span class=
"help-block"
43 *
ngIf=
"targetForm.showError('target_iqn', formDir, 'required')"
44 i18n
>This field is required.
</span>
46 <span class=
"help-block"
47 *
ngIf=
"targetForm.showError('target_iqn', formDir, 'pattern')"
48 i18n
>IQN has wrong pattern.
</span>
50 <span class=
"help-block"
51 *
ngIf=
"targetForm.showError('target_iqn', formDir, 'iqn')">
52 <ng-container i18n
>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'
</ng-container>
54 <ng-container i18n
>For example: iqn
.2016-
06.org.dashboard:storage:disk.sn-a8675309
</ng-container>
57 href=
"https://en.wikipedia.org/wiki/ISCSI#Addressing"
58 i18n
>More information
</a>
61 <span class=
"help-block"
62 *
ngIf=
"hasAdvancedSettings(targetForm.getValue('target_controls'))"
63 i18n
>This target has modified advanced settings.
</span>
69 <div class=
"form-group"
70 [ngClass]=
"{'has-error': targetForm.showError('portals', formDir)}">
71 <label class=
"control-label col-sm-3"
73 <ng-container i18n
>Portals
</ng-container>
74 <span class=
"required"></span>
76 <div class=
"col-sm-9">
78 <ng-container *
ngFor=
"let portal of portals.value; let i = index">
79 <div class=
"input-group cd-mb">
80 <input class=
"form-control"
84 <span class=
"input-group-btn">
85 <button class=
"btn btn-default"
87 (click)=
"removePortal(i, portal)">
88 <i class=
"fa fa-remove fa-fw"
89 aria-hidden=
"true"></i>
95 <span class=
"help-block"
96 *
ngIf=
"targetForm.showError('portals', formDir, 'minGateways')"
97 i18n
>At least {{ minimum_gateways }} gateways are required.
</span>
100 <div class=
"col-md-12">
101 <cd-select [data]=
"portals.value"
102 [options]=
"portalsSelections"
103 [messages]=
"messages.portals"
104 (selection)=
"onPortalSelection($event)"
105 elemClass=
"btn btn-default pull-right">
106 <i class=
"fa fa-fw fa-plus"></i>
107 <ng-container i18n
>Add portal
</ng-container>
117 <div class=
"form-group"
118 [ngClass]=
"{'has-error': targetForm.showError('disks', formDir)}">
119 <label class=
"control-label col-sm-3"
122 <div class=
"col-sm-9">
123 <ng-container *
ngFor=
"let image of targetForm.getValue('disks'); let i = index">
124 <div class=
"input-group cd-mb">
125 <input class=
"form-control"
129 <div class=
"input-group-addon"
130 *
ngIf=
"api_version >= 1">lun: {{ imagesSettings[image]['lun'] }}
</div>
131 <span class=
"input-group-btn">
132 <button class=
"btn btn-default"
134 (click)=
"imageSettingsModal(image)">
135 <i class=
"fa fa-cogs fa-fw"
136 aria-hidden=
"true"></i>
138 <button class=
"btn btn-default"
140 (click)=
"removeImage(i, image)">
141 <i class=
"fa fa-remove fa-fw"
142 aria-hidden=
"true"></i>
148 <span class=
"help-block">
149 <ng-container *
ngIf=
"backstores.length > 1"
150 i18n
>Backstore: {{ imagesSettings[image].backstore | iscsiBackstore }}.
</ng-container>
152 <ng-container *
ngIf=
"hasAdvancedSettings(imagesSettings[image][imagesSettings[image].backstore])"
153 i18n
>This image has modified settings.
</ng-container>
157 <input class=
"form-control"
161 formControlName=
"disks" />
163 <span class=
"help-block"
164 *
ngIf=
"targetForm.showError('disks', formDir, 'dupLunId')"
165 i18n
>Duplicated LUN numbers.
</span>
167 <span class=
"help-block"
168 *
ngIf=
"targetForm.showError('disks', formDir, 'dupWwn')"
169 i18n
>Duplicated WWN.
</span>
172 <div class=
"col-md-12">
173 <cd-select [data]=
"disks.value"
174 [options]=
"imagesSelections"
175 [messages]=
"messages.images"
176 (selection)=
"onImageSelection($event)"
177 elemClass=
"btn btn-default pull-right">
178 <i class=
"fa fa-fw fa-plus"></i>
179 <ng-container i18n
>Add image
</ng-container>
189 <div class=
"form-group">
190 <div class=
"col-sm-offset-3 col-sm-9">
191 <div class=
"checkbox checkbox-primary">
192 <input type=
"checkbox"
193 formControlName=
"acl_enabled"
196 <label for=
"acl_enabled"
197 i18n
>ACL authentication
</label>
204 <!-- Target level authentication was introduced in ceph-iscsi config v11 -->
205 <div formGroupName=
"auth" *
ngIf=
"cephIscsiConfigVersion > 10 && !targetForm.getValue('acl_enabled')">
208 <div class=
"form-group"
209 [ngClass]=
"{'has-error': targetForm.showError('user', formDir)}">
210 <label class=
"control-label col-sm-3"
212 <ng-container i18n
>User
</ng-container>
214 <div class=
"col-sm-9">
215 <input class=
"form-control"
219 formControlName=
"user" />
221 <span class=
"help-block"
222 *
ngIf=
"targetForm.showError('user', formDir, 'required')"
223 i18n
>This field is required.
</span>
225 <span class=
"help-block"
226 *
ngIf=
"targetForm.showError('user', formDir, 'pattern')"
227 i18n
>Usernames must have a length of
8 to
64 characters and
228 can only contain letters, '.', '@', '-', '_' or ':'.
</span>
232 <!-- Target password -->
233 <div class=
"form-group"
234 [ngClass]=
"{'has-error': targetForm.showError('password', formDir)}">
235 <label class=
"control-label col-sm-3"
236 for=
"target_password">
237 <ng-container i18n
>Password
</ng-container>
239 <div class=
"col-sm-9">
240 <div class=
"input-group">
241 <input class=
"form-control"
243 autocomplete=
"new-password"
245 name=
"target_password"
246 formControlName=
"password" />
247 <span class=
"input-group-btn">
248 <button type=
"button"
249 class=
"btn btn-default"
250 cdPasswordButton=
"target_password">
252 <button type=
"button"
253 class=
"btn btn-default"
254 cdCopy2ClipboardButton=
"target_password">
259 <span class=
"help-block"
260 *
ngIf=
"targetForm.showError('password', formDir, 'required')"
261 i18n
>This field is required.
</span>
263 <span class=
"help-block"
264 *
ngIf=
"targetForm.showError('password', formDir, 'pattern')"
265 i18n
>Passwords must have a length of
12 to
16 characters
266 and can only contain letters, '@', '-', '_' or '/'.
</span>
270 <!-- Target mutual_user -->
271 <div class=
"form-group"
272 [ngClass]=
"{'has-error': targetForm.showError('mutual_user', formDir)}">
273 <label class=
"control-label col-sm-3"
274 for=
"target_mutual_user">
275 <ng-container i18n
>Mutual User
</ng-container>
277 <div class=
"col-sm-9">
278 <input class=
"form-control"
280 id=
"target_mutual_user"
281 name=
"target_mutual_user"
282 formControlName=
"mutual_user" />
284 <span class=
"help-block"
285 *
ngIf=
"targetForm.showError('mutual_user', formDir, 'required')"
286 i18n
>This field is required.
</span>
288 <span class=
"help-block"
289 *
ngIf=
"targetForm.showError('mutual_user', formDir, 'pattern')"
290 i18n
>Usernames must have a length of
8 to
64 characters and
291 can only contain letters, '.', '@', '-', '_' or ':'.
</span>
295 <!-- Target mutual_password -->
296 <div class=
"form-group"
297 [ngClass]=
"{'has-error': targetForm.showError('mutual_password', formDir)}">
298 <label class=
"control-label col-sm-3"
299 for=
"target_mutual_password">
300 <ng-container i18n
>Mutual Password
</ng-container>
302 <div class=
"col-sm-9">
303 <div class=
"input-group">
304 <input class=
"form-control"
306 autocomplete=
"new-password"
307 id=
"target_mutual_password"
308 name=
"target_mutual_password"
309 formControlName=
"mutual_password" />
311 <span class=
"input-group-btn">
312 <button type=
"button"
313 class=
"btn btn-default"
314 cdPasswordButton=
"target_mutual_password">
316 <button type=
"button"
317 class=
"btn btn-default"
318 cdCopy2ClipboardButton=
"target_mutual_password">
323 <span class=
"help-block"
324 *
ngIf=
"targetForm.showError('mutual_password', formDir, 'required')"
325 i18n
>This field is required.
</span>
327 <span class=
"help-block"
328 *
ngIf=
"targetForm.showError('mutual_password', formDir, 'pattern')"
329 i18n
>Passwords must have a length of
12 to
16 characters
330 and can only contain letters, '@', '-', '_' or '/'.
</span>
337 <div class=
"form-group"
338 *
ngIf=
"targetForm.getValue('acl_enabled')">
339 <label class=
"control-label col-sm-3"
341 i18n
>Initiators
</label>
342 <div class=
"col-sm-9"
343 formArrayName=
"initiators">
344 <div class=
"panel panel-default"
345 *
ngFor=
"let initiator of initiators.controls; let ii = index"
346 [formGroupName]=
"ii">
347 <div class=
"panel-heading">
348 <ng-container i18n
>Initiator
</ng-container>: {{ initiator.getValue('client_iqn') }}
349 <button type=
"button"
351 (click)=
"removeInitiator(ii)">
352 <i class=
"fa fa-remove fa-fw"></i>
355 <div class=
"panel-body">
356 <!-- Initiator: Name -->
357 <div class=
"form-group"
358 [ngClass]=
"{'has-error': initiator.showError('client_iqn', formDir)}">
359 <label class=
"control-label col-sm-3"
361 <ng-container i18n
>Client IQN
</ng-container>
362 <span class=
"required"></span>
364 <div class=
"col-sm-9">
365 <input class=
"form-control"
367 formControlName=
"client_iqn"
369 (blur)=
"updatedInitiatorSelector()">
371 <span class=
"help-block"
372 *
ngIf=
"initiator.showError('client_iqn', formDir, 'notUnique')"
373 i18n
>Initiator IQN needs to be unique.
</span>
375 <span class=
"help-block"
376 *
ngIf=
"initiator.showError('client_iqn', formDir, 'required')"
377 i18n
>This field is required.
</span>
379 <span class=
"help-block"
380 *
ngIf=
"initiator.showError('client_iqn', formDir, 'pattern')"
381 i18n
>IQN has wrong pattern.
</span>
385 <ng-container formGroupName=
"auth">
386 <!-- Initiator: User -->
387 <div class=
"form-group"
388 [ngClass]=
"{'has-error': initiator.showError('user', formDir)}">
389 <label class=
"control-label col-sm-3"
392 <div class=
"col-sm-9">
393 <input [id]=
"'user' + ii"
395 formControlName=
"user"
397 <span class=
"help-block"
398 *
ngIf=
"initiator.showError('user', formDir, 'required')"
399 i18n
>This field is required.
</span>
401 <span class=
"help-block"
402 *
ngIf=
"initiator.showError('user', formDir, 'pattern')"
403 i18n
>Usernames must have a length of
8 to
64 characters and
404 can only contain letters, '.', '@', '-', '_' or ':'.
</span>
408 <!-- Initiator: Password -->
409 <div class=
"form-group"
410 [ngClass]=
"{'has-error': initiator.showError('password', formDir)}">
411 <label class=
"control-label col-sm-3"
413 i18n
>Password
</label>
414 <div class=
"col-sm-9">
415 <div class=
"input-group">
416 <input [id]=
"'password' + ii"
418 formControlName=
"password"
421 <span class=
"input-group-btn">
422 <button type=
"button"
423 class=
"btn btn-default"
424 [cdPasswordButton]=
"'password' + ii">
426 <button type=
"button"
427 class=
"btn btn-default"
428 [cdCopy2ClipboardButton]=
"'password' + ii">
432 <span class=
"help-block"
433 *
ngIf=
"initiator.showError('password', formDir, 'required')"
434 i18n
>This field is required.
</span>
436 <span class=
"help-block"
437 *
ngIf=
"initiator.showError('password', formDir, 'pattern')"
438 i18n
>Passwords must have a length of
12 to
16 characters
439 and can only contain letters, '@', '-', '_' or '/'.
</span>
444 <!-- Initiator: mutual_user -->
445 <div class=
"form-group"
446 [ngClass]=
"{'has-error': initiator.showError('mutual_user', formDir)}">
447 <label class=
"control-label col-sm-3"
449 <ng-container i18n
>Mutual User
</ng-container>
451 <div class=
"col-sm-9">
452 <input [id]=
"'mutual_user' + ii"
454 formControlName=
"mutual_user"
457 <span class=
"help-block"
458 *
ngIf=
"initiator.showError('mutual_user', formDir, 'required')"
459 i18n
>This field is required.
</span>
461 <span class=
"help-block"
462 *
ngIf=
"initiator.showError('mutual_user', formDir, 'pattern')"
463 i18n
>Usernames must have a length of
8 to
64 characters and
464 can only contain letters, '.', '@', '-', '_' or ':'.
</span>
468 <!-- Initiator: mutual_password -->
469 <div class=
"form-group"
470 [ngClass]=
"{'has-error': initiator.showError('mutual_password', formDir)}">
471 <label class=
"control-label col-sm-3"
472 for=
"mutual_password"
473 i18n
>Mutual Password
</label>
474 <div class=
"col-sm-9">
475 <div class=
"input-group">
476 <input [id]=
"'mutual_password' + ii"
478 formControlName=
"mutual_password"
481 <span class=
"input-group-btn">
482 <button type=
"button"
483 class=
"btn btn-default"
484 [cdPasswordButton]=
"'mutual_password' + ii">
486 <button type=
"button"
487 class=
"btn btn-default"
488 [cdCopy2ClipboardButton]=
"'mutual_password' + ii">
492 <span class=
"help-block"
493 *
ngIf=
"initiator.showError('mutual_password', formDir, 'required')"
494 i18n
>This field is required.
</span>
496 <span class=
"help-block"
497 *
ngIf=
"initiator.showError('mutual_password', formDir, 'pattern')"
498 i18n
>Passwords must have a length of
12 to
16 characters and
499 can only contain letters, '@', '-', '_' or '/'.
</span>
504 <!-- Initiator: Images -->
505 <div class=
"form-group"
506 [ngClass]=
"{'has-error': initiator.showError('luns', formDir)}">
507 <label class=
"control-label col-sm-3"
510 <div class=
"col-sm-9">
511 <ng-container *
ngFor=
"let image of initiator.getValue('luns'); let li = index">
512 <div class=
"input-group cd-mb">
513 <input class=
"form-control"
517 <span class=
"input-group-btn">
518 <button class=
"btn btn-default"
520 (click)=
"removeInitiatorImage(initiator, li, ii, image)">
521 <i class=
"fa fa-remove fa-fw"
522 aria-hidden=
"true"></i>
528 <span *
ngIf=
"initiator.getValue('cdIsInGroup')"
529 i18n
>Initiator belongs to a group. Images will be configure in the group.
</span>
532 *
ngIf=
"!initiator.getValue('cdIsInGroup')">
533 <div class=
"col-md-12">
534 <cd-select [data]=
"initiator.getValue('luns')"
535 [options]=
"imagesInitiatorSelections[ii]"
536 [messages]=
"messages.initiatorImage"
537 elemClass=
"btn btn-default pull-right">
538 <i class=
"fa fa-fw fa-plus"></i>
539 <ng-container i18n
>Add image
</ng-container>
549 <div class=
"col-md-12">
550 <span class=
"text-muted"
551 *
ngIf=
"initiators.controls.length === 0"
552 i18n
>No items added.
</span>
554 <button (click)=
"addInitiator(); false"
555 class=
"btn btn-default pull-right">
556 <i class=
"fa fa-fw fa-plus"></i>
557 <ng-container i18n
>Add initiator
</ng-container>
567 <div class=
"form-group"
568 *
ngIf=
"targetForm.getValue('acl_enabled')"
569 [ngClass]=
"{'has-error': targetForm.showError('groups', formDir)}">
570 <label class=
"control-label col-sm-3"
573 <div class=
"col-sm-9"
574 formArrayName=
"groups">
575 <div class=
"panel panel-default"
576 *
ngFor=
"let group of groups.controls; let gi = index"
577 [formGroupName]=
"gi">
578 <div class=
"panel-heading">
579 <ng-container i18n
>Group
</ng-container>: {{ group.getValue('group_id') }}
580 <button type=
"button"
582 (click)=
"groups.removeAt(gi)">
583 <i class=
"fa fa-remove fa-fw"></i>
586 <div class=
"panel-body">
587 <!-- Group: group_id -->
588 <div class=
"form-group">
589 <label class=
"control-label col-sm-3"
591 <ng-container i18n
>Name
</ng-container>
592 <span class=
"required"></span>
594 <div class=
"col-sm-9">
595 <input class=
"form-control"
597 formControlName=
"group_id">
601 <!-- Group: members -->
602 <div class=
"form-group"
603 [ngClass]=
"{'has-error': group.showError('members', formDir)}">
604 <label class=
"control-label col-sm-3"
606 <ng-container i18n
>Initiators
</ng-container>
608 <div class=
"col-sm-9">
609 <ng-container *
ngFor=
"let member of group.getValue('members'); let i = index">
610 <div class=
"input-group cd-mb">
611 <input class=
"form-control"
615 <span class=
"input-group-btn">
616 <button class=
"btn btn-default"
618 (click)=
"removeGroupInitiator(group, i, gi)">
619 <i class=
"fa fa-remove fa-fw"
620 aria-hidden=
"true"></i>
627 <div class=
"col-md-12">
628 <cd-select [data]=
"group.getValue('members')"
629 [options]=
"groupMembersSelections[gi]"
630 [messages]=
"messages.groupInitiator"
631 (selection)=
"onGroupMemberSelection($event)"
632 elemClass=
"btn btn-default pull-right">
633 <i class=
"fa fa-fw fa-plus"></i>
634 <ng-container i18n
>Add initiator
</ng-container>
643 <!-- Group: disks -->
644 <div class=
"form-group"
645 [ngClass]=
"{'has-error': group.showError('disks', formDir)}">
646 <label class=
"control-label col-sm-3"
648 <ng-container i18n
>Images
</ng-container>
650 <div class=
"col-sm-9">
651 <ng-container *
ngFor=
"let disk of group.getValue('disks'); let i = index">
652 <div class=
"input-group cd-mb">
653 <input class=
"form-control"
657 <span class=
"input-group-btn">
658 <button class=
"btn btn-default"
660 (click)=
"removeGroupDisk(group, i, gi)">
661 <i class=
"fa fa-remove fa-fw"
662 aria-hidden=
"true"></i>
669 <div class=
"col-md-12">
670 <cd-select [data]=
"group.getValue('disks')"
671 [options]=
"groupDiskSelections[gi]"
672 [messages]=
"messages.initiatorImage"
673 elemClass=
"btn btn-default pull-right">
674 <i class=
"fa fa-fw fa-plus"></i>
675 <ng-container i18n
>Add image
</ng-container>
687 <div class=
"col-md-12">
688 <span class=
"text-muted"
689 *
ngIf=
"groups.controls.length === 0"
690 i18n
>No items added.
</span>
692 <button (click)=
"addGroup(); false"
693 class=
"btn btn-default pull-right">
694 <i class=
"fa fa-fw fa-plus"></i>
695 <ng-container i18n
>Add group
</ng-container>
703 <div class=
"panel-footer">
704 <div class=
"button-group text-right">
707 (submitAction)=
"submit()"
708 i18n=
"form action button|Example: Create Pool@@formActionButton"
709 type=
"button">{{ action | titlecase }} {{ resource | upperFirst }}
</cd-submit-button>
710 <cd-back-button></cd-back-button>