Files
lib-secret-manager/secret_manager/credentials_loader.py
T

62 lines
1.8 KiB
Python

import logging
import os
from typing import Set
logger = logging.getLogger(__name__)
class MissingCredentialError(RuntimeError):
"""Neither the environment variable nor the secret file provided a value."""
def get_secret(env_var: str, path: str | None = None) -> str:
"""Resolve a secret from an environment variable, falling back to a file.
Resolution order:
1. The environment variable ``env_var`` (if set and non-empty).
2. The file at ``path`` (if given and it exists).
Raises:
MissingCredentialError: If neither source provides a value.
"""
value = os.getenv(env_var, "").strip()
if value:
logger.debug(f"Loaded secret from environment variable {env_var}")
return value
if path:
try:
return return_credentials(path)
except FileNotFoundError:
pass
sources = f"environment variable {env_var}" + (f" or file {path}" if path else "")
raise MissingCredentialError(f"No credential found: set {sources}")
def return_credentials(path: str) -> str:
"""Read and return credentials from a file."""
logger.debug(f"Opening credentials for path:{path}")
try:
with open(path) as file:
return file.read().strip()
except FileNotFoundError:
logger.fatal(f"[FATAL] Secret file not found: {path}")
raise
except Exception as e:
logger.fatal(f"[FATAL] Failed to read secret file {path}: {e}")
raise
def cleanup_secret_files(secret_paths: Set[str]) -> None:
"""Delete secret files after they've been loaded into memory.
Args:
secret_paths: Set of file paths to delete
"""
for path in secret_paths:
try:
if os.path.exists(path):
os.remove(path)
logger.debug(f"Deleted secret file: {path}")
else:
logger.debug(f"Secret file already removed: {path}")
except Exception as e:
logger.warning(f"Could not delete secret file {path}: {e}")