]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/cephadm/nvmeof: Add key encryption support to nvmeof configuration 60966/head
authorGil Bregman <gbregman@il.ibm.com>
Thu, 5 Dec 2024 12:07:45 +0000 (14:07 +0200)
committerGil Bregman <gbregman@il.ibm.com>
Thu, 5 Dec 2024 12:07:45 +0000 (14:07 +0200)
Signed-off-by: Gil Bregman <gbregman@il.ibm.com>
src/cephadm/cephadmlib/daemons/nvmeof.py
src/pybind/mgr/cephadm/inventory.py
src/pybind/mgr/cephadm/services/nvmeof.py
src/pybind/mgr/cephadm/templates/services/nvmeof/ceph-nvmeof.conf.j2
src/pybind/mgr/cephadm/tests/test_cephadm.py
src/pybind/mgr/cephadm/tests/test_services.py
src/python-common/ceph/deployment/service_spec.py

index 06e60a49d8e4f905782c6a8a5e9efcd59095fa42..51b085df2a7eef785d958316f65ebb1703fee89c 100644 (file)
@@ -100,6 +100,7 @@ class CephNvmeof(ContainerDaemonForm):
             'client_cert',
             'client_key',
             'root_ca_cert',
+            'encryption_key',
         ]:
             if fn in files:
                 mounts[
index d3681cbe60a7c5ee833f374dcf4c8ec0283ae61a..f1c56d753783b164895d8bb09c0147cf6f16ab54 100644 (file)
@@ -438,6 +438,7 @@ class SpecStore():
             for key_attr in [
                 'server_key',
                 'client_key',
+                'encryption_key',
             ]:
                 key = getattr(nvmeof_spec, key_attr, None)
                 if key:
@@ -490,6 +491,7 @@ class SpecStore():
             self.mgr.cert_key_store.rm_cert('nvmeof_root_ca_cert', service_name=spec.service_name())
             self.mgr.cert_key_store.rm_key('nvmeof_server_key', service_name=spec.service_name())
             self.mgr.cert_key_store.rm_key('nvmeof_client_key', service_name=spec.service_name())
+            self.mgr.cert_key_store.rm_key('nvmeof_encryption_key', service_name=spec.service_name())
 
     def get_created(self, spec: ServiceSpec) -> Optional[datetime.datetime]:
         return self.spec_created.get(spec.service_name())
@@ -1969,6 +1971,7 @@ class CertKeyStore():
         'ingress_ssl_key',
         'nvmeof_server_key',
         'nvmeof_client_key',
+        'nvmeof_encryption_key',
     ]
 
     known_certs: Dict[str, Any] = {}
@@ -2005,6 +2008,7 @@ class CertKeyStore():
             'ingress_ssl_key': {},  # service-name -> key
             'nvmeof_server_key': {},  # service-name -> key
             'nvmeof_client_key': {},  # service-name -> key
+            'nvmeof_encryption_key': {},  # service-name -> key
         }
 
     def get_cert(self, entity: str, service_name: str = '', host: str = '') -> str:
index 418be93b6af7ad604f98e59bc410f7d0e96af31f..0c9dc244c57eda61b8575a68fd10e8ca8726a170 100644 (file)
@@ -91,6 +91,9 @@ class NvmeofService(CephService):
                 daemon_spec.extra_files['client_key'] = spec.client_key
                 daemon_spec.extra_files['root_ca_cert'] = spec.root_ca_cert
 
+        if spec.encryption_key:
+            daemon_spec.extra_files['encryption_key'] = spec.encryption_key
+
         daemon_spec.final_config, daemon_spec.deps = self.generate_config(daemon_spec)
         daemon_spec.deps = []
         return daemon_spec
index 73f36952ee78ed73e12344aaf04025b83ce31ed9..acc93507424d98af32d972246d3aed431e49cad5 100644 (file)
@@ -9,6 +9,7 @@ state_update_notify = {{ spec.state_update_notify }}
 state_update_interval_sec = {{ spec.state_update_interval_sec }}
 enable_spdk_discovery_controller = {{ spec.enable_spdk_discovery_controller }}
 enable_key_encryption = {{ spec.enable_key_encryption }}
+encryption_key = /encryption.key
 enable_prometheus_exporter = {{ spec.enable_prometheus_exporter }}
 prometheus_exporter_ssl = False
 prometheus_port = 10008
