feat(vaults): tolerate vault failures during key get/add

Wrap vault get_key/add_key/add_keys calls in broad exception handlers so a single failing vault (network, auth, driver error) no longer aborts the operation - other vaults are still consulted/written. Failure cause is logged at WARNING so issues remain debuggable.

Inspired by unshackle-dl/unshackle#104 by @CodeName393.

Co-authored-by: CodeName393 <62503817+CodeName393@users.noreply.github.com>
This commit is contained in:
imSp4rky
2026-05-17 12:18:32 -06:00
parent 13dcd7aa1a
commit 64da561534

View File

@@ -1,3 +1,4 @@
import logging
from typing import Any, Iterator, Optional, Union from typing import Any, Iterator, Optional, Union
from uuid import UUID from uuid import UUID
@@ -5,6 +6,8 @@ from unshackle.core.config import config
from unshackle.core.utilities import import_module_by_path from unshackle.core.utilities import import_module_by_path
from unshackle.core.vault import Vault from unshackle.core.vault import Vault
log = logging.getLogger(__name__)
_VAULTS = sorted( _VAULTS = sorted(
(path for path in config.directories.vaults.glob("*.py") if path.stem.lower() != "__init__"), key=lambda x: x.stem (path for path in config.directories.vaults.glob("*.py") if path.stem.lower() != "__init__"), key=lambda x: x.stem
) )
@@ -48,7 +51,13 @@ class Vaults:
def get_key(self, kid: Union[UUID, str]) -> tuple[Optional[str], Optional[Vault]]: def get_key(self, kid: Union[UUID, str]) -> tuple[Optional[str], Optional[Vault]]:
"""Get Key from the first Vault it can by KID (Key ID) and Service.""" """Get Key from the first Vault it can by KID (Key ID) and Service."""
for vault in self.vaults: for vault in self.vaults:
key = vault.get_key(kid, self.service) try:
key = vault.get_key(kid, self.service)
except (PermissionError, NotImplementedError):
continue
except Exception as e:
log.warning(f"Failed to get key from Vault '{vault.name}': {e}")
continue
if key and key.count("0") != len(key): if key and key.count("0") != len(key):
return key, vault return key, vault
return None, None return None, None
@@ -62,6 +71,8 @@ class Vaults:
success += vault.add_key(self.service, kid, key) success += vault.add_key(self.service, kid, key)
except (PermissionError, NotImplementedError): except (PermissionError, NotImplementedError):
pass pass
except Exception as e:
log.warning(f"Failed to add key to Vault '{vault.name}': {e}")
return success return success
def add_keys(self, kid_keys: dict[Union[UUID, str], str]) -> int: def add_keys(self, kid_keys: dict[Union[UUID, str], str]) -> int:
@@ -79,6 +90,8 @@ class Vaults:
success += 1 success += 1
except (PermissionError, NotImplementedError): except (PermissionError, NotImplementedError):
pass pass
except Exception as e:
log.warning(f"Failed to add keys to Vault '{vault.name}': {e}")
return success return success