]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
62333d3391b747a7a06d821b18df092641f6e645
[ceph-ci.git] /
1 <cd-modal [pageURL]="pageURL"
2           [modalRef]="activeModal">
3   <span class="modal-title"
4         i18n>{{ action | titlecase }} {{ resource | upperFirst }}</span>
5   <ng-container class="modal-content">
6     <form #frm="ngForm"
7           [formGroup]="serviceForm"
8           novalidate>
9       <div class="modal-body">
10         <cd-alert-panel *ngIf="serviceForm.controls.service_type.value === 'rgw' && showRealmCreationForm"
11                         type="info"
12                         spacingClass="mb-3"
13                         i18n>
14           <a class="text-decoration-underline"
15              (click)="createMultisiteSetup()">
16              Click here</a> to create a new Realm/Zone Group/Zone
17         </cd-alert-panel>
18
19         <!-- Service type -->
20         <div class="form-group row">
21           <label class="cd-col-form-label required"
22                  for="service_type"
23                  i18n>Type</label>
24           <div class="cd-col-form-input">
25             <select id="service_type"
26                     name="service_type"
27                     class="form-select"
28                     formControlName="service_type"
29                     (change)="onServiceTypeChange($event.target.value)">
30               <option i18n
31                       [ngValue]="null">-- Select a service type --</option>
32               <option *ngFor="let serviceType of serviceTypes"
33                       [value]="serviceType">
34                 {{ serviceType }}
35               </option>
36             </select>
37             <span class="invalid-feedback"
38                   *ngIf="serviceForm.showError('service_type', frm, 'required')"
39                   i18n>This field is required.</span>
40           </div>
41         </div>
42
43         <!-- backend_service -->
44         <div *ngIf="serviceForm.controls.service_type.value === 'ingress'"
45              class="form-group row">
46           <label i18n
47                  class="cd-col-form-label"
48                  [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
49                  for="backend_service">Backend Service</label>
50           <div class="cd-col-form-input">
51             <select id="backend_service"
52                     name="backend_service"
53                     class="form-select"
54                     formControlName="backend_service"
55                     (change)="prePopulateId()">
56               <option *ngIf="services === null"
57                       [ngValue]="null"
58                       i18n>Loading...</option>
59               <option *ngIf="services !== null && services.length === 0"
60                       [ngValue]="null"
61                       i18n>-- No service available --</option>
62               <option *ngIf="services !== null && services.length > 0"
63                       [ngValue]="null"
64                       i18n>-- Select an existing service --</option>
65               <option *ngFor="let service of services"
66                       [value]="service.service_name">{{ service.service_name }}</option>
67             </select>
68             <span class="invalid-feedback"
69                   *ngIf="serviceForm.showError('backend_service', frm, 'required')"
70                   i18n>This field is required.</span>
71           </div>
72         </div>
73
74         <!-- NVMe/TCP -->
75         <!-- Block Pool -->
76         <div class="form-group row"
77              *ngIf="serviceForm.controls.service_type.value === 'nvmeof'">
78           <label i18n
79                  class="cd-col-form-label required"
80                  for="pool">Block Pool</label>
81           <div class="cd-col-form-input">
82             <select id="pool"
83                     name="pool"
84                     class="form-select"
85                     formControlName="pool"
86                     (change)="onBlockPoolChange()">
87               <option *ngIf="rbdPools === null"
88                       [ngValue]="null"
89                       i18n>Loading...</option>
90               <option *ngIf="rbdPools && rbdPools.length === 0"
91                       [ngValue]="null"
92                       i18n>-- No block pools available --</option>
93               <option *ngIf="rbdPools && rbdPools.length > 0"
94                       [ngValue]="null"
95                       i18n>-- Select a pool --</option>
96               <option *ngFor="let pool of rbdPools"
97                       [value]="pool.pool_name">{{ pool.pool_name }}</option>
98             </select>
99             <cd-help-text i18n>
100               A pool in which the gateway configuration can be managed.
101             </cd-help-text>
102             <span class="invalid-feedback"
103                   *ngIf="serviceForm.showError('pool', frm, 'required')"
104                   i18n>This field is required.</span>
105           </div>
106         </div>
107
108         <!-- Service id -->
109         <div class="form-group row"
110              *ngIf="serviceForm.controls.service_type.value !== 'snmp-gateway'">
111           <label class="cd-col-form-label"
112                  [ngClass]="{'required': ['mds', 'rgw', 'nfs', 'iscsi', 'nvmeof', 'smb', 'ingress'].includes(serviceForm.controls.service_type.value)}"
113                  for="service_id">
114             <span i18n>Service Name</span>
115           </label>
116           <div class="cd-col-form-input">
117             <div class="input-group">
118               <span class="input-group-text"
119                     *ngIf="serviceForm.controls.service_type.value && ['mds', 'rgw', 'nfs', 'iscsi', 'nvmeof', 'smb', 'ingress'].includes(serviceForm.controls.service_type.value)"
120                     for="userId"
121                     i18n>{{serviceForm.controls.service_type.value}}.
122               </span>
123               <input id="service_id"
124                      class="form-control"
125                      type="text"
126                      formControlName="service_id">
127             </div>
128             <span class="invalid-feedback"
129                   *ngIf="serviceForm.showError('service_id', frm, 'required')"
130                   i18n>This field is required.</span>
131             <span class="invalid-feedback"
132                   *ngIf="serviceForm.showError('service_id', frm, 'uniqueName')"
133                   i18n>This service id is already in use.</span>
134             <span class="invalid-feedback"
135                   *ngIf="serviceForm.showError('service_id', frm, 'mdsPattern')"
136                   i18n>MDS service id must start with a letter and contain alphanumeric characters or '.', '-', and '_'</span>
137           </div>
138         </div>
139
140         <div class="form-group row"
141              *ngIf="serviceForm.controls.service_type.value === 'rgw'">
142           <label class="cd-col-form-label"
143                  for="realm_name"
144                  i18n>Realm</label>
145           <div class="cd-col-form-input">
146             <select class="form-select"
147                     id="realm_name"
148                     formControlName="realm_name"
149                     name="realm_name"
150                     [attr.disabled]="realmList.length === 0  || editing ? true : null">
151             <option *ngIf="realmList.length === 0"
152                     i18n
153                     selected>-- No realm available --</option>
154             <option *ngFor="let realm of realmList"
155                     [value]="realm.name">
156                   {{ realm.name }}
157             </option>
158             </select>
159           </div>
160         </div>
161
162         <div class="form-group row"
163              *ngIf="serviceForm.controls.service_type.value === 'rgw'">
164           <label class="cd-col-form-label"
165                  for="zonegroup_name"
166                  i18n>Zone Group</label>
167           <div class="cd-col-form-input">
168             <select class="form-select"
169                     id="zonegroup_name"
170                     formControlName="zonegroup_name"
171                     name="zonegroup_name"
172                     [attr.disabled]="zonegroupList.length === 0  || editing ? true : null">
173               <option *ngFor="let zonegroup of zonegroupList"
174                       [value]="zonegroup.name">
175               {{ zonegroup.name }}
176               </option>
177             </select>
178           </div>
179         </div>
180
181         <div class="form-group row"
182              *ngIf="serviceForm.controls.service_type.value === 'rgw'">
183           <label class="cd-col-form-label"
184                  for="zone_name"
185                  i18n>Zone</label>
186           <div class="cd-col-form-input">
187             <select class="form-select"
188                     id="zone_name"
189                     formControlName="zone_name"
190                     name="zone_name"
191                     [attr.disabled]="zoneList.length === 0  || editing ? true : null">
192               <option *ngFor="let zone of zoneList"
193                       [value]="zone.name">
194               {{ zone.name }}
195               </option>
196             </select>
197           </div>
198         </div>
199
200         <!-- unmanaged -->
201         <div class="form-group row">
202           <div class="cd-col-form-offset">
203             <div class="custom-control custom-checkbox">
204               <input class="custom-control-input"
205                      id="unmanaged"
206                      type="checkbox"
207                      formControlName="unmanaged">
208               <label class="custom-control-label m-0"
209                      for="unmanaged"
210                      i18n>Unmanaged</label>
211               <cd-help-text i18n>If Unmanaged is selected, the orchestrator will not stop or stop any daemons associated with this service. Placement and all other properties will be ignored.</cd-help-text>
212             </div>
213           </div>
214         </div>
215
216         <!-- Placement -->
217         <div *ngIf="!serviceForm.controls.unmanaged.value"
218              class="form-group row">
219           <label class="cd-col-form-label"
220                  for="placement"
221                  i18n>Placement</label>
222           <div class="cd-col-form-input">
223             <select id="placement"
224                     class="form-select"
225                     formControlName="placement">
226               <option i18n
227                       value="hosts">Hosts</option>
228               <option i18n
229                       value="label">Label</option>
230             </select>
231           </div>
232         </div>
233
234         <!-- Label -->
235         <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'label'"
236              class="form-group row">
237           <label i18n
238                  class="cd-col-form-label"
239                  for="label">Label</label>
240           <div class="cd-col-form-input">
241             <input id="label"
242                    class="form-control"
243                    type="text"
244                    formControlName="label"
245                    [ngbTypeahead]="searchLabels"
246                    (focus)="labelFocus.next($any($event).target.value)"
247                    (click)="labelClick.next($any($event).target.value)">
248             <span class="invalid-feedback"
249                   *ngIf="serviceForm.showError('label', frm, 'required')"
250                   i18n>This field is required.</span>
251           </div>
252         </div>
253
254         <!-- Hosts -->
255         <div *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.placement.value === 'hosts'"
256              class="form-group row">
257           <label class="cd-col-form-label"
258                  for="hosts"
259                  i18n>Hosts</label>
260           <div class="cd-col-form-input">
261             <cd-select-badges id="hosts"
262                               [data]="serviceForm.controls.hosts.value"
263                               [options]="hosts.options"
264                               [messages]="hosts.messages">
265             </cd-select-badges>
266           </div>
267         </div>
268
269         <!-- Count -->
270         <div *ngIf="!serviceForm.controls.unmanaged.value"
271              class="form-group row">
272           <label class="cd-col-form-label"
273                  for="count">
274             <span i18n>Count</span>
275           </label>
276           <div class="cd-col-form-input">
277             <input id="count"
278                    class="form-control"
279                    type="number"
280                    formControlName="count"
281                    min="1">
282             <cd-help-text i18n>Number of deamons that will be deployed</cd-help-text>
283             <span class="invalid-feedback"
284                   *ngIf="serviceForm.showError('count', frm, 'min')"
285                   i18n>The value must be at least 1.</span>
286             <span class="invalid-feedback"
287                   *ngIf="serviceForm.showError('count', frm, 'pattern')"
288                   i18n>The entered value needs to be a number.</span>
289           </div>
290         </div>
291
292         <!-- RGW -->
293         <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'rgw'">
294           <!-- rgw_frontend_port -->
295           <div class="form-group row">
296             <label i18n
297                    class="cd-col-form-label"
298                    for="rgw_frontend_port">Port</label>
299             <div class="cd-col-form-input">
300               <input id="rgw_frontend_port"
301                      class="form-control"
302                      type="number"
303                      formControlName="rgw_frontend_port"
304                      min="1"
305                      max="65535">
306               <span class="invalid-feedback"
307                     *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'pattern')"
308                     i18n>The entered value needs to be a number.</span>
309               <span class="invalid-feedback"
310                     *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'min')"
311                     i18n>The value must be at least 1.</span>
312               <span class="invalid-feedback"
313                     *ngIf="serviceForm.showError('rgw_frontend_port', frm, 'max')"
314                     i18n>The value cannot exceed 65535.</span>
315             </div>
316           </div>
317         </ng-container>
318
319         <!-- iSCSI -->
320         <!-- pool -->
321         <div class="form-group row"
322              *ngIf="serviceForm.controls.service_type.value === 'iscsi'">
323           <label i18n
324                  class="cd-col-form-label required"
325                  for="pool">Pool</label>
326           <div class="cd-col-form-input">
327             <select id="pool"
328                     name="pool"
329                     class="form-select"
330                     formControlName="pool">
331               <option *ngIf="pools === null"
332                       [ngValue]="null"
333                       i18n>Loading...</option>
334               <option *ngIf="pools && pools.length === 0"
335                       [ngValue]="null"
336                       i18n>-- No pools available --</option>
337               <option *ngIf="pools && pools.length > 0"
338                       [ngValue]="null"
339                       i18n>-- Select a pool --</option>
340               <option *ngFor="let pool of pools"
341                       [value]="pool.pool_name">{{ pool.pool_name }}</option>
342             </select>
343             <span class="invalid-feedback"
344                   *ngIf="serviceForm.showError('pool', frm, 'required')"
345                   i18n>This field is required.</span>
346           </div>
347         </div>
348
349         <!-- fields in iSCSI which are hidden when unmanaged is true -->
350         <ng-container *ngIf="!serviceForm.controls.unmanaged.value && serviceForm.controls.service_type.value === 'iscsi'">
351           <!-- trusted_ip_list -->
352           <div class="form-group row">
353             <label class="cd-col-form-label"
354                    for="trusted_ip_list">
355               <span i18n>Trusted IPs</span>
356               <cd-helper>
357                 <span i18n>Comma separated list of IP addresses.</span>
358                 <br>
359                 <span i18n>Please add the <b>Ceph Manager</b> IP addresses here, otherwise the iSCSI gateways can't be reached.</span>
360               </cd-helper>
361             </label>
362             <div class="cd-col-form-input">
363               <input id="trusted_ip_list"
364                      class="form-control"
365                      type="text"
366                      formControlName="trusted_ip_list">
367             </div>
368           </div>
369
370           <!-- api_port -->
371           <div class="form-group row">
372             <label i18n
373                    class="cd-col-form-label"
374                    for="api_port">Port</label>
375             <div class="cd-col-form-input">
376               <input id="api_port"
377                      class="form-control"
378                      type="number"
379                      formControlName="api_port"
380                      min="1"
381                      max="65535">
382               <span class="invalid-feedback"
383                     *ngIf="serviceForm.showError('api_port', frm, 'pattern')"
384                     i18n>The entered value needs to be a number.</span>
385               <span class="invalid-feedback"
386                     *ngIf="serviceForm.showError('api_port', frm, 'min')"
387                     i18n>The value must be at least 1.</span>
388               <span class="invalid-feedback"
389                     *ngIf="serviceForm.showError('api_port', frm, 'max')"
390                     i18n>The value cannot exceed 65535.</span>
391             </div>
392           </div>
393
394           <!-- api_user -->
395           <div class="form-group row">
396             <label i18n
397                    class="cd-col-form-label"
398                    [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
399                    for="api_user">User</label>
400             <div class="cd-col-form-input">
401               <input id="api_user"
402                      class="form-control"
403                      type="text"
404                      formControlName="api_user">
405               <span class="invalid-feedback"
406                     *ngIf="serviceForm.showError('api_user', frm, 'required')"
407                     i18n>This field is required.</span>
408             </div>
409           </div>
410
411           <!-- api_password -->
412           <div class="form-group row">
413             <label i18n
414                    class="cd-col-form-label"
415                    [ngClass]="{'required': ['iscsi'].includes(serviceForm.controls.service_type.value)}"
416                    for="api_password">Password</label>
417             <div class="cd-col-form-input">
418               <div class="input-group">
419                 <input id="api_password"
420                        class="form-control"
421                        type="password"
422                        autocomplete="new-password"
423                        formControlName="api_password">
424                 <button type="button"
425                         class="btn btn-light"
426                         cdPasswordButton="api_password">
427                 </button>
428                 <cd-copy-2-clipboard-button source="api_password">
429                 </cd-copy-2-clipboard-button>
430                 <span class="invalid-feedback"
431                       *ngIf="serviceForm.showError('api_password', frm, 'required')"
432                       i18n>This field is required.</span>
433               </div>
434             </div>
435           </div>
436         </ng-container>
437
438         <!-- smb -->
439         <ng-container *ngIf="serviceForm.controls.service_type.value === 'smb'">
440           <div class="form-group row">
441             <label class="cd-col-form-label required"
442                    for="cluster_id"
443                    i18n>
444               Cluster id
445               <cd-helper>
446                 <span>A short name identifying the SMB “cluster”. In this case a cluster is simply a management unit of one or more Samba services sharing a common configuration,
447                    and may not provide actual clustering or availability mechanisms.</span>
448               </cd-helper>
449             </label>
450             <div class="cd-col-form-input">
451               <input id="cluster_id"
452                      class="form-control"
453                      type="text"
454                      formControlName="cluster_id"
455                      placeholder="foo"
456                      i18n-placeholder>
457               <span class="invalid-feedback"
458                     *ngIf="serviceForm.showError('cluster_id', frm, 'required')"
459                     i18n>This field is required.</span>
460             </div>
461           </div>
462
463           <div class="form-group row">
464             <label class="cd-col-form-label required"
465                    for="config_uri">
466               <span i18n>Config URI</span>
467               <cd-helper i18n>
468                 Configuration source that should be loaded by the samba-container as the primary configuration file.
469               </cd-helper>
470             </label>
471             <div class="cd-col-form-input">
472               <input id="config_uri"
473                      class="form-control"
474                      type="text"
475                      formControlName="config_uri"
476                      placeholder="rados://.smb/foo/scc.toml"
477                      i18n-placeholder>
478               <span class="invalid-feedback"
479                     *ngIf="serviceForm.showError('config_uri', frm, 'required')"
480                     i18n>This field is required.</span>
481               <span class="invalid-feedback"
482                     *ngIf="serviceForm.showError('config_uri', frm, 'configUriPattern')"
483                     i18n>The value must start with either 'http:', 'https:', 'rados:' or 'rados:mon-config-key:'</span>
484             </div>
485           </div>
486
487           <div class="form-group row"
488                formGroupName="features">
489             <label class="cd-col-form-label"
490                    for="features"
491                    i18n>Features
492               <cd-helper>
493                 <span>Pre-defined terms enabling specific deployment characteristics.</span>
494               </cd-helper>
495             </label>
496             <div class="cd-col-form-input">
497               <div class="custom-control custom-checkbox"
498                    *ngFor="let feature of smbFeaturesList">
499                 <input class="custom-control-input"
500                        type="checkbox"
501                        name="{{feature}}"
502                        id="{{feature}}"
503                        formControlName="{{feature}}">
504                 <label class="custom-control-label"
505                        for="{{feature}}"
506                        i18n>{{feature}}
507                 </label>
508               </div>
509             </div>
510           </div>
511
512           <div class="form-group row">
513             <label class="cd-col-form-label"
514                    for="custom_dns">
515               <span i18n>Custom DNS</span>
516               <cd-helper i18n>
517                 <span>Comma separated list of DNSs.</span>
518                 <br>
519                 <span>A list of IP addresses that will be used as the DNS servers for a Samba container.</span>
520               </cd-helper>
521             </label>
522             <div class="cd-col-form-input">
523               <input id="custom_dns"
524                      class="form-control"
525                      type="text"
526                      formControlName="custom_dns"
527                      placeholder="192.168.76.204"
528                      i18n-placeholder>
529             </div>
530           </div>
531
532           <div class="form-group row">
533             <label class="cd-col-form-label"
534                    for="join_sources">
535               <span i18n>Join sources</span>
536               <cd-helper i18n>
537                 <span>Comma separated list of URIs.</span>
538                 <br>
539                 <span>A list of values that will be used to identify where authentication data that will be used to perform domain joins are located.</span>
540               </cd-helper>
541             </label>
542             <div class="cd-col-form-input">
543               <input id="join_sources"
544                      class="form-control"
545                      type="text"
546                      formControlName="join_sources"
547                      placeholder="rados:mon-config-key:smb/config/foo/join1.json"
548                      i18n-placeholder>
549             </div>
550           </div>
551
552           <div class="form-group row">
553             <label class="cd-col-form-label"
554                    for="user_sources">
555               <span i18n>User sources</span>
556               <cd-helper i18n>
557                 <span>Comma separated list of URIs.</span>
558                 <br>
559                 <span>A list of pseudo-uris containing data the samba-container can use to create users (and/or
560                   groups). A ceph based samba container may typically use a rados uri
561                   or a mon config-key store uri </span>
562               </cd-helper>
563             </label>
564             <div class="cd-col-form-input">
565               <input id="user_sources"
566                      class="form-control"
567                      type="text"
568                      formControlName="user_sources"
569                      placeholder="rados:mon-config-key:smb/config/foo/join2.json"
570                      i18n-placeholder>
571             </div>
572           </div>
573
574           <div class="form-group row">
575             <label class="cd-col-form-label"
576                    for="include_ceph_users">
577               <span i18n>Ceph users</span>
578               <cd-helper i18n>
579                 <span>Comma separated list of Ceph users.</span>
580                 <br>
581                 <span>A list of cephx user names that the Samba Containers may use.</span>
582               </cd-helper>
583             </label>
584             <div class="cd-col-form-input">
585               <input id="include_ceph_users"
586                      class="form-control"
587                      type="text"
588                      formControlName="include_ceph_users"
589                      placeholder="client.smb.fs.cluster.foo"
590                      i18n-placeholder>
591             </div>
592           </div>
593
594         </ng-container>
595
596         <!-- Ingress -->
597         <ng-container *ngIf="serviceForm.controls.service_type.value === 'ingress'">
598           <!-- virtual_ip -->
599           <div class="form-group row">
600             <label class="cd-col-form-label"
601                    [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
602                    for="virtual_ip">
603               <span i18n>Virtual IP</span>
604               <cd-helper>
605                 <span i18n>The virtual IP address and subnet (in CIDR notation) where the ingress service will be available.</span>
606               </cd-helper>
607             </label>
608             <div class="cd-col-form-input">
609               <input id="virtual_ip"
610                      class="form-control"
611                      type="text"
612                      formControlName="virtual_ip">
613               <span class="invalid-feedback"
614                     *ngIf="serviceForm.showError('virtual_ip', frm, 'required')"
615                     i18n>This field is required.</span>
616             </div>
617           </div>
618
619           <!-- frontend_port -->
620           <div class="form-group row">
621             <label class="cd-col-form-label"
622                    [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
623                    for="frontend_port">
624               <span i18n>Frontend Port</span>
625               <cd-helper>
626                 <span i18n>The port used to access the ingress service.</span>
627               </cd-helper>
628             </label>
629             <div class="cd-col-form-input">
630               <input id="frontend_port"
631                      class="form-control"
632                      type="number"
633                      formControlName="frontend_port"
634                      min="1"
635                      max="65535">
636               <span class="invalid-feedback"
637                     *ngIf="serviceForm.showError('frontend_port', frm, 'pattern')"
638                     i18n>The entered value needs to be a number.</span>
639               <span class="invalid-feedback"
640                     *ngIf="serviceForm.showError('frontend_port', frm, 'min')"
641                     i18n>The value must be at least 1.</span>
642               <span class="invalid-feedback"
643                     *ngIf="serviceForm.showError('frontend_port', frm, 'max')"
644                     i18n>The value cannot exceed 65535.</span>
645               <span class="invalid-feedback"
646                     *ngIf="serviceForm.showError('frontend_port', frm, 'required')"
647                     i18n>This field is required.</span>
648             </div>
649           </div>
650
651           <!-- monitor_port -->
652           <div class="form-group row">
653             <label class="cd-col-form-label"
654                    [ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
655                    for="monitor_port">
656               <span i18n>Monitor Port</span>
657               <cd-helper>
658                 <span i18n>The port used by haproxy for load balancer status.</span>
659               </cd-helper>
660             </label>
661             <div class="cd-col-form-input">
662               <input id="monitor_port"
663                      class="form-control"
664                      type="number"
665                      formControlName="monitor_port"
666                      min="1"
667                      max="65535">
668               <span class="invalid-feedback"
669                     *ngIf="serviceForm.showError('monitor_port', frm, 'pattern')"
670                     i18n>The entered value needs to be a number.</span>
671               <span class="invalid-feedback"
672                     *ngIf="serviceForm.showError('monitor_port', frm, 'min')"
673                     i18n>The value must be at least 1.</span>
674               <span class="invalid-feedback"
675                     *ngIf="serviceForm.showError('monitor_port', frm, 'max')"
676                     i18n>The value cannot exceed 65535.</span>
677               <span class="invalid-feedback"
678                     *ngIf="serviceForm.showError('monitor_port', frm, 'required')"
679                     i18n>This field is required.</span>
680             </div>
681           </div>
682           <!-- virtual_interface_networks -->
683           <div class="form-group row"
684                *ngIf="!serviceForm.controls.unmanaged.value">
685             <label class="cd-col-form-label"
686                    for="virtual_interface_networks">
687               <span i18n>CIDR Networks</span>
688               <cd-helper>
689                 <span i18n>A list of networks to identify which network interface to use for the virtual IP address.</span>
690               </cd-helper>
691             </label>
692             <div class="cd-col-form-input">
693               <input id="virtual_interface_networks"
694                      class="form-control"
695                      type="text"
696                      formControlName="virtual_interface_networks">
697             </div>
698           </div>
699         </ng-container>
700
701         <!-- SNMP-Gateway -->
702         <ng-container *ngIf="serviceForm.controls.service_type.value === 'snmp-gateway'">
703           <!-- snmp-version -->
704           <div class="form-group row">
705             <label class="cd-col-form-label required"
706                    for="snmp_version"
707                    i18n>Version</label>
708             <div class="cd-col-form-input">
709               <select id="snmp_version"
710                       name="snmp_version"
711                       class="form-select"
712                       formControlName="snmp_version"
713                       (change)="clearValidations()">
714                 <option i18n
715                         [ngValue]="null">-- Select SNMP version --</option>
716                 <option *ngFor="let snmpVersion of ['V2c', 'V3']"
717                         [value]="snmpVersion">{{ snmpVersion }}</option>
718               </select>
719               <span class="invalid-feedback"
720                     *ngIf="serviceForm.showError('snmp_version', frm, 'required')"
721                     i18n>This field is required.</span>
722             </div>
723           </div>
724           <!-- Destination -->
725           <div class="form-group row">
726             <label class="cd-col-form-label required"
727                    for="snmp_destination">
728               <span i18n>Destination</span>
729               <cd-helper>
730                 <span i18n>Must be of the format hostname:port.</span>
731               </cd-helper>
732             </label>
733             <div class="cd-col-form-input">
734               <input id="snmp_destination"
735                      class="form-control"
736                      type="text"
737                      formControlName="snmp_destination">
738               <span class="invalid-feedback"
739                     *ngIf="serviceForm.showError('snmp_destination', frm, 'required')"
740                     i18n>This field is required.</span>
741               <span class="invalid-feedback"
742                     *ngIf="serviceForm.showError('snmp_destination', frm, 'snmpDestinationPattern')"
743                     i18n>The value does not match the pattern: <strong>hostname:port</strong></span>
744             </div>
745           </div>
746           <!-- Engine id for snmp V3 -->
747           <div class="form-group row"
748                *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
749             <label class="cd-col-form-label required"
750                    for="engine_id">
751               <span i18n>Engine Id</span>
752               <cd-helper>
753                 <span i18n>Unique identifier for the device (in hex).</span>
754               </cd-helper>
755             </label>
756             <div class="cd-col-form-input">
757               <input id="engine_id"
758                      class="form-control"
759                      type="text"
760                      formControlName="engine_id">
761               <span class="invalid-feedback"
762                     *ngIf="serviceForm.showError('engine_id', frm, 'required')"
763                     i18n>This field is required.</span>
764               <span class="invalid-feedback"
765                     *ngIf="serviceForm.showError('engine_id', frm, 'snmpEngineIdPattern')"
766                     i18n>The value does not match the pattern: <strong>Must be in hexadecimal and length must be multiple of 2 with min value = 10 amd max value = 64.</strong></span>
767             </div>
768           </div>
769           <!-- Auth protocol for snmp V3 -->
770           <div class="form-group row"
771                *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
772             <label class="cd-col-form-label required"
773                    for="auth_protocol"
774                    i18n>Auth Protocol</label>
775             <div class="cd-col-form-input">
776               <select id="auth_protocol"
777                       name="auth_protocol"
778                       class="form-select"
779                       formControlName="auth_protocol">
780                 <option i18n
781                         [ngValue]="null">-- Select auth protocol --</option>
782                 <option *ngFor="let authProtocol of ['SHA', 'MD5']"
783                         [value]="authProtocol">
784                   {{ authProtocol }}
785                 </option>
786               </select>
787               <span class="invalid-feedback"
788                     *ngIf="serviceForm.showError('auth_protocol', frm, 'required')"
789                     i18n>This field is required.</span>
790             </div>
791           </div>
792           <!-- Privacy protocol for snmp V3 -->
793           <div class="form-group row"
794                *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
795             <label class="cd-col-form-label"
796                    for="privacy_protocol"
797                    i18n>Privacy Protocol</label>
798             <div class="cd-col-form-input">
799               <select id="privacy_protocol"
800                       name="privacy_protocol"
801                       class="form-select"
802                       formControlName="privacy_protocol">
803                 <option i18n
804                         [ngValue]="null">-- Select privacy protocol --</option>
805                 <option *ngFor="let privacyProtocol of ['DES', 'AES']"
806                         [value]="privacyProtocol">
807                   {{ privacyProtocol }}
808                 </option>
809               </select>
810             </div>
811           </div>
812           <!-- Credentials -->
813           <fieldset>
814             <legend i18n>Credentials</legend>
815             <!-- snmp v2c snmp_community -->
816             <div class="form-group row"
817                  *ngIf="serviceForm.controls.snmp_version.value === 'V2c'">
818               <label class="cd-col-form-label required"
819                      for="snmp_community">
820                 <span i18n>SNMP Community</span>
821               </label>
822               <div class="cd-col-form-input">
823                 <input id="snmp_community"
824                        class="form-control"
825                        type="text"
826                        formControlName="snmp_community">
827                 <span class="invalid-feedback"
828                       *ngIf="serviceForm.showError('snmp_community', frm, 'required')"
829                       i18n>This field is required.</span>
830               </div>
831             </div>
832             <!-- snmp v3 auth username -->
833             <div class="form-group row"
834                  *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
835               <label class="cd-col-form-label required"
836                      for="snmp_v3_auth_username">
837                 <span i18n>Username</span>
838               </label>
839               <div class="cd-col-form-input">
840                 <input id="snmp_v3_auth_username"
841                        class="form-control"
842                        type="text"
843                        formControlName="snmp_v3_auth_username">
844                 <span class="invalid-feedback"
845                       *ngIf="serviceForm.showError('snmp_v3_auth_username', frm, 'required')"
846                       i18n>This field is required.</span>
847               </div>
848             </div>
849             <!-- snmp v3 auth password -->
850             <div class="form-group row"
851                  *ngIf="serviceForm.controls.snmp_version.value === 'V3'">
852               <label class="cd-col-form-label required"
853                      for="snmp_v3_auth_password">
854                 <span i18n>Password</span>
855               </label>
856               <div class="cd-col-form-input">
857                 <input id="snmp_v3_auth_password"
858                        class="form-control"
859                        type="password"
860                        formControlName="snmp_v3_auth_password">
861                 <span class="invalid-feedback"
862                       *ngIf="serviceForm.showError('snmp_v3_auth_password', frm, 'required')"
863                       i18n>This field is required.</span>
864               </div>
865             </div>
866             <!-- snmp v3 priv password -->
867             <div class="form-group row"
868                  *ngIf="serviceForm.controls.snmp_version.value === 'V3' && serviceForm.controls.privacy_protocol.value !== null && serviceForm.controls.privacy_protocol.value !== undefined">
869               <label class="cd-col-form-label required"
870                      for="snmp_v3_priv_password">
871                 <span i18n>Encryption</span>
872               </label>
873               <div class="cd-col-form-input">
874                 <input id="snmp_v3_priv_password"
875                        class="form-control"
876                        type="password"
877                        formControlName="snmp_v3_priv_password">
878                 <span class="invalid-feedback"
879                       *ngIf="serviceForm.showError('snmp_v3_priv_password', frm, 'required')"
880                       i18n>This field is required.</span>
881               </div>
882             </div>
883           </fieldset>
884         </ng-container>
885         <!-- RGW, Ingress & iSCSI -->
886         <ng-container *ngIf="!serviceForm.controls.unmanaged.value && ['rgw', 'iscsi', 'ingress'].includes(serviceForm.controls.service_type.value)">
887           <!-- ssl -->
888           <div class="form-group row">
889             <div class="cd-col-form-offset">
890               <div class="custom-control custom-checkbox">
891                 <input class="custom-control-input"
892                        id="ssl"
893                        type="checkbox"
894                        formControlName="ssl">
895                 <label class="custom-control-label"
896                        for="ssl"
897                        i18n>SSL</label>
898               </div>
899             </div>
900           </div>
901
902           <!-- ssl_cert -->
903           <div *ngIf="serviceForm.controls.ssl.value"
904                class="form-group row">
905             <label class="cd-col-form-label"
906                    for="ssl_cert">
907               <span i18n>Certificate</span>
908               <cd-helper i18n>The SSL certificate in PEM format.</cd-helper>
909             </label>
910             <div class="cd-col-form-input">
911               <textarea id="ssl_cert"
912                         class="form-control resize-vertical text-monospace text-pre"
913                         formControlName="ssl_cert"
914                         rows="5">
915               </textarea>
916               <input type="file"
917                      (change)="fileUpload($event.target.files, 'ssl_cert')">
918               <span class="invalid-feedback"
919                     *ngIf="serviceForm.showError('ssl_cert', frm, 'required')"
920                     i18n>This field is required.</span>
921               <span class="invalid-feedback"
922                     *ngIf="serviceForm.showError('ssl_cert', frm, 'pattern')"
923                     i18n>Invalid SSL certificate.</span>
924             </div>
925           </div>
926
927           <!-- ssl_key -->
928           <div *ngIf="serviceForm.controls.ssl.value && !(['rgw', 'ingress'].includes(serviceForm.controls.service_type.value))"
929                class="form-group row">
930             <label class="cd-col-form-label"
931                    for="ssl_key">
932               <span i18n>Private key</span>
933               <cd-helper i18n>The SSL private key in PEM format.</cd-helper>
934             </label>
935             <div class="cd-col-form-input">
936               <textarea id="ssl_key"
937                         class="form-control resize-vertical text-monospace text-pre"
938                         formControlName="ssl_key"
939                         rows="5">
940               </textarea>
941               <input type="file"
942                      (change)="fileUpload($event.target.files,'ssl_key')">
943               <span class="invalid-feedback"
944                     *ngIf="serviceForm.showError('ssl_key', frm, 'required')"
945                     i18n>This field is required.</span>
946               <span class="invalid-feedback"
947                     *ngIf="serviceForm.showError('ssl_key', frm, 'pattern')"
948                     i18n>Invalid SSL private key.</span>
949             </div>
950           </div>
951         </ng-container>
952         <!-- Grafana -->
953         <ng-container *ngIf="serviceForm.controls.service_type.value === 'grafana'">
954           <div class="form-group row">
955             <label class="cd-col-form-label"
956                    for="grafana_port">
957               <span i18n>Grafana Port</span>
958               <cd-helper>
959                 <span i18n>The default port used by grafana.</span>
960               </cd-helper>
961             </label>
962             <div class="cd-col-form-input">
963               <input id="grafana_port"
964                      class="form-control"
965                      type="number"
966                      formControlName="grafana_port"
967                      min="1"
968                      max="65535">
969               <span class="invalid-feedback"
970                     *ngIf="serviceForm.showError('grafana_port', frm, 'pattern')"
971                     i18n>The entered value needs to be a number.</span>
972               <span class="invalid-feedback"
973                     *ngIf="serviceForm.showError('grafana_port', frm, 'min')"
974                     i18n>The value must be at least 1.</span>
975               <span class="invalid-feedback"
976                     *ngIf="serviceForm.showError('grafana_port', frm, 'max')"
977                     i18n>The value cannot exceed 65535.</span>
978               <span class="invalid-feedback"
979                     *ngIf="serviceForm.showError('grafana_port', frm, 'required')"
980                     i18n>This field is required.</span>
981             </div>
982           </div>
983
984           <div class="form-group row">
985             <label i18n
986                    class="cd-col-form-label"
987                    for="grafana_admin_password">
988               <span>Grafana Password</span>
989               <cd-helper>The password of the default Grafana Admin. Set once on first-run.</cd-helper>
990             </label>
991             <div class="cd-col-form-input">
992               <div class="input-group">
993                 <input id="grafana_admin_password"
994                        class="form-control"
995                        type="password"
996                        autocomplete="new-password"
997                        [attr.disabled]="editing ? true:null"
998                        formControlName="grafana_admin_password">
999                 <span class="input-group-append">
1000                   <button type="button"
1001                           class="btn btn-light"
1002                           cdPasswordButton="grafana_admin_password">
1003                   </button>
1004                   <cd-copy-2-clipboard-button source="grafana_admin_password">
1005                   </cd-copy-2-clipboard-button>
1006                 </span>
1007               </div>
1008             </div>
1009           </div>
1010         </ng-container>
1011       </div>
1012
1013       <div class="modal-footer">
1014         <div class="text-right">
1015           <cd-form-button-panel (submitActionEvent)="onSubmit()"
1016                                 [form]="serviceForm"
1017                                 [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"></cd-form-button-panel>
1018         </div>
1019       </div>
1020     </form>
1021   </ng-container>
1022 </cd-modal>