index 3c647476e440af175d76edb30276acae194fd21f..b81510504d9ff56b9de76531552809bc618766b5 100644 (file)
@@ -1797,15 +1797,18 @@ class TestCephadm(object):
         grafana_host1_key = 'fake-grafana-host1-key'
         nvmeof_client_key = 'nvmeof-client-key'
         nvmeof_server_key = 'nvmeof-server-key'
+        nvmeof_encryption_key = 'nvmeof-encryption-key'
         grafana_host1_key = 'fake-grafana-host1-cert'
         cephadm_module.cert_key_store.save_key('grafana_key', grafana_host1_key, host='host1')
         cephadm_module.cert_key_store.save_key('nvmeof_client_key', nvmeof_client_key, service_name='nvmeof.foo')
         cephadm_module.cert_key_store.save_key('nvmeof_server_key', nvmeof_server_key, service_name='nvmeof.foo')
+        cephadm_module.cert_key_store.save_key('nvmeof_encryption_key', nvmeof_encryption_key, service_name='nvmeof.foo')
 
         expected_calls = [
             mock.call(f'{CERT_STORE_KEY_PREFIX}grafana_key', json.dumps({'host1': PrivKey(grafana_host1_key).to_json()})),
             mock.call(f'{CERT_STORE_KEY_PREFIX}nvmeof_client_key', json.dumps({'nvmeof.foo': PrivKey(nvmeof_client_key).to_json()})),
             mock.call(f'{CERT_STORE_KEY_PREFIX}nvmeof_server_key', json.dumps({'nvmeof.foo': PrivKey(nvmeof_server_key).to_json()})),
+            mock.call(f'{CERT_STORE_KEY_PREFIX}nvmeof_encryption_key', json.dumps({'nvmeof.foo': PrivKey(nvmeof_encryption_key).to_json()})),
         ]
         _set_store.assert_has_calls(expected_calls)
 
@@ -1822,15 +1825,19 @@ class TestCephadm(object):
             'ingress_ssl_key': False,
             'nvmeof_client_key': False,
             'nvmeof_server_key': False,
+            'nvmeof_encryption_key': False,
         }
         assert cephadm_module.cert_key_store.key_ls() == expected_ls
 
         cephadm_module.cert_key_store.save_key('nvmeof_client_key', 'xxx', service_name='nvmeof.foo')
         cephadm_module.cert_key_store.save_key('nvmeof_server_key', 'xxx', service_name='nvmeof.foo')
+        cephadm_module.cert_key_store.save_key('nvmeof_encryption_key', 'xxx', service_name='nvmeof.foo')
         expected_ls['nvmeof_server_key'] = {}
         expected_ls['nvmeof_server_key']['nvmeof.foo'] = True
         expected_ls['nvmeof_client_key'] = {}
         expected_ls['nvmeof_client_key']['nvmeof.foo'] = True
+        expected_ls['nvmeof_encryption_key'] = {}
+        expected_ls['nvmeof_encryption_key']['nvmeof.foo'] = True
         assert cephadm_module.cert_key_store.key_ls() == expected_ls
 
     @mock.patch("cephadm.module.CephadmOrchestrator.get_store_prefix")
@@ -1844,6 +1851,7 @@ class TestCephadm(object):
         nvmeof_root_ca_cert = 'nvmeof-root-ca-cert'
         nvmeof_server_key = 'nvmeof-server-key'
         nvmeof_client_key = 'nvmeof-client-key'
+        nvmeof_encryption_key = 'nvmeof-encryption-key'
 
         def _fake_prefix_store(key):
             if key == 'cert_store.cert.':
@@ -1858,6 +1866,7 @@ class TestCephadm(object):
                     f'{CERT_STORE_KEY_PREFIX}grafana_key': json.dumps({'host1': PrivKey(grafana_host1_key).to_json()}),
                     f'{CERT_STORE_KEY_PREFIX}nvmeof_server_key': json.dumps({'nvmeof.foo': PrivKey(nvmeof_server_key).to_json()}),
                     f'{CERT_STORE_KEY_PREFIX}nvmeof_client_key': json.dumps({'nvmeof.foo': PrivKey(nvmeof_client_key).to_json()}),
