Skip to content

Conversation

@onematchfox
Copy link
Contributor

@onematchfox onematchfox commented Nov 26, 2025

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.

Copy link
Contributor

Copilot AI left a 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-addressMETRICS_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.envFrom field 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.

Comment on lines +251 to +333
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)
}
}
Copy link

Copilot AI Nov 26, 2025

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.

Copilot uses AI. Check for mistakes.
Comment on lines 106 to +107
env: []
envFrom: []
Copy link

Copilot AI Nov 26, 2025

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-secrets

This would help users understand how to use this field for supplying sensitive configuration.

Suggested change
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

Copilot uses AI. Check for mistakes.
@onematchfox onematchfox force-pushed the controller-config-env-vars branch 2 times, most recently from bab56e8 to d1a6777 Compare November 27, 2025 09:13
Copy link
Contributor

@EItanya EItanya left a 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>
@onematchfox onematchfox force-pushed the controller-config-env-vars branch from d1a6777 to e30f1c5 Compare December 2, 2025 07:44
@onematchfox
Copy link
Contributor Author

There's now a merge conflict, but overall I approve of the direction and will approve once that's sorted

Fixed.

@EItanya EItanya merged commit d2cdd9d into kagent-dev:main Dec 2, 2025
17 checks passed
@onematchfox onematchfox deleted the controller-config-env-vars branch December 2, 2025 15:01
GTRekter pushed a commit to GTRekter/kagent that referenced this pull request Dec 4, 2025
**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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants