]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/ceph_secrets: add storage backend protocol for mgr KV secrets
authorRedouane Kachach <rkachach@ibm.com>
Mon, 26 Jan 2026 13:40:43 +0000 (14:40 +0100)
committerRedouane Kachach <rkachach@ibm.com>
Thu, 11 Jun 2026 08:45:58 +0000 (10:45 +0200)
Define a minimal backend protocol for secret persistence
operations (get/set/rm/list), keeping the module implementation
decoupled from the backing store details. For now we will start with
monstore-db as secure KV store but the idea is to extend this to other
backends such as Vault.

Fixes: https://tracker.ceph.com/issues/74562
Assisted-by: Claude <claude.ai>
Assisted-by: ChatGPT <chatgpt.com>
Signed-off-by: Redouane Kachach <rkachach@ibm.com>
src/pybind/mgr/ceph_secrets/backends.py [new file with mode: 0644]
src/pybind/mgr/ceph_secrets/secret_backend.py [new file with mode: 0644]

diff --git a/src/pybind/mgr/ceph_secrets/backends.py b/src/pybind/mgr/ceph_secrets/backends.py
new file mode 100644 (file)
index 0000000..83da430
--- /dev/null
@@ -0,0 +1,5 @@
+from .secret_store import SecretStoreMon
+
+BACKENDS = {
+    "mon": SecretStoreMon,
+}
diff --git a/src/pybind/mgr/ceph_secrets/secret_backend.py b/src/pybind/mgr/ceph_secrets/secret_backend.py
new file mode 100644 (file)
index 0000000..af276da
--- /dev/null
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+from __future__ import annotations
+
+from abc import ABC, abstractmethod
+from typing import List, Optional, TYPE_CHECKING
+from ceph_secrets_types import SecretScope
+
+
+if TYPE_CHECKING:
+    # Import only for type-checkers to avoid runtime import cycles
+    from .secret_store import SecretRecord
+
+
+class SecretStorageBackend(ABC):
+    """
+    Abstract base class for ceph secrets storage backends.
+
+    Backends store secret instances addressed by:
+      (namespace, scope, target, name)
+
+    For custom scope, target is empty and name stores the free-form path suffix.
+
+    Epoch:
+      Each namespace has an independent monotonic epoch counter that is bumped
+      on every set and on rm only when an existing secret is actually removed.
+      Consumers can use get_epoch(namespace) as a cheap change-detector to
+      avoid re-fetching secrets when nothing changed in their namespace.
+
+    Implementations:
+      - SecretStoreMon  (Mon KV store)
+      - Vault backend (future)
+    """
+
+    @abstractmethod
+    def get(self, namespace: str, scope: SecretScope, target: str, name: str) -> Optional["SecretRecord"]:
+        ...
+
+    @abstractmethod
+    def set(
+        self,
+        namespace: str,
+        scope: SecretScope,
+        target: str,
+        name: str,
+        data: str,
+        user_made: bool = True,
+        editable: bool = True,
+    ) -> "SecretRecord":
+        ...
+
+    @abstractmethod
+    def rm(self, namespace: str, scope: SecretScope, target: str, name: str) -> bool:
+        ...
+
+    @abstractmethod
+    def ls(
+        self,
+        namespace: Optional[str] = None,
+        scope: Optional[SecretScope] = None,
+        target: Optional[str] = None,
+    ) -> List["SecretRecord"]:
+        ...
+
+    @abstractmethod
+    def get_epoch(self, namespace: str) -> int:
+        """Return the current epoch for *namespace*."""
+        ...
+
+    @abstractmethod
+    def bump_epoch(self, namespace: str) -> int:
+        """Increment and persist the epoch for *namespace*; return the new value."""
+        ...