+                    f'{CERT_STORE_KEY_PREFIX}nvmeof_encryption_key': json.dumps({'nvmeof.foo': PrivKey(nvmeof_encryption_key).to_json()}),
                 }
             else:
                 raise Exception(f'Get store with unexpected value {key}')
@@ -1871,6 +1880,7 @@ class TestCephadm(object):
         assert cephadm_module.cert_key_store.known_keys['grafana_key']['host1'] == PrivKey(grafana_host1_key)
         assert cephadm_module.cert_key_store.known_keys['nvmeof_server_key']['nvmeof.foo'] == PrivKey(nvmeof_server_key)
         assert cephadm_module.cert_key_store.known_keys['nvmeof_client_key']['nvmeof.foo'] == PrivKey(nvmeof_client_key)
+        assert cephadm_module.cert_key_store.known_keys['nvmeof_encryption_key']['nvmeof.foo'] == PrivKey(nvmeof_encryption_key)
 
     def test_cert_store_get_cert_key(self, cephadm_module: CephadmOrchestrator):
         cephadm_module.cert_key_store._init_known_cert_key_dicts()
@@ -1898,13 +1908,16 @@ class TestCephadm(object):
 
         grafana_host1_key = 'fake-grafana-host1-cert'
         nvmeof_server_key = 'nvmeof-server-key'
+        nvmeof_encryption_key = 'nvmeof-encryption-key'
         cephadm_module.cert_key_store.save_key('grafana_key', grafana_host1_key, host='host1')
         cephadm_module.cert_key_store.save_key('grafana_key', grafana_host1_key, host='host1')
         cephadm_module.cert_key_store.save_key('nvmeof_server_key', nvmeof_server_key, service_name='nvmeof.foo')
+        cephadm_module.cert_key_store.save_key('nvmeof_encryption_key', nvmeof_encryption_key, service_name='nvmeof.foo')
 
         assert cephadm_module.cert_key_store.get_key('grafana_key', host='host1') == grafana_host1_key
         assert cephadm_module.cert_key_store.get_key('nvmeof_server_key', service_name='nvmeof.foo') == nvmeof_server_key
         assert cephadm_module.cert_key_store.get_key('nvmeof_client_key', service_name='nvmeof.foo') == ''
+        assert cephadm_module.cert_key_store.get_key('nvmeof_encryption_key', service_name='nvmeof.foo') == nvmeof_encryption_key
 
         with pytest.raises(OrchestratorError, match='Attempted to access priv key for unknown entity'):
             cephadm_module.cert_key_store.get_key('unknown_entity')
index 75c7c3c5bf79e322ccf39d1ea6dc4186fb922cf3..1b3c9bdb899dac3271b3a7f6f1fa9d2e6e7586d1 100644 (file)
@@ -399,6 +399,7 @@ state_update_notify = True
 state_update_interval_sec = 5
 enable_spdk_discovery_controller = False
 enable_key_encryption = True
+encryption_key = /encryption.key
 enable_prometheus_exporter = True
 prometheus_exporter_ssl = False
 prometheus_port = 10008
index 10e9f26794000faf228f2f1044a466442198e6d7..ebe66989cc04e4c230b3bde4a2b49828df65e630 100644 (file)
@@ -1335,6 +1335,7 @@ class NvmeofServiceSpec(ServiceSpec):
                  state_update_interval_sec: Optional[int] = 5,
                  enable_spdk_discovery_controller: Optional[bool] = False,
                  enable_key_encryption: Optional[bool] = True,
+                 encryption_key: Optional[str] = None,
                  omap_file_lock_duration: Optional[int] = 20,
                  omap_file_lock_retries: Optional[int] = 30,
                  omap_file_lock_retry_sleep_interval: Optional[float] = 1.0,
@@ -1422,6 +1423,8 @@ class NvmeofServiceSpec(ServiceSpec):
         self.enable_spdk_discovery_controller = enable_spdk_discovery_controller
         #: ``enable_key_encryption`` encrypt DHCHAP and PSK keys before saving in OMAP
         self.enable_key_encryption = enable_key_encryption
+        #: ``encryption_key`` gateway encryption key
+        self.encryption_key = encryption_key
         #: ``enable_prometheus_exporter`` enables Prometheus exporter
         self.enable_prometheus_exporter = enable_prometheus_exporter
         #: ``verify_nqns`` enables verification of subsystem and host NQNs for validity