diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.html
index 0e7ecb82f24..1fc6559d020 100644
--- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.html
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.html
@@ -1153,112 +1153,8 @@
}
- @if (serviceForm.controls.ssl.value && ['rgw', 'ingress', 'iscsi', 'grafana', 'oauth2-proxy', 'mgmt-gateway', 'nvmeof', 'nfs'].includes(serviceForm.controls.service_type.value)) {
-
-
- @if (editing && currentCertificate?.has_certificate) {
-
- }
-
-
-
- Choose Certificate Authority
-
-
- Internal
-
-
- External
-
-
-
-
- @if (showCertSourceChangeWarning) {
-
- Changing the certificate source will redeploy the service daemons to apply the new certificate configuration.
-
- }
-
- @if (serviceForm.controls.certificateType.value === CertificateType.internal) {
-
- Certificate will be generated automatically by Cephadm CA for internal certificate type.
-
-
-
-
-
- @if (serviceForm.controls.service_type.value === 'rgw'
- && serviceForm.controls.virtual_host_enabled.value) {
-
-
- Include wildcard certificate for bucket subdomains
-
- Add wildcard certificates (*.domain) to allow SSL for all bucket subdomains. Required for virtual-host style with SSL.
-
-
-
- }
- }
-
+ @if (serviceForm.controls.ssl.value && ['rgw', 'ingress', 'iscsi', 'grafana', 'oauth2-proxy', 'mgmt-gateway', 'nfs'].includes(serviceForm.controls.service_type.value)) {
+
}
@@ -1396,6 +1292,9 @@
@if (serviceForm.controls.enable_mtls.value) {
+
+
+ @if (serviceForm.controls.certificateType.value === CertificateType.external) {
@@ -1452,6 +1351,7 @@
}
}
+ }
+
+
+
+ @if (editing && currentCertificate?.has_certificate) {
+
+ }
+
+
+
+ Choose Certificate Authority
+
+
+ Internal
+
+
+ External
+
+
+
+
+ @if (showCertSourceChangeWarning) {
+
+ Changing the certificate source will redeploy the service daemons to apply the new certificate configuration.
+
+ }
+
+ @if (serviceForm.controls.certificateType.value === CertificateType.internal) {
+
+ Certificate will be generated automatically by Cephadm CA for internal certificate type.
+
+
+
+
+
+ @if (serviceForm.controls.service_type.value === 'rgw'
+ && serviceForm.controls.virtual_host_enabled.value) {
+
+
+ Include wildcard certificate for bucket subdomains
+
+ Add wildcard certificates (*.domain) to allow SSL for all bucket subdomains. Required for virtual-host style with SSL.
+
+
+
+ }
+ }
+
+
+
{
+ formHelper.setValue('enable_mtls', true);
+ formHelper.setValue('certificateType', 'internal');
+ fixture.detectChanges();
+ const root_ca_cert = fixture.debugElement.query(By.css('#root_ca_cert'));
+ const client_cert = fixture.debugElement.query(By.css('#client_cert'));
+ const client_key = fixture.debugElement.query(By.css('#client_key'));
+ const server_cert = fixture.debugElement.query(By.css('#server_cert'));
+ const server_key = fixture.debugElement.query(By.css('#server_key'));
+ expect(root_ca_cert).toBeNull();
+ expect(client_cert).toBeNull();
+ expect(client_key).toBeNull();
+ expect(server_cert).toBeNull();
+ expect(server_key).toBeNull();
+ });
+
it('should submit nvmeof without mTLS', () => {
component.onSubmit();
expect(cephServiceService.create).toHaveBeenCalledWith({
@@ -572,6 +588,7 @@ x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
it('should submit nvmeof with mTLS', () => {
formHelper.setValue('enable_mtls', true);
+ formHelper.setValue('certificateType', 'external');
formHelper.setValue('root_ca_cert', 'root_ca_cert');
formHelper.setValue('client_cert', 'client_cert');
formHelper.setValue('client_key', 'client_key');
@@ -585,6 +602,8 @@ x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
unmanaged: false,
group: 'default',
enable_auth: true,
+ ssl: true,
+ certificate_source: 'inline',
root_ca_cert: 'root_ca_cert',
client_cert: 'client_cert',
client_key: 'client_key',
@@ -592,6 +611,23 @@ x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
server_key: 'server_key'
});
});
+
+ it('should submit nvmeof with internal mTLS', () => {
+ formHelper.setValue('enable_mtls', true);
+ formHelper.setValue('certificateType', 'internal');
+ component.onSubmit();
+ expect(cephServiceService.create).toHaveBeenCalledWith({
+ service_type: 'nvmeof',
+ service_id: 'rbd.default',
+ placement: {},
+ unmanaged: false,
+ pool: 'rbd',
+ group: 'default',
+ enable_auth: true,
+ ssl: true,
+ certificate_source: 'cephadm-signed'
+ });
+ });
});
describe('should test service smb', () => {
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts
index 86a074fef8c..6c10ff5a2ce 100644
--- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts
@@ -238,7 +238,8 @@ export class ServiceFormComponent extends CdForm implements OnInit {
CdValidators.composeIf(
{
service_type: 'nvmeof',
- enable_mtls: true
+ enable_mtls: true,
+ certificateType: CertificateType.external
},
[Validators.required]
)
@@ -250,7 +251,8 @@ export class ServiceFormComponent extends CdForm implements OnInit {
CdValidators.composeIf(
{
service_type: 'nvmeof',
- enable_mtls: true
+ enable_mtls: true,
+ certificateType: CertificateType.external
},
[Validators.required]
)
@@ -262,7 +264,8 @@ export class ServiceFormComponent extends CdForm implements OnInit {
CdValidators.composeIf(
{
service_type: 'nvmeof',
- enable_mtls: true
+ enable_mtls: true,
+ certificateType: CertificateType.external
},
[Validators.required]
)
@@ -274,7 +277,8 @@ export class ServiceFormComponent extends CdForm implements OnInit {
CdValidators.composeIf(
{
service_type: 'nvmeof',
- enable_mtls: true
+ enable_mtls: true,
+ certificateType: CertificateType.external
},
[Validators.required]
)
@@ -286,7 +290,8 @@ export class ServiceFormComponent extends CdForm implements OnInit {
CdValidators.composeIf(
{
service_type: 'nvmeof',
- enable_mtls: true
+ enable_mtls: true,
+ certificateType: CertificateType.external
},
[Validators.required]
)
@@ -781,11 +786,19 @@ export class ServiceFormComponent extends CdForm implements OnInit {
case 'nvmeof':
this.serviceForm.get('group').setValue(response[0].spec.group);
this.serviceForm.get('enable_mtls').setValue(response[0].spec?.enable_auth);
- this.serviceForm.get('root_ca_cert').setValue(response[0].spec?.root_ca_cert);
- this.serviceForm.get('client_cert').setValue(response[0].spec?.client_cert);
- this.serviceForm.get('client_key').setValue(response[0].spec?.client_key);
- this.serviceForm.get('server_cert').setValue(response[0].spec?.server_cert);
- this.serviceForm.get('server_key').setValue(response[0].spec?.server_key);
+ if (response[0].spec?.enable_auth) {
+ if (response[0].spec?.certificate_source !== 'cephadm-signed') {
+ this.serviceForm.get('certificateType').setValue(CertificateType.external);
+ }
+ if (response[0].spec?.['custom_sans']) {
+ this.serviceForm.get('custom_sans').setValue(response[0].spec['custom_sans']);
+ }
+ this.serviceForm.get('root_ca_cert').setValue(response[0].spec?.root_ca_cert);
+ this.serviceForm.get('client_cert').setValue(response[0].spec?.client_cert);
+ this.serviceForm.get('client_key').setValue(response[0].spec?.client_key);
+ this.serviceForm.get('server_cert').setValue(response[0].spec?.server_cert);
+ this.serviceForm.get('server_key').setValue(response[0].spec?.server_key);
+ }
break;
case 'rgw':
this.serviceForm
@@ -1329,11 +1342,22 @@ export class ServiceFormComponent extends CdForm implements OnInit {
serviceSpec['group'] = values['group'];
serviceSpec['enable_auth'] = values['enable_mtls'];
if (values['enable_mtls']) {
- serviceSpec['root_ca_cert'] = values['root_ca_cert'];
- serviceSpec['client_cert'] = values['client_cert'];
- serviceSpec['client_key'] = values['client_key'];
- serviceSpec['server_cert'] = values['server_cert'];
- serviceSpec['server_key'] = values['server_key'];
+ serviceSpec['ssl'] = true;
+ serviceSpec['certificate_source'] =
+ values['certificateType'] === CertificateType.internal ? 'cephadm-signed' : 'inline';
+ if (
+ values['certificateType'] === CertificateType.internal &&
+ values['custom_sans']?.length > 0
+ ) {
+ serviceSpec['custom_sans'] = values['custom_sans'];
+ }
+ if (values['certificateType'] === CertificateType.external) {
+ serviceSpec['root_ca_cert'] = values['root_ca_cert'];
+ serviceSpec['client_cert'] = values['client_cert'];
+ serviceSpec['client_key'] = values['client_key'];
+ serviceSpec['server_cert'] = values['server_cert'];
+ serviceSpec['server_key'] = values['server_key'];
+ }
}
break;
case 'iscsi':
@@ -1583,7 +1607,7 @@ export class ServiceFormComponent extends CdForm implements OnInit {
return isExternalCert;
}
- const sslCertServices = ['rgw', 'ingress', 'iscsi', 'grafana', 'oauth2-proxy', 'nvmeof', 'nfs'];
+ const sslCertServices = ['rgw', 'ingress', 'iscsi', 'grafana', 'oauth2-proxy', 'nfs'];
return isSslEnabled && isExternalCert && sslCertServices.includes(serviceType);
}
@@ -1593,7 +1617,7 @@ export class ServiceFormComponent extends CdForm implements OnInit {
this.serviceForm.controls.certificateType?.value === CertificateType.external;
const isSslEnabled = this.serviceForm.controls.ssl?.value;
- const sslKeyServices = ['iscsi', 'grafana', 'oauth2-proxy', 'nvmeof', 'nfs', 'mgmt-gateway'];
+ const sslKeyServices = ['iscsi', 'grafana', 'oauth2-proxy', 'nfs', 'mgmt-gateway'];
return isSslEnabled && isExternalCert && sslKeyServices.includes(serviceType);
}