From: Redouane Kachach Date: Mon, 26 Jan 2026 13:40:43 +0000 (+0100) Subject: mgr/ceph_secrets: add storage backend protocol for mgr KV secrets X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=16ae0b3d2bef1b83f1a8a75d2026a9cbd5c372d8;p=ceph.git mgr/ceph_secrets: add storage backend protocol for mgr KV secrets 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 Assisted-by: ChatGPT Signed-off-by: Redouane Kachach --- diff --git a/src/pybind/mgr/ceph_secrets/backends.py b/src/pybind/mgr/ceph_secrets/backends.py new file mode 100644 index 000000000000..83da430d7b36 --- /dev/null +++ b/src/pybind/mgr/ceph_secrets/backends.py @@ -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 index 000000000000..af276da72410 --- /dev/null +++ b/src/pybind/mgr/ceph_secrets/secret_backend.py @@ -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.""" + ...