"""Utilities for reading the pre-seeded Cerbos policy metadata from Redis.""" import logging from ddtrace.trace import tracer from pdp.connectors.cerbos_policy_parser import PolicyMetadataDatabase from pdp.connectors.redis_client import NullSerializer, RedisConnector from pdp.constants.constants import CACHE_ENTRY_CERBOS_POLICY_METADATA logger = logging.getLogger(__name__) class CerbosPolicyDBLookupError(Exception): pass class CerbosPolicyDBParseError(Exception): pass @tracer.wrap() async def get_cerbos_policy_metadata( redis_connector: RedisConnector, ) -> PolicyMetadataDatabase: """Read the pre-seeded policy metadata database from Redis. Raises CerbosPolicyDBLookupError if the key is missing — a missing key indicates a misconfigured deployment and should surface as a 500. Raises CerbosPolicyDBParseError if the cached value cannot be deserialized. """ raw: str | None = await redis_connector.get( key=CACHE_ENTRY_CERBOS_POLICY_METADATA, serializer=NullSerializer() ) if raw is None: msg = ( f"Cache entry '{CACHE_ENTRY_CERBOS_POLICY_METADATA}' not found. " "Run 'make seed_policy_metadata_cache' (or the Jenkins stage) " "to populate it." ) logger.error(msg) raise CerbosPolicyDBLookupError(msg) try: return PolicyMetadataDatabase.from_json(raw) except Exception as exc: msg = ( f"Failed to parse cache entry '{CACHE_ENTRY_CERBOS_POLICY_METADATA}': {exc}" ) logger.error(msg) raise CerbosPolicyDBParseError(msg) from exc