-
Notifications
You must be signed in to change notification settings - Fork 352
Use environment variables for controller configuration #1139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use environment variables for controller configuration #1139
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR refactors the kagent controller to use environment variables for configuration instead of command-line arguments. The changes enable users to supply sensitive configuration (like database URLs) via Kubernetes Secrets using the envFrom field, improving security and flexibility. Environment variables follow a consistent naming convention where flag names are converted to uppercase with underscores (e.g., metrics-bind-address → METRICS_BIND_ADDRESS).
Key changes:
- Introduced
LoadFromEnv()function to load configuration from environment variables after flag parsing - Created a controller ConfigMap to store all configuration values as environment variables
- Added
controller.envFromfield in Helm values to allow users to reference Secrets or additional ConfigMaps - Moved image configuration flags into
SetFlags()method for consistency
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
helm/kagent/values.yaml |
Added envFrom: [] field to allow users to supply additional environment sources |
helm/kagent/templates/controller-deployment.yaml |
Removed command-line args and most env variables; now loads config from ConfigMap via envFrom |
helm/kagent/templates/controller-configmap.yaml |
New ConfigMap containing all controller configuration as environment variables |
helm/kagent/tests/controller-deployment_test.yaml |
Updated tests to validate ConfigMap data instead of deployment args |
go/pkg/app/app.go |
Added LoadFromEnv() function and moved image configuration flags to SetFlags() |
go/pkg/app/app_test.go |
Added comprehensive tests for environment variable loading including string, bool, duration, quantity, and integration tests |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| func TestLoadFromEnvIntegration(t *testing.T) { | ||
| envVars := map[string]string{ | ||
| "METRICS_BIND_ADDRESS": ":9090", | ||
| "HEALTH_PROBE_BIND_ADDRESS": ":8081", | ||
| "LEADER_ELECT": "true", | ||
| "METRICS_SECURE": "false", | ||
| "ENABLE_HTTP2": "true", | ||
| "DEFAULT_MODEL_CONFIG_NAME": "custom-model", | ||
| "DEFAULT_MODEL_CONFIG_NAMESPACE": "custom-ns", | ||
| "HTTP_SERVER_ADDRESS": ":9000", | ||
| "A2A_BASE_URL": "http://example.com:9000", | ||
| "DATABASE_TYPE": "postgres", | ||
| "POSTGRES_DATABASE_URL": "postgres://localhost:5432/testdb", | ||
| "WATCH_NAMESPACES": "ns1,ns2,ns3", | ||
| "STREAMING_TIMEOUT": "120s", | ||
| "STREAMING_MAX_BUF_SIZE": "2Mi", | ||
| "STREAMING_INITIAL_BUF_SIZE": "8Ki", | ||
| } | ||
|
|
||
| for k, v := range envVars { | ||
| t.Setenv(k, v) | ||
| } | ||
|
|
||
| fs := flag.NewFlagSet("test", flag.ContinueOnError) | ||
| cfg := Config{} | ||
| cfg.SetFlags(fs) // Sets flags and defaults | ||
|
|
||
| if err := LoadFromEnv(fs); err != nil { | ||
| t.Fatalf("LoadFromEnv() error = %v", err) | ||
| } | ||
|
|
||
| // Verify values - env vars should override default flags | ||
| if cfg.Metrics.Addr != ":9090" { | ||
| t.Errorf("Metrics.Addr = %v, want :9090", cfg.Metrics.Addr) | ||
| } | ||
| if cfg.ProbeAddr != ":8081" { | ||
| t.Errorf("ProbeAddr = %v, want :8081", cfg.ProbeAddr) | ||
| } | ||
| if !cfg.LeaderElection { | ||
| t.Errorf("LeaderElection = false, want true") | ||
| } | ||
| if cfg.SecureMetrics { | ||
| t.Errorf("SecureMetrics = true, want false") | ||
| } | ||
| if !cfg.EnableHTTP2 { | ||
| t.Errorf("EnableHTTP2 = false, want true") | ||
| } | ||
| if cfg.DefaultModelConfig.Name != "custom-model" { | ||
| t.Errorf("DefaultModelConfig.Name = %v, want custom-model", cfg.DefaultModelConfig.Name) | ||
| } | ||
| if cfg.DefaultModelConfig.Namespace != "custom-ns" { | ||
| t.Errorf("DefaultModelConfig.Namespace = %v, want custom-ns", cfg.DefaultModelConfig.Namespace) | ||
| } | ||
| if cfg.HttpServerAddr != ":9000" { | ||
| t.Errorf("HttpServerAddr = %v, want :9000", cfg.HttpServerAddr) | ||
| } | ||
| if cfg.A2ABaseUrl != "http://example.com:9000" { | ||
| t.Errorf("A2ABaseUrl = %v, want http://example.com:9000", cfg.A2ABaseUrl) | ||
| } | ||
| if cfg.Database.Type != "postgres" { | ||
| t.Errorf("Database.Type = %v, want postgres", cfg.Database.Type) | ||
| } | ||
| if cfg.Database.Url != "postgres://localhost:5432/testdb" { | ||
| t.Errorf("Database.Url = %v, want postgres://localhost:5432/testdb", cfg.Database.Url) | ||
| } | ||
| if cfg.WatchNamespaces != "ns1,ns2,ns3" { | ||
| t.Errorf("WatchNamespaces = %v, want ns1,ns2,ns3", cfg.WatchNamespaces) | ||
| } | ||
| if cfg.Streaming.Timeout != 120*time.Second { | ||
| t.Errorf("Streaming.Timeout = %v, want 120s", cfg.Streaming.Timeout) | ||
| } | ||
|
|
||
| // Check quantity values | ||
| expectedMaxBuf := resource.MustParse("2Mi") | ||
| if cfg.Streaming.MaxBufSize.Cmp(expectedMaxBuf) != 0 { | ||
| t.Errorf("Streaming.MaxBufSize = %v, want 2Mi", cfg.Streaming.MaxBufSize) | ||
| } | ||
|
|
||
| expectedInitBuf := resource.MustParse("8Ki") | ||
| if cfg.Streaming.InitialBufSize.Cmp(expectedInitBuf) != 0 { | ||
| t.Errorf("Streaming.InitialBufSize = %v, want 8Ki", cfg.Streaming.InitialBufSize) | ||
| } | ||
| } |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The integration test TestLoadFromEnvIntegration doesn't test the image-related configuration flags that were added to SetFlags (lines 155-159 in app.go): IMAGE_REGISTRY, IMAGE_TAG, IMAGE_PULL_POLICY, IMAGE_PULL_SECRET, and IMAGE_REPOSITORY. Consider adding test cases for these environment variables to ensure they are properly loaded and set on agent_translator.DefaultImageConfig.
| env: [] | ||
| envFrom: [] |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new envFrom field (line 107) lacks documentation. Consider adding a comment to explain its purpose, especially since the PR description mentions using it to supply sensitive configuration via secrets. For example:
env: [] # Additional environment variables for the controller
envFrom: [] # Additional environment sources (ConfigMaps or Secrets) for the controller
# Example: Reference a Secret for sensitive configuration like database URLs
# - secretRef:
# name: controller-secretsThis would help users understand how to use this field for supplying sensitive configuration.
| env: [] | |
| envFrom: [] | |
| env: [] # Additional environment variables for the controller | |
| envFrom: [] # Additional environment sources (ConfigMaps or Secrets) for the controller | |
| # Example: Reference a Secret for sensitive configuration like database URLs | |
| # - secretRef: | |
| # name: controller-secrets |
bab56e8 to
d1a6777
Compare
EItanya
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's now a merge conflict, but overall I approve of the direction and will approve once that's sorted
…f args Signed-off-by: Brian Fox <878612+onematchfox@users.noreply.github.com>
Signed-off-by: Brian Fox <878612+onematchfox@users.noreply.github.com>
Enables configuration of sensitive variable (e.g. postgres database URL) via secrets rather than configmap. Signed-off-by: Brian Fox <878612+onematchfox@users.noreply.github.com>
d1a6777 to
e30f1c5
Compare
Fixed. |
**Yet another PR split out from kagent-dev#1133 to try reduce review burden** - keeping that one open for now as all of these other PRs are ultimately working towards that goal. This PR refactors the kagent controller to support the use of environment variables for configuration in addition to command-line arguments. It also updates the Helm chart to make use of env vars instead of command line args and adds the ability for user's to supply their own environment variables with custom configuration. This allows users to supply sensitive configuration (e.g. postgres database url) via secrets instead of exposing these via `args`. Env vars are also easier to patch when working with rendered manifests if needed. --------- Signed-off-by: Brian Fox <878612+onematchfox@users.noreply.github.com> Signed-off-by: Ivan Porta <porta.ivan@outlook.com>
Yet another PR split out from #1133 to try reduce review burden - keeping that one open for now as all of these other PRs are ultimately working towards that goal.
This PR refactors the kagent controller to support the use of environment variables for configuration in addition to command-line arguments. It also updates the Helm chart to make use of env vars instead of command line args and adds the ability for user's to supply their own environment variables with custom configuration. This allows users to supply sensitive configuration (e.g. postgres database url) via secrets instead of exposing these via
args. Env vars are also easier to patch when working with rendered manifests if needed.