Skip to content

Commit e3e7139

Browse files
authored
Merge pull request ceph#57801 from afreen23/wip-nvmeof-service
mgr/dashboard: Configure NVMe/TCP Reviewed-by: Pedro Gonzalez Gomez <[email protected]> Reviewed-by: Ankush Behl <[email protected]> Reviewed-by: Nizamudeen A <[email protected]> Reviewed-by: rivkap <NOT@FOUND>
2 parents ae75087 + c6cf917 commit e3e7139

File tree

4 files changed

+304
-143
lines changed

4 files changed

+304
-143
lines changed

src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
i18n>Loading...</option>
7676
<option *ngIf="pools !== null && pools.length === 0"
7777
[ngValue]="null"
78-
i18n>-- No rbd pools available --</option>
78+
i18n>-- No block pools available --</option>
7979
<option *ngIf="pools !== null && pools.length > 0"
8080
[ngValue]="null"
8181
i18n>-- Select a pool --</option>

src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.html

Lines changed: 81 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
(click)="createMultisiteSetup()">
1616
Click here</a> to create a new Realm/Zone Group/Zone
1717
</cd-alert-panel>
18+
1819
<!-- Service type -->
1920
<div class="form-group row">
2021
<label class="cd-col-form-label required"
@@ -25,7 +26,7 @@
2526
name="service_type"
2627
class="form-select"
2728
formControlName="service_type"
28-
(change)="getServiceIds($event.target.value)">
29+
(change)="onServiceTypeChange($event.target.value)">
2930
<option i18n
3031
[ngValue]="null">-- Select a service type --</option>
3132
<option *ngFor="let serviceType of serviceTypes"
@@ -40,50 +41,90 @@
4041
</div>
4142

4243
<!-- backend_service -->
43-
<div *ngIf="serviceForm.controls.service_type.value === 'ingress'"
44-
class="form-group row">
45-
<label i18n
46-
class="cd-col-form-label"
47-
[ngClass]="{'required': ['ingress'].includes(serviceForm.controls.service_type.value)}"
48-
for="backend_service">Backend Service</label>
49-
<div class="cd-col-form-input">
50-
<select id="backend_service"
51-
name="backend_service"
52-
class="form-select"
53-
formControlName="backend_service"
54-
(change)="prePopulateId()">
55-
<option *ngIf="services === null"
56-
[ngValue]="null"
57-
i18n>Loading...</option>
58-
<option *ngIf="services !== null && services.length === 0"
59-
[ngValue]="null"
60-
i18n>-- No service available --</option>
61-
<option *ngIf="services !== null && services.length > 0"
62-
[ngValue]="null"
63-
i18n>-- Select an existing service --</option>
64-
<option *ngFor="let service of services"
65-
[value]="service.service_name">{{ service.service_name }}</option>
66-
</select>
67-
<span class="invalid-feedback"
68-
*ngIf="serviceForm.showError('backend_service', frm, 'required')"
69-
i18n>This field is required.</span>
70-
</div>
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>
7171
</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>
72107

73108
<!-- Service id -->
74109
<div class="form-group row"
75110
*ngIf="serviceForm.controls.service_type.value !== 'snmp-gateway'">
76111
<label class="cd-col-form-label"
77-
[ngClass]="{'required': ['mds', 'rgw', 'nfs', 'iscsi', 'smb', 'ingress'].includes(serviceForm.controls.service_type.value)}"
112+
[ngClass]="{'required': ['mds', 'rgw', 'nfs', 'iscsi', 'nvmeof', 'smb', 'ingress'].includes(serviceForm.controls.service_type.value)}"
78113
for="service_id">
79-
<span i18n>Id</span>
80-
<cd-helper i18n>Used in the service name which is &lt;service_type.service_id&gt;</cd-helper>
114+
<span i18n>Service Name</span>
81115
</label>
82116
<div class="cd-col-form-input">
83-
<input id="service_id"
84-
class="form-control"
85-
type="text"
86-
formControlName="service_id">
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>
87128
<span class="invalid-feedback"
88129
*ngIf="serviceForm.showError('service_id', frm, 'required')"
89130
i18n>This field is required.</span>
@@ -164,11 +205,10 @@
164205
id="unmanaged"
165206
type="checkbox"
166207
formControlName="unmanaged">
167-
<label class="custom-control-label"
208+
<label class="custom-control-label m-0"
168209
for="unmanaged"
169210
i18n>Unmanaged</label>
170-
<cd-helper i18n>If set to true, the orchestrator will not start nor stop any daemon associated with this service.
171-
Placement and all other properties will be ignored.</cd-helper>
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>
172212
</div>
173213
</div>
174214
</div>
@@ -226,20 +266,20 @@
226266
</div>
227267
</div>
228268

229-
<!-- count -->
269+
<!-- Count -->
230270
<div *ngIf="!serviceForm.controls.unmanaged.value"
231271
class="form-group row">
232272
<label class="cd-col-form-label"
233273
for="count">
234274
<span i18n>Count</span>
235-
<cd-helper i18n>Only that number of daemons will be created.</cd-helper>
236275
</label>
237276
<div class="cd-col-form-input">
238277
<input id="count"
239278
class="form-control"
240279
type="number"
241280
formControlName="count"
242281
min="1">
282+
<cd-help-text i18n>Number of deamons that will be deployed</cd-help-text>
243283
<span class="invalid-feedback"
244284
*ngIf="serviceForm.showError('count', frm, 'min')"
245285
i18n>The value must be at least 1.</span>

src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,33 @@ x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
387387
});
388388
});
389389

390+
describe('should test service nvmeof', () => {
391+
beforeEach(() => {
392+
formHelper.setValue('service_type', 'nvmeof');
393+
formHelper.setValue('service_id', 'svc');
394+
formHelper.setValue('pool', 'xyz');
395+
});
396+
397+
it('should submit nvmeof', () => {
398+
component.onSubmit();
399+
expect(cephServiceService.create).toHaveBeenCalledWith({
400+
service_type: 'nvmeof',
401+
service_id: 'svc',
402+
placement: {},
403+
unmanaged: false,
404+
pool: 'xyz'
405+
});
406+
});
407+
408+
it('should throw error when there is no service id', () => {
409+
formHelper.expectErrorChange('service_id', '', 'required');
410+
});
411+
412+
it('should throw error when there is no pool', () => {
413+
formHelper.expectErrorChange('pool', '', 'required');
414+
});
415+
});
416+
390417
describe('should test service smb', () => {
391418
beforeEach(() => {
392419
formHelper.setValue('service_type', 'smb');
@@ -608,6 +635,15 @@ x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
608635
expect(serviceType.disabled).toBeTruthy();
609636
expect(serviceId.disabled).toBeTruthy();
610637
});
638+
639+
it('should not edit pools for nvmeof service', () => {
640+
component.serviceType = 'nvmeof';
641+
formHelper.setValue('service_type', 'nvmeof');
642+
component.ngOnInit();
643+
fixture.detectChanges();
644+
const poolId = fixture.debugElement.query(By.css('#pool')).nativeElement;
645+
expect(poolId.disabled).toBeTruthy();
646+
});
611647
});
612648
});
613649
});

0 commit comments

Comments
 (0)