]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
dc432a095fa833c31c6f843dbcaf6260c64832af
[ceph.git] /
1 <div class="cd-col-form"
2      *cdFormLoading="loading">
3   <form name="targetForm"
4         #formDir="ngForm"
5         [formGroup]="targetForm"
6         novalidate>
7     <div class="card">
8       <div i18n="form title|Example: Create Pool@@formTitle"
9            class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
10
11       <div class="card-body">
12         <!-- Target IQN -->
13         <div class="form-group row">
14           <label class="cd-col-form-label required"
15                  for="target_iqn"
16                  i18n>Target IQN</label>
17           <div class="cd-col-form-input">
18             <div class="input-group">
19               <input class="form-control"
20                      type="text"
21                      id="target_iqn"
22                      name="target_iqn"
23                      formControlName="target_iqn"
24                      cdTrim />
25               <span class="input-group-append">
26                 <button class="btn btn-light"
27                         id="ecp-info-button"
28                         type="button"
29                         (click)="targetSettingsModal()">
30                   <i [ngClass]="[icons.deepCheck]"
31                      aria-hidden="true"></i>
32                 </button>
33               </span>
34             </div>
35
36             <span class="invalid-feedback"
37                   *ngIf="targetForm.showError('target_iqn', formDir, 'required')"
38                   i18n>This field is required.</span>
39
40             <span class="invalid-feedback"
41                   *ngIf="targetForm.showError('target_iqn', formDir, 'pattern')"
42                   i18n>IQN has wrong pattern.</span>
43
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>
48               <br>
49               <ng-container i18n>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</ng-container>
50               <br>
51               <a target="_blank"
52                  href="https://en.wikipedia.org/wiki/ISCSI#Addressing"
53                  i18n>More information</a>
54             </span>
55
56             <span class="form-text text-muted"
57                   *ngIf="hasAdvancedSettings(targetForm.getValue('target_controls'))"
58                   i18n>This target has modified advanced settings.</span>
59             <hr />
60           </div>
61         </div>
62
63         <!-- Portals -->
64         <div class="form-group row">
65           <label class="cd-col-form-label required"
66                  for="portals"
67                  i18n>Portals</label>
68           <div class="cd-col-form-input">
69
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"
73                        type="text"
74                        [value]="portal"
75                        disabled />
76                 <span class="input-group-append">
77                   <button class="btn btn-light"
78                           type="button"
79                           (click)="removePortal(i, portal)">
80                     <i [ngClass]="[icons.destroy]"
81                        aria-hidden="true"></i>
82                   </button>
83                 </span>
84               </div>
85             </ng-container>
86
87             <div class="row">
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>
96                 </cd-select>
97               </div>
98             </div>
99
100             <input class="form-control"
101                    type="hidden"
102                    id="portals"
103                    name="portals"
104                    formControlName="portals" />
105
106             <span class="invalid-feedback"
107                   *ngIf="targetForm.showError('portals', formDir, 'minGateways')"
108                   i18n>At least {{ minimum_gateways }} gateways are required.</span>
109
110             <hr />
111           </div>
112         </div>
113
114         <!-- Images -->
115         <div class="form-group row">
116           <label class="cd-col-form-label"
117                  for="disks"
118                  i18n>Images</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"
123                        type="text"
124                        [value]="image"
125                        disabled />
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"
130                           type="button"
131                           (click)="imageSettingsModal(image)">
132                     <i [ngClass]="[icons.deepCheck]"
133                        aria-hidden="true"></i>
134                   </button>
135                   <button class="btn btn-light"
136                           type="button"
137                           (click)="removeImage(i, image)">
138                     <i [ngClass]="[icons.destroy]"
139                        aria-hidden="true"></i>
140                   </button>
141                 </span>
142
143               </div>
144
145               <span class="form-text text-muted">
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             <input class="form-control"
155                    type="hidden"
156                    id="disks"
157                    name="disks"
158                    formControlName="disks" />
159
160             <span class="invalid-feedback"
161                   *ngIf="targetForm.showError('disks', formDir, 'dupLunId')"
162                   i18n>Duplicated LUN numbers.</span>
163
164             <span class="invalid-feedback"
165                   *ngIf="targetForm.showError('disks', formDir, 'dupWwn')"
166                   i18n>Duplicated WWN.</span>
167
168             <div class="row">
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>
177                 </cd-select>
178               </div>
179             </div>
180
181             <hr />
182           </div>
183         </div>
184
185         <!-- acl_enabled -->
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"
192                      name="acl_enabled"
193                      id="acl_enabled">
194               <label for="acl_enabled"
195                      class="custom-control-label"
196                      i18n>ACL authentication</label>
197             </div>
198
199             <hr />
200           </div>
201         </div>
202
203         <!-- Target level authentication was introduced in ceph-iscsi config v11 -->
204         <div formGroupName="auth"
205              *ngIf="cephIscsiConfigVersion > 10 && !targetForm.getValue('acl_enabled')">
206
207           <!-- Target user -->
208           <div class="form-group row">
209             <label class="cd-col-form-label"
210                    for="target_user">
211               <ng-container i18n>User</ng-container>
212             </label>
213             <div class="cd-col-form-input">
214               <input class="form-control"
215                      type="text"
216                      id="target_user"
217                      name="target_user"
218                      formControlName="user" />
219
220               <span class="invalid-feedback"
221                     *ngIf="targetForm.showError('user', formDir, 'required')"
222                     i18n>This field is required.</span>
223
224               <span class="invalid-feedback"
225                     *ngIf="targetForm.showError('user', formDir, 'pattern')"
226                     i18n>User names must have a length of 8 to 64 characters and can contain
227                 alphanumeric characters, '.', '@', '-', '_' or ':'.</span>
228             </div>
229           </div>
230
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>
236             </label>
237             <div class="cd-col-form-input">
238               <div class="input-group">
239                 <input class="form-control"
240                        type="password"
241                        autocomplete="new-password"
242                        id="target_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">
249                   </button>
250                   <button type="button"
251                           class="btn btn-light"
252                           cdCopy2ClipboardButton="target_password">
253                   </button>
254                 </span>
255               </div>
256
257               <span class="invalid-feedback"
258                     *ngIf="targetForm.showError('password', formDir, 'required')"
259                     i18n>This field is required.</span>
260
261               <span class="invalid-feedback"
262                     *ngIf="targetForm.showError('password', formDir, 'pattern')"
263                     i18n>Passwords must have a length of 12 to 16 characters and can contain
264                 alphanumeric characters, '@', '-', '_' or '/'.</span>
265             </div>
266           </div>
267
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>
273             </label>
274             <div class="cd-col-form-input">
275               <input class="form-control"
276                      type="text"
277                      id="target_mutual_user"
278                      name="target_mutual_user"
279                      formControlName="mutual_user" />
280
281               <span class="invalid-feedback"
282                     *ngIf="targetForm.showError('mutual_user', formDir, 'required')"
283                     i18n>This field is required.</span>
284
285               <span class="invalid-feedback"
286                     *ngIf="targetForm.showError('mutual_user', formDir, 'pattern')"
287                     i18n>User names must have a length of 8 to 64 characters and can contain
288                 alphanumeric characters, '.', '@', '-', '_' or ':'.</span>
289             </div>
290           </div>
291
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>
297             </label>
298             <div class="cd-col-form-input">
299               <div class="input-group">
300                 <input class="form-control"
301                        type="password"
302                        autocomplete="new-password"
303                        id="target_mutual_password"
304                        name="target_mutual_password"
305                        formControlName="mutual_password" />
306
307                 <span class="input-group-append">
308                   <button type="button"
309                           class="btn btn-light"
310                           cdPasswordButton="target_mutual_password">
311                   </button>
312                   <button type="button"
313                           class="btn btn-light"
314                           cdCopy2ClipboardButton="target_mutual_password">
315                   </button>
316                 </span>
317               </div>
318
319               <span class="invalid-feedback"
320                     *ngIf="targetForm.showError('mutual_password', formDir, 'required')"
321                     i18n>This field is required.</span>
322
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 and can contain
326                 alphanumeric characters, '@', '-', '_' or '/'.</span>
327             </div>
328           </div>
329
330         </div>
331
332         <!-- Initiators -->
333         <div class="form-group row"
334              *ngIf="targetForm.getValue('acl_enabled')">
335           <label class="cd-col-form-label"
336                  for="initiators"
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"
346                         class="close"
347                         (click)="removeInitiator(ii)">
348                   <i [ngClass]="[icons.destroy]"></i>
349                 </button>
350               </div>
351               <div class="card-body">
352                 <!-- Initiator: Name -->
353                 <div class="form-group row">
354                   <label class="cd-col-form-label required"
355                          for="client_iqn"
356                          i18n>Client IQN</label>
357                   <div class="cd-col-form-input">
358                     <input class="form-control"
359                            type="text"
360                            formControlName="client_iqn"
361                            cdTrim
362                            (blur)="updatedInitiatorSelector()">
363
364                     <span class="invalid-feedback"
365                           *ngIf="initiator.showError('client_iqn', formDir, 'notUnique')"
366                           i18n>Initiator IQN needs to be unique.</span>
367
368                     <span class="invalid-feedback"
369                           *ngIf="initiator.showError('client_iqn', formDir, 'required')"
370                           i18n>This field is required.</span>
371
372                     <span class="invalid-feedback"
373                           *ngIf="initiator.showError('client_iqn', formDir, 'pattern')"
374                           i18n>IQN has wrong pattern.</span>
375                   </div>
376                 </div>
377
378                 <ng-container formGroupName="auth">
379                   <!-- Initiator: User -->
380                   <div class="form-group row">
381                     <label class="cd-col-form-label"
382                            for="user"
383                            i18n>User</label>
384                     <div class="cd-col-form-input">
385                       <input [id]="'user' + ii"
386                              class="form-control"
387                              formControlName="user"
388                              type="text">
389                       <span class="invalid-feedback"
390                             *ngIf="initiator.showError('user', formDir, 'required')"
391                             i18n>This field is required.</span>
392
393                       <span class="invalid-feedback"
394                             *ngIf="initiator.showError('user', formDir, 'pattern')"
395                             i18n>User names must have a length of 8 to 64 characters and can contain
396                         alphanumeric characters, '.', '@', '-', '_' or ':'.</span>
397                     </div>
398                   </div>
399
400                   <!-- Initiator: Password -->
401                   <div class="form-group row">
402                     <label class="cd-col-form-label"
403                            for="password"
404                            i18n>Password</label>
405                     <div class="cd-col-form-input">
406                       <div class="input-group">
407                         <input [id]="'password' + ii"
408                                class="form-control"
409                                formControlName="password"
410                                type="password">
411
412                         <span class="input-group-append">
413                           <button type="button"
414                                   class="btn btn-light"
415                                   [cdPasswordButton]="'password' + ii">
416                           </button>
417                           <button type="button"
418                                   class="btn btn-light"
419                                   [cdCopy2ClipboardButton]="'password' + ii">
420                           </button>
421                         </span>
422                       </div>
423                       <span class="invalid-feedback"
424                             *ngIf="initiator.showError('password', formDir, 'required')"
425                             i18n>This field is required.</span>
426
427                       <span class="invalid-feedback"
428                             *ngIf="initiator.showError('password', formDir, 'pattern')"
429                             i18n>Passwords must have a length of 12 to 16 characters and can contain
430                         alphanumeric characters, '@', '-', '_' or '/'.</span>
431                     </div>
432                   </div>
433
434
435                   <!-- Initiator: mutual_user -->
436                   <div class="form-group row">
437                     <label class="cd-col-form-label"
438                            for="mutual_user">
439                       <ng-container i18n>Mutual User</ng-container>
440                     </label>
441                     <div class="cd-col-form-input">
442                       <input [id]="'mutual_user' + ii"
443                              class="form-control"
444                              formControlName="mutual_user"
445                              type="text">
446
447                       <span class="invalid-feedback"
448                             *ngIf="initiator.showError('mutual_user', formDir, 'required')"
449                             i18n>This field is required.</span>
450
451                       <span class="invalid-feedback"
452                             *ngIf="initiator.showError('mutual_user', formDir, 'pattern')"
453                             i18n>User names must have a length of 8 to 64 characters and can contain
454                         alphanumeric characters, '.', '@', '-', '_' or ':'.</span>
455                     </div>
456                   </div>
457
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"
466                                class="form-control"
467                                formControlName="mutual_password"
468                                type="password">
469
470                         <span class="input-group-append">
471                           <button type="button"
472                                   class="btn btn-light"
473                                   [cdPasswordButton]="'mutual_password' + ii">
474                           </button>
475                           <button type="button"
476                                   class="btn btn-light"
477                                   [cdCopy2ClipboardButton]="'mutual_password' + ii">
478                           </button>
479                         </span>
480                       </div>
481                       <span class="invalid-feedback"
482                             *ngIf="initiator.showError('mutual_password', formDir, 'required')"
483                             i18n>This field is required.</span>
484
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 can contain
488                         alphanumeric characters, '@', '-', '_' or '/'.</span>
489                     </div>
490                   </div>
491                 </ng-container>
492
493                 <!-- Initiator: Images -->
494                 <div class="form-group row">
495                   <label class="cd-col-form-label"
496                          for="luns"
497                          i18n>Images</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"
502                                type="text"
503                                [value]="image"
504                                disabled />
505                         <span class="input-group-append">
506                           <button class="btn btn-light"
507                                   type="button"
508                                   (click)="removeInitiatorImage(initiator, li, ii, image)">
509                             <i [ngClass]="[icons.destroy]"
510                                aria-hidden="true"></i>
511                           </button>
512                         </span>
513                       </div>
514                     </ng-container>
515
516                     <span *ngIf="initiator.getValue('cdIsInGroup')"
517                           i18n>Initiator belongs to a group. Images will be configure in the group.</span>
518
519                     <div class="row"
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>
528                         </cd-select>
529                       </div>
530                     </div>
531                   </div>
532                 </div>
533               </div>
534             </div>
535
536             <div class="row">
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>
541
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>
546                 </button>
547               </div>
548             </div>
549
550             <hr />
551           </div>
552         </div>
553
554         <!-- Groups -->
555         <div class="form-group row"
556              *ngIf="targetForm.getValue('acl_enabled')">
557           <label class="cd-col-form-label"
558                  for="initiators"
559                  i18n>Groups</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"
568                         class="close"
569                         (click)="groups.removeAt(gi)">
570                   <i [ngClass]="[icons.destroy]"></i>
571                 </button>
572               </div>
573               <div class="card-body">
574                 <!-- Group: group_id -->
575                 <div class="form-group row">
576                   <label class="cd-col-form-label required"
577                          for="group_id"
578                          i18n>Name</label>
579                   <div class="cd-col-form-input">
580                     <input class="form-control"
581                            type="text"
582                            formControlName="group_id">
583                   </div>
584                 </div>
585
586                 <!-- Group: members -->
587                 <div class="form-group row">
588                   <label class="cd-col-form-label"
589                          for="members">
590                     <ng-container i18n>Initiators</ng-container>
591                   </label>
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"
596                                type="text"
597                                [value]="member"
598                                disabled />
599                         <span class="input-group-append">
600                           <button class="btn btn-light"
601                                   type="button"
602                                   (click)="removeGroupInitiator(group, i, gi)">
603                             <i [ngClass]="[icons.destroy]"
604                                aria-hidden="true"></i>
605                           </button>
606                         </span>
607                       </div>
608                     </ng-container>
609
610                     <div class="row">
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>
619                         </cd-select>
620                       </div>
621                     </div>
622
623                     <hr />
624                   </div>
625                 </div>
626
627                 <!-- Group: disks -->
628                 <div class="form-group row">
629                   <label class="cd-col-form-label"
630                          for="disks">
631                     <ng-container i18n>Images</ng-container>
632                   </label>
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"
637                                type="text"
638                                [value]="disk"
639                                disabled />
640                         <span class="input-group-append">
641                           <button class="btn btn-light"
642                                   type="button"
643                                   (click)="removeGroupDisk(group, i, gi)">
644                             <i [ngClass]="[icons.destroy]"
645                                aria-hidden="true"></i>
646                           </button>
647                         </span>
648                       </div>
649                     </ng-container>
650
651                     <div class="row">
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>
659                         </cd-select>
660                       </div>
661                     </div>
662
663                     <hr />
664                   </div>
665                 </div>
666               </div>
667             </div>
668
669             <div class="row">
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>
674
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>
679                 </button>
680               </div>
681             </div>
682           </div>
683         </div>
684
685       </div>
686       <div class="card-footer">
687         <div class="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>
692         </div>
693       </div>
694     </div>
695   </form>
696 </div>