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 class="panel-title"
11 i18n>{isEdit, select, 1 {Edit} other {Add}} target</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" />
30 <span class="input-group-btn">
31 <button class="btn btn-default"
34 (click)="targetSettingsModal()">
35 <i class="fa fa-cogs fa-fw"
36 aria-hidden="true"></i>
41 <span class="help-block"
42 *ngIf="targetForm.showError('target_iqn', formDir, 'required')"
43 i18n>This field is required.</span>
45 <span class="help-block"
46 *ngIf="targetForm.showError('target_iqn', formDir, 'pattern')"
47 i18n>IQN has wrong pattern.</span>
49 <span class="help-block"
50 *ngIf="targetForm.showError('target_iqn', formDir, 'iqn')">
51 <ng-container i18n>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</ng-container>
53 <ng-container i18n>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</ng-container>
56 href="https://en.wikipedia.org/wiki/ISCSI#Addressing"
57 i18n>More information</a>
60 <span class="help-block"
61 *ngIf="hasAdvancedSettings(targetForm.getValue('target_controls'))"
62 i18n>This target has modified advanced settings.</span>
68 <div class="form-group"
69 [ngClass]="{'has-error': targetForm.showError('portals', formDir)}">
70 <label class="control-label col-sm-3"
72 <ng-container i18n>Portals</ng-container>
73 <span class="required"></span>
75 <div class="col-sm-9">
77 <ng-container *ngFor="let portal of portals.value; let i = index">
78 <div class="input-group cd-mb">
79 <input class="form-control"
83 <span class="input-group-btn">
84 <button class="btn btn-default"
86 (click)="removePortal(i, portal)">
87 <i class="fa fa-remove fa-fw"
88 aria-hidden="true"></i>
94 <span class="help-block"
95 *ngIf="targetForm.showError('portals', formDir, 'minGateways')"
96 i18n>At least {{ minimum_gateways }} gateways are required.</span>
99 <div class="col-md-12">
100 <cd-select [data]="portals.value"
101 [options]="portalsSelections"
102 [messages]="messages.portals"
103 (selection)="onPortalSelection($event)"
104 elemClass="btn btn-default pull-right">
105 <i class="fa fa-fw fa-plus"></i>
106 <ng-container i18n>Add portal</ng-container>
116 <div class="form-group"
117 [ngClass]="{'has-error': targetForm.showError('disks', formDir)}">
118 <label class="control-label col-sm-3"
121 <div class="col-sm-9">
122 <ng-container *ngFor="let image of targetForm.getValue('disks'); let i = index">
123 <div class="input-group cd-mb">
124 <input class="form-control"
128 <span class="input-group-btn">
129 <button class="btn btn-default"
131 (click)="imageSettingsModal(image)">
132 <i class="fa fa-cogs fa-fw"
133 aria-hidden="true"></i>
135 <button class="btn btn-default"
137 (click)="removeImage(i, image)">
138 <i class="fa fa-remove fa-fw"
139 aria-hidden="true"></i>
145 <span class="help-block">
146 <ng-container *ngIf="backstores.length > 1"
147 i18n>Backstore: {{ imagesSettings[image].backstore }}. </ng-container>
149 <ng-container *ngIf="hasAdvancedSettings(imagesSettings[image][imagesSettings[image].backstore])"
150 i18n>This image has modified settings.</ng-container>
154 <span class="help-block"
155 *ngIf="targetForm.showError('disks', formDir, 'required')"
156 i18n>At least 1 image is required.</span>
159 <div class="col-md-12">
160 <cd-select [data]="disks.value"
161 [options]="imagesSelections"
162 [messages]="messages.images"
163 (selection)="onImageSelection($event)"
164 elemClass="btn btn-default pull-right">
165 <i class="fa fa-fw fa-plus"></i>
166 <ng-container i18n>Add image</ng-container>
176 <div class="form-group">
177 <div class="col-sm-offset-3 col-sm-9">
178 <div class="checkbox checkbox-primary">
179 <input type="checkbox"
180 formControlName="acl_enabled"
183 <label for="acl_enabled"
184 i18n>ACL authentication</label>
192 <div class="form-group"
193 *ngIf="targetForm.getValue('acl_enabled')">
194 <label class="control-label col-sm-3"
196 i18n>Initiators</label>
197 <div class="col-sm-9"
198 formArrayName="initiators">
199 <div class="panel panel-default"
200 *ngFor="let initiator of initiators.controls; let ii = index"
201 [formGroupName]="ii">
202 <div class="panel-heading">
203 <ng-container i18n>Initiator</ng-container>: {{ initiator.getValue('client_iqn') }}
204 <button type="button"
206 (click)="removeInitiator(ii)">
207 <i class="fa fa-remove fa-fw"></i>
210 <div class="panel-body">
211 <!-- Initiator: Name -->
212 <div class="form-group"
213 [ngClass]="{'has-error': initiator.showError('client_iqn', formDir)}">
214 <label class="control-label col-sm-3"
216 <ng-container i18n>Client IQN</ng-container>
217 <span class="required"></span>
219 <div class="col-sm-9">
220 <input class="form-control"
222 formControlName="client_iqn"
223 (blur)="updatedInitiatorSelector()">
225 <span class="help-block"
226 *ngIf="initiator.showError('client_iqn', formDir, 'notUnique')"
227 i18n>Initiator IQN needs to be unique.</span>
229 <span class="help-block"
230 *ngIf="initiator.showError('client_iqn', formDir, 'required')"
231 i18n>This field is required.</span>
233 <span class="help-block"
234 *ngIf="initiator.showError('client_iqn', formDir, 'pattern')"
235 i18n>IQN has wrong pattern.</span>
239 <ng-container formGroupName="auth">
240 <!-- Initiator: User -->
241 <div class="form-group"
242 [ngClass]="{'has-error': initiator.showError('user', formDir)}">
243 <label class="control-label col-sm-3"
246 <div class="col-sm-9">
249 formControlName="user"
251 <span class="help-block"
252 *ngIf="initiator.showError('user', formDir, 'required')"
253 i18n>This field is required.</span>
255 <span class="help-block"
256 *ngIf="initiator.showError('user', formDir, 'pattern')"
257 i18n>Usernames must have a length of 8 to 64 characters and
258 can only contain letters, '.', '@', '-', '_' or ':'.</span>
262 <!-- Initiator: Password -->
263 <div class="form-group"
264 [ngClass]="{'has-error': initiator.showError('password', formDir)}">
265 <label class="control-label col-sm-3"
267 i18n>Password</label>
268 <div class="col-sm-9">
269 <div class="input-group">
272 formControlName="password"
275 <span class="input-group-btn">
276 <button type="button"
277 class="btn btn-default"
278 cdPasswordButton="password">
280 <button type="button"
281 class="btn btn-default"
282 cdCopy2ClipboardButton="password">
286 <span class="help-block"
287 *ngIf="initiator.showError('password', formDir, 'required')"
288 i18n>This field is required.</span>
290 <span class="help-block"
291 *ngIf="initiator.showError('password', formDir, 'pattern')"
292 i18n>Passwords must have a length of 12 to 16 characters
293 and can only contain letters, '@', '-', '_' or '/'.</span>
298 <!-- Initiator: mutual_user -->
299 <div class="form-group"
300 [ngClass]="{'has-error': initiator.showError('mutual_user', formDir)}">
301 <label class="control-label col-sm-3"
303 <ng-container i18n>Mutual User</ng-container>
305 <div class="col-sm-9">
306 <input id="mutual_user"
308 formControlName="mutual_user"
311 <span class="help-block"
312 *ngIf="initiator.showError('mutual_user', formDir, 'required')"
313 i18n>This field is required.</span>
315 <span class="help-block"
316 *ngIf="initiator.showError('mutual_user', formDir, 'pattern')"
317 i18n>Usernames must have a length of 8 to 64 characters and
318 can only contain letters, '.', '@', '-', '_' or ':'.</span>
322 <!-- Initiator: mutual_password -->
323 <div class="form-group"
324 [ngClass]="{'has-error': initiator.showError('mutual_password', formDir)}">
325 <label class="control-label col-sm-3"
326 for="mutual_password"
327 i18n>Mutual Password</label>
328 <div class="col-sm-9">
329 <div class="input-group">
330 <input id="mutual_password"
332 formControlName="mutual_password"
335 <span class="input-group-btn">
336 <button type="button"
337 class="btn btn-default"
338 cdPasswordButton="mutual_password">
340 <button type="button"
341 class="btn btn-default"
342 cdCopy2ClipboardButton="mutual_password">
346 <span class="help-block"
347 *ngIf="initiator.showError('mutual_password', formDir, 'required')"
348 i18n>This field is required.</span>
350 <span class="help-block"
351 *ngIf="initiator.showError('mutual_password', formDir, 'pattern')"
352 i18n>Passwords must have a length of 12 to 16 characters and
353 can only contain letters, '@', '-', '_' or '/'.</span>
358 <!-- Initiator: Images -->
359 <div class="form-group"
360 [ngClass]="{'has-error': initiator.showError('luns', formDir)}">
361 <label class="control-label col-sm-3"
364 <div class="col-sm-9">
365 <ng-container *ngFor="let image of initiator.getValue('luns'); let li = index">
366 <div class="input-group cd-mb">
367 <input class="form-control"
371 <span class="input-group-btn">
372 <button class="btn btn-default"
374 (click)="removeInitiatorImage(initiator, li, ii, image)">
375 <i class="fa fa-remove fa-fw"
376 aria-hidden="true"></i>
382 <span *ngIf="initiator.getValue('cdIsInGroup')"
383 i18n>Initiator belongs to a group. Images will be configure in the group.</span>
386 *ngIf="!initiator.getValue('cdIsInGroup')">
387 <div class="col-md-12">
388 <cd-select [data]="initiator.getValue('luns')"
389 [options]="imagesInitiatorSelections[ii]"
390 [messages]="messages.initiatorImage"
391 elemClass="btn btn-default pull-right">
392 <i class="fa fa-fw fa-plus"></i>
393 <ng-container i18n>Add image</ng-container>
403 <div class="col-md-12">
404 <span class="text-muted"
405 *ngIf="initiators.controls.length === 0"
406 i18n>No items added.</span>
408 <button (click)="addInitiator(); false"
409 class="btn btn-default pull-right">
410 <i class="fa fa-fw fa-plus"></i>
411 <ng-container i18n>Add initiator</ng-container>
421 <div class="form-group"
422 *ngIf="targetForm.getValue('acl_enabled')"
423 [ngClass]="{'has-error': targetForm.showError('groups', formDir)}">
424 <label class="control-label col-sm-3"
427 <div class="col-sm-9"
428 formArrayName="groups">
429 <div class="panel panel-default"
430 *ngFor="let group of groups.controls; let gi = index"
431 [formGroupName]="gi">
432 <div class="panel-heading">
433 <ng-container i18n>Group</ng-container>: {{ group.getValue('group_id') }}
434 <button type="button"
436 (click)="groups.removeAt(gi)">
437 <i class="fa fa-remove fa-fw"></i>
440 <div class="panel-body">
441 <!-- Group: group_id -->
442 <div class="form-group">
443 <label class="control-label col-sm-3"
445 <ng-container i18n>Name</ng-container>
446 <span class="required"></span>
448 <div class="col-sm-9">
449 <input class="form-control"
451 formControlName="group_id">
455 <!-- Group: members -->
456 <div class="form-group"
457 [ngClass]="{'has-error': group.showError('members', formDir)}">
458 <label class="control-label col-sm-3"
460 <ng-container i18n>Initiators</ng-container>
462 <div class="col-sm-9">
463 <ng-container *ngFor="let member of group.getValue('members'); let i = index">
464 <div class="input-group cd-mb">
465 <input class="form-control"
469 <span class="input-group-btn">
470 <button class="btn btn-default"
472 (click)="removeGroupInitiator(group, i, gi)">
473 <i class="fa fa-remove fa-fw"
474 aria-hidden="true"></i>
481 <div class="col-md-12">
482 <cd-select [data]="group.getValue('members')"
483 [options]="groupMembersSelections[gi]"
484 [messages]="messages.groupInitiator"
485 (selection)="onGroupMemberSelection($event)"
486 elemClass="btn btn-default pull-right">
487 <i class="fa fa-fw fa-plus"></i>
488 <ng-container i18n>Add initiator</ng-container>
497 <!-- Group: disks -->
498 <div class="form-group"
499 [ngClass]="{'has-error': group.showError('disks', formDir)}">
500 <label class="control-label col-sm-3"
502 <ng-container i18n>Images</ng-container>
504 <div class="col-sm-9">
505 <ng-container *ngFor="let disk of group.getValue('disks'); let i = index">
506 <div class="input-group cd-mb">
507 <input class="form-control"
511 <span class="input-group-btn">
512 <button class="btn btn-default"
514 (click)="removeGroupDisk(group, i, gi)">
515 <i class="fa fa-remove fa-fw"
516 aria-hidden="true"></i>
523 <div class="col-md-12">
524 <cd-select [data]="group.getValue('disks')"
525 [options]="groupDiskSelections[gi]"
526 [messages]="messages.initiatorImage"
527 elemClass="btn btn-default pull-right">
528 <i class="fa fa-fw fa-plus"></i>
529 <ng-container i18n>Add image</ng-container>
541 <div class="col-md-12">
542 <span class="text-muted"
543 *ngIf="groups.controls.length === 0"
544 i18n>No items added.</span>
546 <button (click)="addGroup(); false"
547 class="btn btn-default pull-right">
548 <i class="fa fa-fw fa-plus"></i>
549 <ng-container i18n>Add group</ng-container>
557 <div class="panel-footer">
558 <div class="button-group text-right">
559 <cd-submit-button [form]="formDir"
561 (submitAction)="submit()"
562 i18n>Submit</cd-submit-button>
563 <cd-back-button></cd-back-button>