]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/blob
6944dda3c6f7afe2d231409dc8271a7d65512c12
[ceph.git] /
1 <div class="col-sm-12 col-lg-6">
2   <form name="targetForm"
3         class="form-horizontal"
4         #formDir="ngForm"
5         [formGroup]="targetForm"
6         novalidate
7         *ngIf="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>
12       </div>
13
14       <div class="panel-body">
15         <!-- Target IQN -->
16         <div class="form-group"
17              [ngClass]="{'has-error': targetForm.showError('target_iqn', formDir)}">
18           <label class="control-label col-sm-3"
19                  for="target_iqn">
20             <ng-container i18n>Target IQN</ng-container>
21             <span class="required"></span>
22           </label>
23           <div class="col-sm-9">
24             <div class="input-group">
25               <input class="form-control"
26                      type="text"
27                      id="target_iqn"
28                      name="target_iqn"
29                      formControlName="target_iqn" />
30               <span class="input-group-btn">
31                 <button class="btn btn-default"
32                         id="ecp-info-button"
33                         type="button"
34                         (click)="targetSettingsModal()">
35                   <i class="fa fa-cogs fa-fw"
36                      aria-hidden="true"></i>
37                 </button>
38               </span>
39             </div>
40
41             <span class="help-block"
42                   *ngIf="targetForm.showError('target_iqn', formDir, 'required')"
43                   i18n>This field is required.</span>
44
45             <span class="help-block"
46                   *ngIf="targetForm.showError('target_iqn', formDir, 'pattern')"
47                   i18n>IQN has wrong pattern.</span>
48
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>
52               <br>
53               <ng-container i18n>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</ng-container>
54               <br>
55               <a target="_blank"
56                  href="https://en.wikipedia.org/wiki/ISCSI#Addressing"
57                  i18n>More information</a>
58             </span>
59
60             <span class="help-block"
61                   *ngIf="hasAdvancedSettings(targetForm.getValue('target_controls'))"
62                   i18n>This target has modified advanced settings.</span>
63             <hr />
64           </div>
65         </div>
66
67         <!-- Portals -->
68         <div class="form-group"
69              [ngClass]="{'has-error': targetForm.showError('portals', formDir)}">
70           <label class="control-label col-sm-3"
71                  for="portals">
72             <ng-container i18n>Portals</ng-container>
73             <span class="required"></span>
74           </label>
75           <div class="col-sm-9">
76
77             <ng-container *ngFor="let portal of portals.value; let i = index">
78               <div class="input-group cd-mb">
79                 <input class="form-control"
80                        type="text"
81                        [value]="portal"
82                        disabled />
83                 <span class="input-group-btn">
84                   <button class="btn btn-default"
85                           type="button"
86                           (click)="removePortal(i, portal)">
87                     <i class="fa fa-remove fa-fw"
88                        aria-hidden="true"></i>
89                   </button>
90                 </span>
91               </div>
92             </ng-container>
93
94             <span class="help-block"
95                   *ngIf="targetForm.showError('portals', formDir, 'minGateways')"
96                   i18n>At least {{ minimum_gateways }} gateways are required.</span>
97
98             <div class="row">
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>
107                 </cd-select>
108               </div>
109             </div>
110
111             <hr />
112           </div>
113         </div>
114
115         <!-- Images -->
116         <div class="form-group"
117              [ngClass]="{'has-error': targetForm.showError('disks', formDir)}">
118           <label class="control-label col-sm-3"
119                  for="disks"
120                  i18n>Images</label>
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"
125                        type="text"
126                        [value]="image"
127                        disabled />
128                 <span class="input-group-btn">
129                   <button class="btn btn-default"
130                           type="button"
131                           (click)="imageSettingsModal(image)">
132                     <i class="fa fa-cogs fa-fw"
133                        aria-hidden="true"></i>
134                   </button>
135                   <button class="btn btn-default"
136                           type="button"
137                           (click)="removeImage(i, image)">
138                     <i class="fa fa-remove fa-fw"
139                        aria-hidden="true"></i>
140                   </button>
141                 </span>
142
143               </div>
144
145               <span class="help-block">
146                 <ng-container *ngIf="backstores.length > 1"
147                               i18n>Backstore: {{ imagesSettings[image].backstore | iscsiBackstore }}.&nbsp;</ng-container>
148
149                 <ng-container *ngIf="hasAdvancedSettings(imagesSettings[image][imagesSettings[image].backstore])"
150                               i18n>This image has modified settings.</ng-container>
151               </span>
152             </ng-container>
153
154             <span class="help-block"
155                   *ngIf="targetForm.showError('disks', formDir, 'required')"
156                   i18n>At least 1 image is required.</span>
157
158             <div class="row">
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>
167                 </cd-select>
168               </div>
169             </div>
170
171             <hr />
172           </div>
173         </div>
174
175         <!-- acl_enabled -->
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"
181                      name="acl_enabled"
182                      id="acl_enabled">
183               <label for="acl_enabled"
184                      i18n>ACL authentication</label>
185             </div>
186
187             <hr />
188           </div>
189         </div>
190
191         <!-- Target level authentication was introduced in ceph-iscsi config v11 -->
192         <div formGroupName="auth" *ngIf="cephIscsiConfigVersion > 10 && !targetForm.getValue('acl_enabled')">
193
194           <!-- Target user -->
195           <div class="form-group"
196                [ngClass]="{'has-error': targetForm.showError('user', formDir)}">
197             <label class="control-label col-sm-3"
198                    for="target_user">
199               <ng-container i18n>User</ng-container>
200             </label>
201             <div class="col-sm-9">
202               <input class="form-control"
203                      type="text"
204                      id="target_user"
205                      name="target_user"
206                      formControlName="user" />
207
208               <span class="help-block"
209                     *ngIf="targetForm.showError('user', formDir, 'required')"
210                     i18n>This field is required.</span>
211
212               <span class="help-block"
213                     *ngIf="targetForm.showError('user', formDir, 'pattern')"
214                     i18n>Usernames must have a length of 8 to 64 characters and
215                 can only contain letters, '.', '@', '-', '_' or ':'.</span>
216             </div>
217           </div>
218
219           <!-- Target password -->
220           <div class="form-group"
221                [ngClass]="{'has-error': targetForm.showError('password', formDir)}">
222             <label class="control-label col-sm-3"
223                    for="target_password">
224               <ng-container i18n>Password</ng-container>
225             </label>
226             <div class="col-sm-9">
227               <div class="input-group">
228                 <input class="form-control"
229                        type="password"
230                        autocomplete="new-password"
231                        id="target_password"
232                        name="target_password"
233                        formControlName="password" />
234
235                 <span class="input-group-btn">
236                   <button type="button"
237                           class="btn btn-default"
238                           cdPasswordButton="target_password">
239                   </button>
240                   <button type="button"
241                           class="btn btn-default"
242                           cdCopy2ClipboardButton="target_password">
243                   </button>
244                 </span>
245               </div>
246
247               <span class="help-block"
248                     *ngIf="targetForm.showError('password', formDir, 'required')"
249                     i18n>This field is required.</span>
250
251               <span class="help-block"
252                     *ngIf="targetForm.showError('password', formDir, 'pattern')"
253                     i18n>Passwords must have a length of 12 to 16 characters
254                 and can only contain letters, '@', '-', '_' or '/'.</span>
255             </div>
256           </div>
257
258           <!-- Target mutual_user -->
259           <div class="form-group"
260                [ngClass]="{'has-error': targetForm.showError('mutual_user', formDir)}">
261             <label class="control-label col-sm-3"
262                    for="target_mutual_user">
263               <ng-container i18n>Mutual User</ng-container>
264             </label>
265             <div class="col-sm-9">
266               <input class="form-control"
267                      type="text"
268                      id="target_mutual_user"
269                      name="target_mutual_user"
270                      formControlName="mutual_user" />
271
272               <span class="help-block"
273                     *ngIf="targetForm.showError('mutual_user', formDir, 'required')"
274                     i18n>This field is required.</span>
275
276               <span class="help-block"
277                     *ngIf="targetForm.showError('mutual_user', formDir, 'pattern')"
278                     i18n>Usernames must have a length of 8 to 64 characters and
279                 can only contain letters, '.', '@', '-', '_' or ':'.</span>
280             </div>
281           </div>
282
283           <!-- Target mutual_password -->
284           <div class="form-group"
285                [ngClass]="{'has-error': targetForm.showError('mutual_password', formDir)}">
286             <label class="control-label col-sm-3"
287                    for="target_mutual_password">
288               <ng-container i18n>Mutual Password</ng-container>
289             </label>
290             <div class="col-sm-9">
291               <div class="input-group">
292                 <input class="form-control"
293                        type="password"
294                        autocomplete="new-password"
295                        id="target_mutual_password"
296                        name="target_mutual_password"
297                        formControlName="mutual_password" />
298
299                 <span class="input-group-btn">
300                   <button type="button"
301                           class="btn btn-default"
302                           cdPasswordButton="target_mutual_password">
303                   </button>
304                   <button type="button"
305                           class="btn btn-default"
306                           cdCopy2ClipboardButton="target_mutual_password">
307                   </button>
308                 </span>
309               </div>
310
311               <span class="help-block"
312                     *ngIf="targetForm.showError('mutual_password', formDir, 'required')"
313                     i18n>This field is required.</span>
314
315               <span class="help-block"
316                     *ngIf="targetForm.showError('mutual_password', formDir, 'pattern')"
317                     i18n>Passwords must have a length of 12 to 16 characters
318                 and can only contain letters, '@', '-', '_' or '/'.</span>
319             </div>
320           </div>
321
322         </div>
323
324         <!-- Initiators -->
325         <div class="form-group"
326              *ngIf="targetForm.getValue('acl_enabled')">
327           <label class="control-label col-sm-3"
328                  for="initiators"
329                  i18n>Initiators</label>
330           <div class="col-sm-9"
331                formArrayName="initiators">
332             <div class="panel panel-default"
333                  *ngFor="let initiator of initiators.controls; let ii = index"
334                  [formGroupName]="ii">
335               <div class="panel-heading">
336                 <ng-container i18n>Initiator</ng-container>: {{ initiator.getValue('client_iqn') }}
337                 <button type="button"
338                         class="close"
339                         (click)="removeInitiator(ii)">
340                   <i class="fa fa-remove fa-fw"></i>
341                 </button>
342               </div>
343               <div class="panel-body">
344                 <!-- Initiator: Name -->
345                 <div class="form-group"
346                      [ngClass]="{'has-error': initiator.showError('client_iqn', formDir)}">
347                   <label class="control-label col-sm-3"
348                          for="client_iqn">
349                     <ng-container i18n>Client IQN</ng-container>
350                     <span class="required"></span>
351                   </label>
352                   <div class="col-sm-9">
353                     <input class="form-control"
354                            type="text"
355                            formControlName="client_iqn"
356                            (blur)="updatedInitiatorSelector()">
357
358                     <span class="help-block"
359                           *ngIf="initiator.showError('client_iqn', formDir, 'notUnique')"
360                           i18n>Initiator IQN needs to be unique.</span>
361
362                     <span class="help-block"
363                           *ngIf="initiator.showError('client_iqn', formDir, 'required')"
364                           i18n>This field is required.</span>
365
366                     <span class="help-block"
367                           *ngIf="initiator.showError('client_iqn', formDir, 'pattern')"
368                           i18n>IQN has wrong pattern.</span>
369                   </div>
370                 </div>
371
372                 <ng-container formGroupName="auth">
373                   <!-- Initiator: User -->
374                   <div class="form-group"
375                        [ngClass]="{'has-error': initiator.showError('user', formDir)}">
376                     <label class="control-label col-sm-3"
377                            for="user"
378                            i18n>User</label>
379                     <div class="col-sm-9">
380                       <input [id]="'user' + ii"
381                              class="form-control"
382                              formControlName="user"
383                              type="text">
384                       <span class="help-block"
385                             *ngIf="initiator.showError('user', formDir, 'required')"
386                             i18n>This field is required.</span>
387
388                       <span class="help-block"
389                             *ngIf="initiator.showError('user', formDir, 'pattern')"
390                             i18n>Usernames must have a length of 8 to 64 characters and
391                         can only contain letters, '.', '@', '-', '_' or ':'.</span>
392                     </div>
393                   </div>
394
395                   <!-- Initiator: Password -->
396                   <div class="form-group"
397                        [ngClass]="{'has-error': initiator.showError('password', formDir)}">
398                     <label class="control-label col-sm-3"
399                            for="password"
400                            i18n>Password</label>
401                     <div class="col-sm-9">
402                       <div class="input-group">
403                         <input [id]="'password' + ii"
404                                class="form-control"
405                                formControlName="password"
406                                type="password">
407
408                         <span class="input-group-btn">
409                           <button type="button"
410                                   class="btn btn-default"
411                                   [cdPasswordButton]="'password' + ii">
412                           </button>
413                           <button type="button"
414                                   class="btn btn-default"
415                                   [cdCopy2ClipboardButton]="'password' + ii">
416                           </button>
417                         </span>
418                       </div>
419                       <span class="help-block"
420                             *ngIf="initiator.showError('password', formDir, 'required')"
421                             i18n>This field is required.</span>
422
423                       <span class="help-block"
424                             *ngIf="initiator.showError('password', formDir, 'pattern')"
425                             i18n>Passwords must have a length of 12 to 16 characters
426                         and can only contain letters, '@', '-', '_' or '/'.</span>
427                     </div>
428                   </div>
429
430
431                   <!-- Initiator: mutual_user -->
432                   <div class="form-group"
433                        [ngClass]="{'has-error': initiator.showError('mutual_user', formDir)}">
434                     <label class="control-label col-sm-3"
435                            for="mutual_user">
436                       <ng-container i18n>Mutual User</ng-container>
437                     </label>
438                     <div class="col-sm-9">
439                       <input [id]="'mutual_user' + ii"
440                              class="form-control"
441                              formControlName="mutual_user"
442                              type="text">
443
444                       <span class="help-block"
445                             *ngIf="initiator.showError('mutual_user', formDir, 'required')"
446                             i18n>This field is required.</span>
447
448                       <span class="help-block"
449                             *ngIf="initiator.showError('mutual_user', formDir, 'pattern')"
450                             i18n>Usernames must have a length of 8 to 64 characters and
451                         can only contain letters, '.', '@', '-', '_' or ':'.</span>
452                     </div>
453                   </div>
454
455                   <!-- Initiator: mutual_password -->
456                   <div class="form-group"
457                        [ngClass]="{'has-error': initiator.showError('mutual_password', formDir)}">
458                     <label class="control-label col-sm-3"
459                            for="mutual_password"
460                            i18n>Mutual Password</label>
461                     <div class="col-sm-9">
462                       <div class="input-group">
463                         <input [id]="'mutual_password' + ii"
464                                class="form-control"
465                                formControlName="mutual_password"
466                                type="password">
467
468                         <span class="input-group-btn">
469                           <button type="button"
470                                   class="btn btn-default"
471                                   [cdPasswordButton]="'mutual_password' + ii">
472                           </button>
473                           <button type="button"
474                                   class="btn btn-default"
475                                   [cdCopy2ClipboardButton]="'mutual_password' + ii">
476                           </button>
477                         </span>
478                       </div>
479                       <span class="help-block"
480                             *ngIf="initiator.showError('mutual_password', formDir, 'required')"
481                             i18n>This field is required.</span>
482
483                       <span class="help-block"
484                             *ngIf="initiator.showError('mutual_password', formDir, 'pattern')"
485                             i18n>Passwords must have a length of 12 to 16 characters and
486                         can only contain letters, '@', '-', '_' or '/'.</span>
487                     </div>
488                   </div>
489                 </ng-container>
490
491                 <!-- Initiator: Images -->
492                 <div class="form-group"
493                      [ngClass]="{'has-error': initiator.showError('luns', formDir)}">
494                   <label class="control-label col-sm-3"
495                          for="luns"
496                          i18n>Images</label>
497                   <div class="col-sm-9">
498                     <ng-container *ngFor="let image of initiator.getValue('luns'); let li = index">
499                       <div class="input-group cd-mb">
500                         <input class="form-control"
501                                type="text"
502                                [value]="image"
503                                disabled />
504                         <span class="input-group-btn">
505                           <button class="btn btn-default"
506                                   type="button"
507                                   (click)="removeInitiatorImage(initiator, li, ii, image)">
508                             <i class="fa fa-remove fa-fw"
509                                aria-hidden="true"></i>
510                           </button>
511                         </span>
512                       </div>
513                     </ng-container>
514
515                     <span *ngIf="initiator.getValue('cdIsInGroup')"
516                           i18n>Initiator belongs to a group. Images will be configure in the group.</span>
517
518                     <div class="row"
519                          *ngIf="!initiator.getValue('cdIsInGroup')">
520                       <div class="col-md-12">
521                         <cd-select [data]="initiator.getValue('luns')"
522                                    [options]="imagesInitiatorSelections[ii]"
523                                    [messages]="messages.initiatorImage"
524                                    elemClass="btn btn-default pull-right">
525                           <i class="fa fa-fw fa-plus"></i>
526                           <ng-container i18n>Add image</ng-container>
527                         </cd-select>
528                       </div>
529                     </div>
530                   </div>
531                 </div>
532               </div>
533             </div>
534
535             <div class="row">
536               <div class="col-md-12">
537                 <span class="text-muted"
538                       *ngIf="initiators.controls.length === 0"
539                       i18n>No items added.</span>
540
541                 <button (click)="addInitiator(); false"
542                         class="btn btn-default pull-right">
543                   <i class="fa fa-fw fa-plus"></i>
544                   <ng-container i18n>Add initiator</ng-container>
545                 </button>
546               </div>
547             </div>
548
549             <hr />
550           </div>
551         </div>
552
553         <!-- Groups -->
554         <div class="form-group"
555              *ngIf="targetForm.getValue('acl_enabled')"
556              [ngClass]="{'has-error': targetForm.showError('groups', formDir)}">
557           <label class="control-label col-sm-3"
558                  for="initiators"
559                  i18n>Groups</label>
560           <div class="col-sm-9"
561                formArrayName="groups">
562             <div class="panel panel-default"
563                  *ngFor="let group of groups.controls; let gi = index"
564                  [formGroupName]="gi">
565               <div class="panel-heading">
566                 <ng-container i18n>Group</ng-container>: {{ group.getValue('group_id') }}
567                 <button type="button"
568                         class="close"
569                         (click)="groups.removeAt(gi)">
570                   <i class="fa fa-remove fa-fw"></i>
571                 </button>
572               </div>
573               <div class="panel-body">
574                 <!-- Group: group_id -->
575                 <div class="form-group">
576                   <label class="control-label col-sm-3"
577                          for="group_id">
578                     <ng-container i18n>Name</ng-container>
579                     <span class="required"></span>
580                   </label>
581                   <div class="col-sm-9">
582                     <input class="form-control"
583                            type="text"
584                            formControlName="group_id">
585                   </div>
586                 </div>
587
588                 <!-- Group: members -->
589                 <div class="form-group"
590                      [ngClass]="{'has-error': group.showError('members', formDir)}">
591                   <label class="control-label col-sm-3"
592                          for="members">
593                     <ng-container i18n>Initiators</ng-container>
594                   </label>
595                   <div class="col-sm-9">
596                     <ng-container *ngFor="let member of group.getValue('members'); let i = index">
597                       <div class="input-group cd-mb">
598                         <input class="form-control"
599                                type="text"
600                                [value]="member"
601                                disabled />
602                         <span class="input-group-btn">
603                           <button class="btn btn-default"
604                                   type="button"
605                                   (click)="removeGroupInitiator(group, i, gi)">
606                             <i class="fa fa-remove fa-fw"
607                                aria-hidden="true"></i>
608                           </button>
609                         </span>
610                       </div>
611                     </ng-container>
612
613                     <div class="row">
614                       <div class="col-md-12">
615                         <cd-select [data]="group.getValue('members')"
616                                    [options]="groupMembersSelections[gi]"
617                                    [messages]="messages.groupInitiator"
618                                    (selection)="onGroupMemberSelection($event)"
619                                    elemClass="btn btn-default pull-right">
620                           <i class="fa fa-fw fa-plus"></i>
621                           <ng-container i18n>Add initiator</ng-container>
622                         </cd-select>
623                       </div>
624                     </div>
625
626                     <hr />
627                   </div>
628                 </div>
629
630                 <!-- Group: disks -->
631                 <div class="form-group"
632                      [ngClass]="{'has-error': group.showError('disks', formDir)}">
633                   <label class="control-label col-sm-3"
634                          for="disks">
635                     <ng-container i18n>Images</ng-container>
636                   </label>
637                   <div class="col-sm-9">
638                     <ng-container *ngFor="let disk of group.getValue('disks'); let i = index">
639                       <div class="input-group cd-mb">
640                         <input class="form-control"
641                                type="text"
642                                [value]="disk"
643                                disabled />
644                         <span class="input-group-btn">
645                           <button class="btn btn-default"
646                                   type="button"
647                                   (click)="removeGroupDisk(group, i, gi)">
648                             <i class="fa fa-remove fa-fw"
649                                aria-hidden="true"></i>
650                           </button>
651                         </span>
652                       </div>
653                     </ng-container>
654
655                     <div class="row">
656                       <div class="col-md-12">
657                         <cd-select [data]="group.getValue('disks')"
658                                    [options]="groupDiskSelections[gi]"
659                                    [messages]="messages.initiatorImage"
660                                    elemClass="btn btn-default pull-right">
661                           <i class="fa fa-fw fa-plus"></i>
662                           <ng-container i18n>Add image</ng-container>
663                         </cd-select>
664                       </div>
665                     </div>
666
667                     <hr />
668                   </div>
669                 </div>
670               </div>
671             </div>
672
673             <div class="row">
674               <div class="col-md-12">
675                 <span class="text-muted"
676                       *ngIf="groups.controls.length === 0"
677                       i18n>No items added.</span>
678
679                 <button (click)="addGroup(); false"
680                         class="btn btn-default pull-right">
681                   <i class="fa fa-fw fa-plus"></i>
682                   <ng-container i18n>Add group</ng-container>
683                 </button>
684               </div>
685             </div>
686           </div>
687         </div>
688
689       </div>
690       <div class="panel-footer">
691         <div class="button-group text-right">
692           <cd-submit-button
693             [form]="formDir"
694             (submitAction)="submit()"
695             i18n="form action button|Example: Create Pool@@formActionButton"
696             type="button">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
697           <cd-back-button></cd-back-button>
698         </div>
699       </div>
700     </div>
701   </form>
702 </div>