config¶
Package config loads Leoflow configuration from defaults, an optional config file, and LEOFLOW_* environment variables, with flags taking precedence.
Index¶
- func DefaultConfigFile() (string, error)
- type AuthSection
- type CORSSection
- type Config
- func Load(configFile string, flags *pflag.FlagSet) (*Config, error)
- type DatabaseSection
- type DispatchSection
- type ExecutorSection
- type HTTPExecutorSection
- type JWTSection
- type LogsSection
- type OTelSection
- type ObservabilitySection
- type PlatformDefaultsSection
- type RedisSection
- type SchedulerSection
- type ServerConfig
- func LoadServer(configFile string, flags *pflag.FlagSet) (*ServerConfig, error)
- func (c *ServerConfig) Validate() error
- type ServerSection
- type UISection
func DefaultConfigFile¶
DefaultConfigFile returns the default configuration file path, \~/.leoflow/config.yaml.
type AuthSection¶
AuthSection configures authentication.
type AuthSection struct {
Provider string `mapstructure:"provider"`
JWT JWTSection `mapstructure:"jwt"`
// DevNoAuth disables authentication entirely, treating every request as an
// admin. It exists ONLY for `leoflow dev` (local, unsandboxed). It is false by
// default and the server logs a prominent warning when it is on. NEVER set
// this in production (LEOFLOW_AUTH_DEV_NO_AUTH).
DevNoAuth bool `mapstructure:"dev_no_auth"`
// LoginRateLimitPerMinute caps failed /auth/token attempts per client IP per
// minute (anti-brute-force). Only failures count, so a successful login never
// consumes budget. Lite raises this well above the production default because
// it is a local single-user tool where lockouts are pure friction.
LoginRateLimitPerMinute int `mapstructure:"login_rate_limit_per_minute"`
}
type CORSSection¶
CORSSection configures cross-origin access.
type Config¶
Config holds the developer CLI configuration.
type Config struct {
// ServerURL is the control plane base URL used by push and auth create-token.
ServerURL string `mapstructure:"server_url"`
// LogLevel is reserved for CLI log verbosity (not yet wired).
LogLevel string `mapstructure:"log_level"`
// Registry is reserved for the image registry used by image build (ADR 0003).
Registry string `mapstructure:"registry"`
// ParserCmd is the command used to invoke the Python parser from compile.
ParserCmd string `mapstructure:"parser_cmd"`
// Lite-edition settings written by `leoflow setup` and read by `leoflow lite`.
// Workspace is the default directory holding the user's DAG projects.
Workspace string `mapstructure:"workspace"`
// LiteExecutor is the chosen executor: "subprocess" (local) or "k8s" (mini-cluster).
LiteExecutor string `mapstructure:"lite_executor"`
// LitePort is the UI/API port for the Lite control plane.
LitePort int `mapstructure:"lite_port"`
// AdminEmail is the Lite admin login created at bootstrap.
AdminEmail string `mapstructure:"admin_email"`
// AdminPasswordHash is the bcrypt hash of the generated admin password; the
// plaintext is shown once at setup and never stored (Lite only).
AdminPasswordHash string `mapstructure:"admin_password_hash"`
// JWTSecret is the per-install Lite JWT signing secret, generated by
// `leoflow setup` (random, 64 hex chars) and persisted alongside the admin
// hash. Rotating it on every fresh install invalidates browser tokens from a
// prior install โ so a reinstall greets the user with the login screen and
// the freshly printed credentials actually do something (#121). Empty on
// legacy installs; the lite runner falls back to the dev-only constant with
// a warning so the upgrade does not break existing setups.
JWTSecret string `mapstructure:"jwt_secret"`
}
func Load¶
Load assembles configuration from defaults, the given file (when non-empty), LEOFLOW_* environment variables, and the provided flag set, in increasing order of precedence. A nil flag set or empty file path is ignored.
type DatabaseSection¶
DatabaseSection configures the Postgres connection pool.
type DatabaseSection struct {
URL string `mapstructure:"url"`
MaxOpenConns int `mapstructure:"max_open_conns"`
MaxIdleConns int `mapstructure:"max_idle_conns"`
}
type DispatchSection¶
DispatchSection sizes the BufferedDispatcher (#127). BufferSize=0 keeps the scheduler tick synchronous with the inner dispatcher โ the right shape for Lite (subprocess fork is microseconds). BufferSize>0 enables the worker pool โ the right shape for Pro (Kubernetes API calls add real latency). The defaults are set per-edition by configsetup so the user does not have to think about this; an operator can still tune the knobs.
type DispatchSection struct {
// BufferSize is the depth of the queued-dispatches channel. 0 disables the
// pool (synchronous passthrough). A full channel returns ErrAtCapacity to
// the scheduler, which leaves the TI scheduled for the next tick.
BufferSize int `mapstructure:"buffer_size"`
// Workers is the number of goroutines draining the queue. Ignored when
// BufferSize <= 0; otherwise floored to 1.
Workers int `mapstructure:"workers"`
}
type ExecutorSection¶
ExecutorSection configures how tasks are executed.
type ExecutorSection struct {
HTTP HTTPExecutorSection `mapstructure:"http"`
// Type selects the pod-path executor: "kubernetes" (default, pod-per-task) or
// "subprocess" (dev only, runs the agent on the host without isolation, used
// by `leoflow dev`).
Type string `mapstructure:"type"`
// AgentPath is the leoflow-agent binary the subprocess executor runs (dev only).
AgentPath string `mapstructure:"agent_path"`
// SubprocessWorkDir is the working directory the subprocess executor runs the
// agent in, so it can import the project's dag.py (dev only). Empty keeps the
// server's working directory.
SubprocessWorkDir string `mapstructure:"subprocess_workdir"`
// AgentControlPlaneAddr is the gRPC address task pods dial back to. Empty
// falls back to server.grpc_addr; in a local k3d/kind cluster set it to a
// host-reachable address such as host.k3d.internal:9091.
AgentControlPlaneAddr string `mapstructure:"agent_control_plane_addr"`
// AgentTLSCAConfigMap names a ConfigMap (key ca.crt) mounted into task pods so
// the agent verifies the control plane's gRPC TLS cert (issue #58). Empty =
// agents use the insecure channel (dev).
AgentTLSCAConfigMap string `mapstructure:"agent_tls_ca_configmap"`
// TaskSecretName names a Kubernetes Secret mounted (read-only) into every task
// pod at TaskSecretMountPath. It lets a task read a credential that lives in
// the cluster's secret store (e.g. a GCP service-account key) referenced by a
// connection's key_path โ so Leoflow never stores the key itself (ADR 0035).
// Empty = no secret mounted.
TaskSecretName string `mapstructure:"task_secret_name"`
// TaskSecretMountPath is where TaskSecretName is mounted in the task pod.
TaskSecretMountPath string `mapstructure:"task_secret_mount_path"`
// Defaults holds per-cluster task defaults applied at dispatch to fill gaps the
// DAG artifact left empty (ADR 0023, layer L0). They never override a value
// baked into dag.json, keeping the artifact portable across clusters.
Defaults PlatformDefaultsSection `mapstructure:"defaults"`
}
type HTTPExecutorSection¶
HTTPExecutorSection configures the inline http_api execution path (ADR 0002).
type HTTPExecutorSection struct {
// InlineMaxDurationSeconds caps how long an inline http_api task may run; a
// task declaring a longer execution_timeout_seconds must use execution_mode: pod.
InlineMaxDurationSeconds int `mapstructure:"inline_max_duration_seconds"`
// InlineConcurrencyLimit bounds the number of in-flight inline goroutines.
InlineConcurrencyLimit int `mapstructure:"inline_concurrency_limit"`
// UserAgent is the User-Agent header sent on inline http_api requests.
UserAgent string `mapstructure:"user_agent"`
}
type JWTSection¶
JWTSection configures JWT issuance and validation.
type JWTSection struct {
Secret string `mapstructure:"secret"`
TokenTTLSeconds int `mapstructure:"token_ttl_seconds"`
}
type LogsSection¶
LogsSection configures task log shipping.
type LogsSection struct {
// Dir is the root directory for the disk log sink.
Dir string `mapstructure:"dir"`
}
type OTelSection¶
OTelSection configures OpenTelemetry export.
type OTelSection struct {
Enabled bool `mapstructure:"enabled"`
Endpoint string `mapstructure:"endpoint"`
}
type ObservabilitySection¶
ObservabilitySection configures logging, metrics, and tracing.
type ObservabilitySection struct {
OTel OTelSection `mapstructure:"otel"`
LogLevel string `mapstructure:"log_level"`
LogFormat string `mapstructure:"log_format"`
}
type PlatformDefaultsSection¶
PlatformDefaultsSection configures the lowest-precedence (L0) task defaults, applied at dispatch to fill gaps the DAG left empty (ADR 0023).
type PlatformDefaultsSection struct {
// StagingSize/StagingStorageClass default the per-run staging volume when the
// DAG enabled staging without pinning them (e.g. the cluster's RWX class).
StagingSize string `mapstructure:"staging_size"`
StagingStorageClass string `mapstructure:"staging_storage_class"`
// StagingAccessMode is the PVC access mode for the staging volume. Defaults to
// ReadWriteMany (multi-node prod); single-node dev (k3d local-path, no RWX)
// sets ReadWriteOnce, which is sufficient for a run's sequential same-node pods.
StagingAccessMode string `mapstructure:"staging_access_mode"`
// ResourcesCPU/ResourcesMemory default a task's request when neither the task
// override nor the DAG set any (Kubernetes quantities, e.g. "250m"/"256Mi").
ResourcesCPU string `mapstructure:"resources_cpu"`
ResourcesMemory string `mapstructure:"resources_memory"`
}
type RedisSection¶
RedisSection configures the Redis connection.
type RedisSection struct {
URL string `mapstructure:"url"`
// CAFile is the absolute path to a PEM CA bundle the client trusts when
// negotiating TLS to a `rediss://` URL (#312). Required to reach managed
// Redis (Memorystore SERVER_AUTHENTICATION, ElastiCache in-transit
// encryption, Azure Cache for Redis) whose server cert is signed by a
// provider / per-instance CA that is not in the container's system
// roots. Empty falls back to the SDK default โ system roots only.
// The Helm chart sets this via LEOFLOW_REDIS_CA_FILE when
// `redis.caConfigMap` is configured, pointing at the mounted ConfigMap.
CAFile string `mapstructure:"ca_file"`
}
type SchedulerSection¶
SchedulerSection configures the scheduler loop.
type SchedulerSection struct {
LoopIntervalMS int `mapstructure:"loop_interval_ms"`
Enabled bool `mapstructure:"enabled"`
Dispatch DispatchSection `mapstructure:"dispatch"`
}
type ServerConfig¶
ServerConfig is the full configuration for the leoflow-server control plane. It mirrors the nested YAML described in the Phase 2 prompt.
type ServerConfig struct {
Server ServerSection `mapstructure:"server"`
Database DatabaseSection `mapstructure:"database"`
Redis RedisSection `mapstructure:"redis"`
Auth AuthSection `mapstructure:"auth"`
Scheduler SchedulerSection `mapstructure:"scheduler"`
Executor ExecutorSection `mapstructure:"executor"`
Logs LogsSection `mapstructure:"logs"`
Observability ObservabilitySection `mapstructure:"observability"`
UI UISection `mapstructure:"ui"`
// SecretKey (LEOFLOW_SECRET_KEY) is the 32-byte key encrypting connection
// secrets at rest (ADR 0019). Raw 32 chars, 64-char hex, or base64. Empty
// disables connection writes.
SecretKey string `mapstructure:"secret_key"`
}
func LoadServer¶
LoadServer assembles the server configuration from defaults, the given file, LEOFLOW_* environment variables, and flags, in increasing precedence.
func (*ServerConfig) Validate¶
Validate reports configuration errors that must abort startup.
type ServerSection¶
ServerSection configures the HTTP, metrics, and agent gRPC listeners.
type ServerSection struct {
HTTPAddr string `mapstructure:"http_addr"`
MetricsAddr string `mapstructure:"metrics_addr"`
GRPCAddr string `mapstructure:"grpc_addr"`
CORS CORSSection `mapstructure:"cors"`
// GRPCTLSCert/GRPCTLSKey enable TLS on the agent gRPC listener (issue #58).
// When both are set the channel is encrypted; empty means plaintext (dev).
GRPCTLSCert string `mapstructure:"grpc_tls_cert"`
GRPCTLSKey string `mapstructure:"grpc_tls_key"`
}
type UISection¶
UISection configures the embedded Airflow UI.
type UISection struct {
// InstanceName is shown in the UI navbar (Airflow's instance_name). Empty
// falls back to "Leoflow"; `leoflow lite` sets it to mark the environment.
InstanceName string `mapstructure:"instance_name"`
// AutoRefreshIntervalSeconds is the SPA's polling cadence for DAG /
// DagRun / task-instance state refresh (Airflow's auto_refresh_interval).
// Zero (the default) falls back to api.DefaultUIAutoRefreshIntervalSeconds
// (30s, production-safe). `leoflow lite` sets it to 1s for a snappy inner
// loop so the SPA reflects state changes almost immediately during dev.
AutoRefreshIntervalSeconds int `mapstructure:"auto_refresh_interval_seconds"`
// Edition marks the running edition; "lite" shows the silver LITE badge and
// "pro" shows the gold PRO badge in the UI shell (independent of the auth
// mode). Empty/any other value shows no badge โ Demo intentionally renders
// without an edition pill.
Edition string `mapstructure:"edition"`
// Workspace is the DAG project directory the Lite web editor edits (ADR 0025).
// Empty disables the editor (Production, or Lite without one).
Workspace string `mapstructure:"workspace"`
// MonacoDir is where the pinned Monaco bundle was fetched by `leoflow setup`;
// the editor page is served Monaco from it. Empty shows a setup hint.
MonacoDir string `mapstructure:"monaco_dir"`
}
Generated by gomarkdoc