]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
2fc58ac5719e4fd107d72cea40550342a5b1d82d
[ceph-ci.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                      autocomplete="off"
217                      id="target_user"
218                      name="target_user"
219                      formControlName="user" />
220
221               <span class="invalid-feedback"
222                     *ngIf="targetForm.showError('user', formDir, 'required')"
223                     i18n>This field is required.</span>
224
225               <span class="invalid-feedback"
226                     *ngIf="targetForm.showError('user', formDir, 'pattern')"
227                     i18n>User names must have a length of 8 to 64 characters and can contain
228                 alphanumeric characters, '.', '@', '-', '_' or ':'.</span>
229             </div>
230           </div>
231
232           <!-- Target password -->
233           <div class="form-group row">
234             <label class="cd-col-form-label"
235                    for="target_password">
236               <ng-container i18n>Password</ng-container>
237             </label>
238             <div class="cd-col-form-input">
239               <div class="input-group">
240                 <input class="form-control"
241                        type="password"
242                        autocomplete="new-password"
243                        id="target_password"
244                        name="target_password"
245                        formControlName="password" />
246                 <span class="input-group-append">
247                   <button type="button"
248                           class="btn btn-light"
249                           cdPasswordButton="target_password">
250                   </button>
251                   <cd-copy-2-clipboard-button source="target_password">
252                   </cd-copy-2-clipboard-button>
253                 </span>
254               </div>
255
256               <span class="invalid-feedback"
257                     *ngIf="targetForm.showError('password', formDir, 'required')"
258                     i18n>This field is required.</span>
259
260               <span class="invalid-feedback"
261                     *ngIf="targetForm.showError('password', formDir, 'pattern')"
262                     i18n>Passwords must have a length of 12 to 16 characters and can contain
263                 alphanumeric characters, '@', '-', '_' or '/'.</span>
264             </div>
265           </div>
266
267           <!-- Target mutual_user -->
268           <div class="form-group row">
269             <label class="cd-col-form-label"
270                    for="target_mutual_user">
271               <ng-container i18n>Mutual User</ng-container>
272             </label>
273             <div class="cd-col-form-input">
274               <input class="form-control"
275                      type="text"
276                      autocomplete="off"
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                   <cd-copy-2-clipboard-button source="target_mutual_password">
313                   </cd-copy-2-clipboard-button>
314                 </span>
315               </div>
316
317               <span class="invalid-feedback"
318                     *ngIf="targetForm.showError('mutual_password', formDir, 'required')"
319                     i18n>This field is required.</span>
320
321               <span class="invalid-feedback"
322                     *ngIf="targetForm.showError('mutual_password', formDir, 'pattern')"
323                     i18n>Passwords must have a length of 12 to 16 characters and can contain
324                 alphanumeric characters, '@', '-', '_' or '/'.</span>
325             </div>
326           </div>
327
328         </div>
329
330         <!-- Initiators -->
331         <div class="form-group row"
332              *ngIf="targetForm.getValue('acl_enabled')">
333           <label class="cd-col-form-label"
334                  for="initiators"
335                  i18n>Initiators</label>
336           <div class="cd-col-form-input"
337                formArrayName="initiators">
338             <div class="card mb-2"
339                  *ngFor="let initiator of initiators.controls; let ii = index"
340                  [formGroupName]="ii">
341               <div class="card-header">
342                 <ng-container i18n>Initiator</ng-container>: {{ initiator.getValue('client_iqn') }}
343                 <button type="button"
344                         class="close"
345                         (click)="removeInitiator(ii)">
346                   <i [ngClass]="[icons.destroy]"></i>
347                 </button>
348               </div>
349               <div class="card-body">
350                 <!-- Initiator: Name -->
351                 <div class="form-group row">
352                   <label class="cd-col-form-label required"
353                          for="client_iqn"
354                          i18n>Client IQN</label>
355                   <div class="cd-col-form-input">
356                     <input class="form-control"
357                            type="text"
358                            formControlName="client_iqn"
359                            cdTrim
360                            (blur)="updatedInitiatorSelector()">
361
362                     <span class="invalid-feedback"
363                           *ngIf="initiator.showError('client_iqn', formDir, 'notUnique')"
364                           i18n>Initiator IQN needs to be unique.</span>
365
366                     <span class="invalid-feedback"
367                           *ngIf="initiator.showError('client_iqn', formDir, 'required')"
368                           i18n>This field is required.</span>
369
370                     <span class="invalid-feedback"
371                           *ngIf="initiator.showError('client_iqn', formDir, 'pattern')"
372                           i18n>IQN has wrong pattern.</span>
373                   </div>
374                 </div>
375
376                 <ng-container formGroupName="auth">
377                   <!-- Initiator: User -->
378                   <div class="form-group row">
379                     <label class="cd-col-form-label"
380                            for="user"
381                            i18n>User</label>
382                     <div class="cd-col-form-input">
383                       <input [id]="'user' + ii"
384                              class="form-control"
385                              formControlName="user"
386                              autocomplete="off"
387                              type="text">
388                       <span class="invalid-feedback"
389                             *ngIf="initiator.showError('user', formDir, 'required')"
390                             i18n>This field is required.</span>
391
392                       <span class="invalid-feedback"
393                             *ngIf="initiator.showError('user', formDir, 'pattern')"
394                             i18n>User names must have a length of 8 to 64 characters and can contain
395                         alphanumeric characters, '.', '@', '-', '_' or ':'.</span>
396                     </div>
397                   </div>
398
399                   <!-- Initiator: Password -->
400                   <div class="form-group row">
401                     <label class="cd-col-form-label"
402                            for="password"
403                            i18n>Password</label>
404                     <div class="cd-col-form-input">
405                       <div class="input-group">
406                         <input [id]="'password' + ii"
407                                class="form-control"
408                                formControlName="password"
409                                autocomplete="new-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                           <cd-copy-2-clipboard-button [source]="'password' + ii">
418                           </cd-copy-2-clipboard-button>
419                         </span>
420                       </div>
421                       <span class="invalid-feedback"
422                             *ngIf="initiator.showError('password', formDir, 'required')"
423                             i18n>This field is required.</span>
424
425                       <span class="invalid-feedback"
426                             *ngIf="initiator.showError('password', formDir, 'pattern')"
427                             i18n>Passwords must have a length of 12 to 16 characters and can contain
428                         alphanumeric characters, '@', '-', '_' or '/'.</span>
429                     </div>
430                   </div>
431
432
433                   <!-- Initiator: mutual_user -->
434                   <div class="form-group row">
435                     <label class="cd-col-form-label"
436                            for="mutual_user">
437                       <ng-container i18n>Mutual User</ng-container>
438                     </label>
439                     <div class="cd-col-form-input">
440                       <input [id]="'mutual_user' + ii"
441                              class="form-control"
442                              formControlName="mutual_user"
443                              autocomplete="off"
444                              type="text">
445
446                       <span class="invalid-feedback"
447                             *ngIf="initiator.showError('mutual_user', formDir, 'required')"
448                             i18n>This field is required.</span>
449
450                       <span class="invalid-feedback"
451                             *ngIf="initiator.showError('mutual_user', formDir, 'pattern')"
452                             i18n>User names must have a length of 8 to 64 characters and can contain
453                         alphanumeric characters, '.', '@', '-', '_' or ':'.</span>
454                     </div>
455                   </div>
456
457                   <!-- Initiator: mutual_password -->
458                   <div class="form-group row">
459                     <label class="cd-col-form-label"
460                            for="mutual_password"
461                            i18n>Mutual Password</label>
462                     <div class="cd-col-form-input">
463                       <div class="input-group">
464                         <input [id]="'mutual_password' + ii"
465                                class="form-control"
466                                formControlName="mutual_password"
467                                autocomplete="new-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                           <cd-copy-2-clipboard-button [source]="'mutual_password' + ii">
476                           </cd-copy-2-clipboard-button>
477                         </span>
478                       </div>
479                       <span class="invalid-feedback"
480                             *ngIf="initiator.showError('mutual_password', formDir, 'required')"
481                             i18n>This field is required.</span>
482
483                       <span class="invalid-feedback"
484                             *ngIf="initiator.showError('mutual_password', formDir, 'pattern')"
485                             i18n>Passwords must have a length of 12 to 16 characters and can contain
486                         alphanumeric characters, '@', '-', '_' or '/'.</span>
487                     </div>
488                   </div>
489                 </ng-container>
490
491                 <!-- Initiator: Images -->
492                 <div class="form-group row">
493                   <label class="cd-col-form-label"
494                          for="luns"
495                          i18n>Images</label>
496                   <div class="cd-col-form-input">
497                     <ng-container *ngFor="let image of initiator.getValue('luns'); let li = index">
498                       <div class="input-group cd-mb">
499                         <input class="cd-form-control"
500                                type="text"
501                                [value]="image"
502                                disabled />
503                         <span class="input-group-append">
504                           <button class="btn btn-light"
505                                   type="button"
506                                   (click)="removeInitiatorImage(initiator, li, ii, image)">
507                             <i [ngClass]="[icons.destroy]"
508                                aria-hidden="true"></i>
509                           </button>
510                         </span>
511                       </div>
512                     </ng-container>
513
514                     <span *ngIf="initiator.getValue('cdIsInGroup')"
515                           i18n>Initiator belongs to a group. Images will be configure in the group.</span>
516
517                     <div class="row"
518                          *ngIf="!initiator.getValue('cdIsInGroup')">
519                       <div class="col-md-12">
520                         <cd-select [data]="initiator.getValue('luns')"
521                                    [options]="imagesInitiatorSelections[ii]"
522                                    [messages]="messages.initiatorImage"
523                                    elemClass="btn btn-light float-right">
524                           <i [ngClass]="[icons.add]"></i>
525                           <ng-container i18n>Add image</ng-container>
526                         </cd-select>
527                       </div>
528                     </div>
529                   </div>
530                 </div>
531               </div>
532             </div>
533
534             <div class="row">
535               <div class="col-md-12">
536                 <span class="form-text text-muted"
537                       *ngIf="initiators.controls.length === 0"
538                       i18n>No items added.</span>
539
540                 <button (click)="addInitiator(); false"
541                         class="btn btn-light float-right">
542                   <i [ngClass]="[icons.add]"></i>
543                   <ng-container i18n>Add initiator</ng-container>
544                 </button>
545               </div>
546             </div>
547
548             <hr />
549           </div>
550         </div>
551
552         <!-- Groups -->
553         <div class="form-group row"
554              *ngIf="targetForm.getValue('acl_enabled')">
555           <label class="cd-col-form-label"
556                  for="initiators"
557                  i18n>Groups</label>
558           <div class="cd-col-form-input"
559                formArrayName="groups">
560             <div class="card mb-2"
561                  *ngFor="let group of groups.controls; let gi = index"
562                  [formGroupName]="gi">
563               <div class="card-header">
564                 <ng-container i18n>Group</ng-container>: {{ group.getValue('group_id') }}
565                 <button type="button"
566                         class="close"
567                         (click)="removeGroup(gi)">
568                   <i [ngClass]="[icons.destroy]"></i>
569                 </button>
570               </div>
571               <div class="card-body">
572                 <!-- Group: group_id -->
573                 <div class="form-group row">
574                   <label class="cd-col-form-label required"
575                          for="group_id"
576                          i18n>Name</label>
577                   <div class="cd-col-form-input">
578                     <input class="form-control"
579                            type="text"
580                            formControlName="group_id">
581                   </div>
582                 </div>
583
584                 <!-- Group: members -->
585                 <div class="form-group row">
586                   <label class="cd-col-form-label"
587                          for="members">
588                     <ng-container i18n>Initiators</ng-container>
589                   </label>
590                   <div class="cd-col-form-input">
591                     <ng-container *ngFor="let member of group.getValue('members'); let i = index">
592                       <div class="input-group cd-mb">
593                         <input class="cd-form-control"
594                                type="text"
595                                [value]="member"
596                                disabled />
597                         <span class="input-group-append">
598                           <button class="btn btn-light"
599                                   type="button"
600                                   (click)="removeGroupInitiator(group, i, gi)">
601                             <i [ngClass]="[icons.destroy]"
602                                aria-hidden="true"></i>
603                           </button>
604                         </span>
605                       </div>
606                     </ng-container>
607
608                     <div class="row">
609                       <div class="col-md-12">
610                         <cd-select [data]="group.getValue('members')"
611                                    [options]="groupMembersSelections[gi]"
612                                    [messages]="messages.groupInitiator"
613                                    (selection)="onGroupMemberSelection($event, gi)"
614                                    elemClass="btn btn-light float-right">
615                           <i [ngClass]="[icons.add]"></i>
616                           <ng-container i18n>Add initiator</ng-container>
617                         </cd-select>
618                       </div>
619                     </div>
620
621                     <hr />
622                   </div>
623                 </div>
624
625                 <!-- Group: disks -->
626                 <div class="form-group row">
627                   <label class="cd-col-form-label"
628                          for="disks">
629                     <ng-container i18n>Images</ng-container>
630                   </label>
631                   <div class="cd-col-form-input">
632                     <ng-container *ngFor="let disk of group.getValue('disks'); let i = index">
633                       <div class="input-group cd-mb">
634                         <input class="cd-form-control"
635                                type="text"
636                                [value]="disk"
637                                disabled />
638                         <span class="input-group-append">
639                           <button class="btn btn-light"
640                                   type="button"
641                                   (click)="removeGroupDisk(group, i, gi)">
642                             <i [ngClass]="[icons.destroy]"
643                                aria-hidden="true"></i>
644                           </button>
645                         </span>
646                       </div>
647                     </ng-container>
648
649                     <div class="row">
650                       <div class="col-md-12">
651                         <cd-select [data]="group.getValue('disks')"
652                                    [options]="groupDiskSelections[gi]"
653                                    [messages]="messages.initiatorImage"
654                                    elemClass="btn btn-light float-right">
655                           <i [ngClass]="[icons.add]"></i>
656                           <ng-container i18n>Add image</ng-container>
657                         </cd-select>
658                       </div>
659                     </div>
660
661                     <hr />
662                   </div>
663                 </div>
664               </div>
665             </div>
666
667             <div class="row">
668               <div class="col-md-12">
669                 <span class="form-text text-muted"
670                       *ngIf="groups.controls.length === 0"
671                       i18n>No items added.</span>
672
673                 <button (click)="addGroup(); false"
674                         class="btn btn-light float-right">
675                   <i [ngClass]="[icons.add]"></i>
676                   <ng-container i18n>Add group</ng-container>
677                 </button>
678               </div>
679             </div>
680           </div>
681         </div>
682
683       </div>
684       <div class="card-footer">
685         <cd-form-button-panel (submitActionEvent)="submit()"
686                               [form]="targetForm"
687                               [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
688                               wrappingClass="text-right"></cd-form-button-panel>
689       </div>
690     </div>
691   </form>
692 </div>