Skip to content

Configuration and State Management

The CLI manages configuration through two distinct persistence layers: a primary cluster definition file and a kubectl-style contexts store. The primary configuration, loaded from ~/.config/dap-cli/config.json, defines the target cluster’s network endpoints and identity realm. This file is typically bootstrapped via dap config init and is immutable during normal operation. User contexts, which bind specific clusters and users to an active session, are managed separately in ~/.config/dap-cli/contexts.json. This separation ensures that non-secret state (cluster URLs, user metadata, context bindings) is persisted consistently across invocations, while sensitive credentials are isolated in a separate, restricted store.

The core cluster configuration is defined by the ClusterConfig dataclass and loaded via the load_config function in src/dap/config/loader.py. By default, the CLI reads from ~/.config/dap-cli/config.json 1. This file contains the portal URL, orchestrator URL, Keycloak realm UUID, and an optional CA bundle. The load_config function parses this JSON file and raises a DapError if the file is missing, malformed, or missing required keys like name or portal_url.

The dap config init command is responsible for creating this file. It accepts a portal URL and optionally an orchestrator URL and realm UUID 2. If the orchestrator URL is omitted, it is derived by substituting ‘dap-portal’ with ‘dap-orchestrator’ in the portal URL. If the realm UUID is omitted, the CLI attempts to auto-discover it from the portal; if discovery fails, it prompts the user for manual input. The resulting JSON is written to the target path with 0o644 permissions.

Credentials are resolved dynamically at runtime via the get_credential function, which implements a resolver chain 1. The function first checks for the requested key in the environment variables (e.g., DAP_ADMIN_PASSWORD). If not found, it checks for an age-encrypted bundle if both DAP_CREDS_AGE_FILE and DAP_AGE_IDENTITY environment variables are set and the files exist. It executes the age CLI tool to decrypt the bundle and parses the output for the matching key. If neither source provides the credential, a DapError is raised with a hint to the operator.

Secrets are also managed via the CredentialStore class, which persists tokens and client secrets to a separate location with 0600 permissions 3. The dap config set-credentials command allows users to update user metadata (non-secret) in the contexts store while simultaneously storing secrets in the CredentialStore. If a client secret is not provided via CLI flags, the command prompts for it interactively.

The contexts store, defined in src/dap/rest/config.py, provides a kubectl-style interface for managing clusters, users, and contexts 4. It is persisted to ~/.config/dap-cli/contexts.json. This store contains three main lists: clusters, users, and contexts, along with a current_context pointer.

  • Clusters: Defined by Cluster dataclass, containing server URL, TLS verification settings, and optional CA bundle or proxy URL.
  • Users: Defined by User dataclass, containing non-secret metadata like client_id, tenant_id, and grant_type. Secrets are not stored here.
  • Contexts: Defined by Context dataclass, binding a portal_cluster and portal_user to an orchestrator_cluster and orchestrator_user, along with an outcome (neo, dpc, ai) and optional namespace.

The Config class provides methods to load, save, and mutate this store. It supports upsert operations for clusters, users, and contexts by name. The resolve_binding function uses the active context (or a specified context name) to determine the correct cluster and user for a given component (portal or orchestrator). If the context is missing or references non-existent clusters/users, it raises a DapError.

The dap config group provides several subcommands for managing the contexts store, registered in src/dap/rest/config_cmds.py:

  • set-cluster: Creates or updates a cluster entry 3.
  • set-credentials: Creates or updates a user entry and stores secrets in the CredentialStore.
  • set-context: Creates or updates a context, optionally setting it as the current context using the --use flag.
  • use-context: Switches the current context to the specified name.
  • current-context: Prints the name of the current context.
  • rename-context: Renames an existing context.
  • get-clusters, get-users, get-contexts: Lists configured entries, marking the current context with an asterisk.
  • delete-cluster, delete-user, delete-context: Removes entries by name.
  • view: Prints the entire contexts store with secrets redacted.
  • validate: Checks for consistency, ensuring referenced clusters and users exist and the current context is valid.
diagram