From 0098e6aef8e932271b80aa78e23632f84726e3ce Mon Sep 17 00:00:00 2001 From: Safwan Date: Tue, 21 Jul 2026 18:21:02 +0500 Subject: [PATCH 1/9] refactor: expose decision engine in public pkg --- cmd/reloader/main.go | 11 ++-- internal/pkg/alerting/alerter.go | 2 +- internal/pkg/alerting/alerter_test.go | 2 +- internal/pkg/config/{ => flags}/flags.go | 10 ++-- internal/pkg/config/{ => flags}/flags_test.go | 52 ++++++++++--------- .../pkg/controller/configmap_reconciler.go | 4 +- .../controller/configmap_reconciler_test.go | 2 +- .../pkg/controller/deployment_reconciler.go | 4 +- internal/pkg/controller/filter.go | 4 +- internal/pkg/controller/filter_test.go | 2 +- internal/pkg/controller/handler.go | 2 +- internal/pkg/controller/manager.go | 4 +- .../pkg/controller/namespace_reconciler.go | 4 +- .../controller/namespace_reconciler_test.go | 2 +- .../pkg/controller/resource_reconciler.go | 4 +- internal/pkg/controller/retry.go | 2 +- internal/pkg/controller/retry_test.go | 4 +- internal/pkg/controller/secret_reconciler.go | 4 +- .../pkg/controller/secret_reconciler_test.go | 2 +- .../secretproviderclass_filter_test.go | 4 +- .../secretproviderclass_reconciler.go | 4 +- .../secretproviderclass_reconciler_test.go | 4 +- internal/pkg/controller/test_helpers_test.go | 4 +- {internal/pkg => pkg}/config/config.go | 0 {internal/pkg => pkg}/config/config_test.go | 0 {internal/pkg => pkg}/config/validation.go | 0 .../pkg => pkg}/config/validation_test.go | 0 {internal/pkg => pkg}/metadata/metadata.go | 2 +- .../pkg => pkg}/metadata/metadata_test.go | 2 +- {internal/pkg => pkg}/metadata/publisher.go | 2 +- {internal/pkg => pkg}/reload/change.go | 0 {internal/pkg => pkg}/reload/change_test.go | 0 .../pkg => pkg}/reload/csi_dep_check_test.go | 0 {internal/pkg => pkg}/reload/decision.go | 3 ++ {internal/pkg => pkg}/reload/decision_test.go | 0 {internal/pkg => pkg}/reload/hasher.go | 0 {internal/pkg => pkg}/reload/hasher_test.go | 0 {internal/pkg => pkg}/reload/matcher.go | 2 +- {internal/pkg => pkg}/reload/matcher_test.go | 2 +- {internal/pkg => pkg}/reload/pause.go | 5 +- {internal/pkg => pkg}/reload/pause_test.go | 2 +- {internal/pkg => pkg}/reload/predicate.go | 2 +- .../pkg => pkg}/reload/predicate_test.go | 2 +- {internal/pkg => pkg}/reload/resource_type.go | 0 .../pkg => pkg}/reload/resource_type_test.go | 0 {internal/pkg => pkg}/reload/service.go | 6 ++- {internal/pkg => pkg}/reload/service_test.go | 2 +- {internal/pkg => pkg}/reload/strategy.go | 2 +- {internal/pkg => pkg}/reload/strategy_test.go | 2 +- 49 files changed, 94 insertions(+), 79 deletions(-) rename internal/pkg/config/{ => flags}/flags.go (98%) rename internal/pkg/config/{ => flags}/flags_test.go (93%) rename {internal/pkg => pkg}/config/config.go (100%) rename {internal/pkg => pkg}/config/config_test.go (100%) rename {internal/pkg => pkg}/config/validation.go (100%) rename {internal/pkg => pkg}/config/validation_test.go (100%) rename {internal/pkg => pkg}/metadata/metadata.go (98%) rename {internal/pkg => pkg}/metadata/metadata_test.go (99%) rename {internal/pkg => pkg}/metadata/publisher.go (98%) rename {internal/pkg => pkg}/reload/change.go (100%) rename {internal/pkg => pkg}/reload/change_test.go (100%) rename {internal/pkg => pkg}/reload/csi_dep_check_test.go (100%) rename {internal/pkg => pkg}/reload/decision.go (84%) rename {internal/pkg => pkg}/reload/decision_test.go (100%) rename {internal/pkg => pkg}/reload/hasher.go (100%) rename {internal/pkg => pkg}/reload/hasher_test.go (100%) rename {internal/pkg => pkg}/reload/matcher.go (99%) rename {internal/pkg => pkg}/reload/matcher_test.go (99%) rename {internal/pkg => pkg}/reload/pause.go (94%) rename {internal/pkg => pkg}/reload/pause_test.go (99%) rename {internal/pkg => pkg}/reload/predicate.go (99%) rename {internal/pkg => pkg}/reload/predicate_test.go (99%) rename {internal/pkg => pkg}/reload/resource_type.go (100%) rename {internal/pkg => pkg}/reload/resource_type_test.go (100%) rename {internal/pkg => pkg}/reload/service.go (96%) rename {internal/pkg => pkg}/reload/service_test.go (99%) rename {internal/pkg => pkg}/reload/strategy.go (99%) rename {internal/pkg => pkg}/reload/strategy_test.go (99%) diff --git a/cmd/reloader/main.go b/cmd/reloader/main.go index 35151f9ba..ff7ba9af8 100644 --- a/cmd/reloader/main.go +++ b/cmd/reloader/main.go @@ -17,12 +17,13 @@ import ( "k8s.io/client-go/discovery" controllerruntime "sigs.k8s.io/controller-runtime" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/internal/pkg/config/flags" "github.com/stakater/Reloader/internal/pkg/controller" "github.com/stakater/Reloader/internal/pkg/csi" - "github.com/stakater/Reloader/internal/pkg/metadata" "github.com/stakater/Reloader/internal/pkg/metrics" "github.com/stakater/Reloader/internal/pkg/openshift" + "github.com/stakater/Reloader/pkg/config" + "github.com/stakater/Reloader/pkg/metadata" ) // Environment variable names for pod identity in HA mode. @@ -49,12 +50,12 @@ func newReloaderCommand() *cobra.Command { RunE: run, } - config.BindFlags(cmd.PersistentFlags(), cfg) + flags.BindFlags(cmd.PersistentFlags(), cfg) return cmd } func run(cmd *cobra.Command, args []string) error { - if err := config.ApplyFlags(cfg); err != nil { + if err := flags.ApplyFlags(cfg); err != nil { return fmt.Errorf("applying flags: %w", err) } @@ -115,7 +116,7 @@ func run(cmd *cobra.Command, args []string) error { log.V(1).Info("Failed to create discovery client", "error", discErr) } - if config.ShouldAutoDetectOpenShift() { + if flags.ShouldAutoDetectOpenShift() { if discoveryClient != nil && openshift.HasDeploymentConfigSupport(discoveryClient, log) { cfg.DeploymentConfigEnabled = true } diff --git a/internal/pkg/alerting/alerter.go b/internal/pkg/alerting/alerter.go index edbc22812..1d9cf224d 100644 --- a/internal/pkg/alerting/alerter.go +++ b/internal/pkg/alerting/alerter.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" ) // AlertMessage contains the details of a reload event to be sent as an alert. diff --git a/internal/pkg/alerting/alerter_test.go b/internal/pkg/alerting/alerter_test.go index d6ae4ad40..30b68e223 100644 --- a/internal/pkg/alerting/alerter_test.go +++ b/internal/pkg/alerting/alerter_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" ) // testServer creates a test HTTP server that captures the request body. diff --git a/internal/pkg/config/flags.go b/internal/pkg/config/flags/flags.go similarity index 98% rename from internal/pkg/config/flags.go rename to internal/pkg/config/flags/flags.go index 784fef108..87ef26ba5 100644 --- a/internal/pkg/config/flags.go +++ b/internal/pkg/config/flags/flags.go @@ -1,4 +1,4 @@ -package config +package flags import ( "fmt" @@ -8,6 +8,8 @@ import ( "github.com/spf13/pflag" "github.com/spf13/viper" "k8s.io/apimachinery/pkg/labels" + + "github.com/stakater/Reloader/pkg/config" ) // v is the viper instance for configuration. @@ -22,7 +24,7 @@ func init() { // BindFlags binds configuration flags to the provided flag set. // Call this before parsing flags, then call ApplyFlags after parsing. -func BindFlags(fs *pflag.FlagSet, cfg *Config) { +func BindFlags(fs *pflag.FlagSet, cfg *config.Config) { // Auto reload fs.Bool( "auto-reload-all", cfg.AutoReloadAll, @@ -265,7 +267,7 @@ func BindFlags(fs *pflag.FlagSet, cfg *Config) { // ApplyFlags applies flag values from viper to the config struct. // Call this after parsing flags. -func ApplyFlags(cfg *Config) error { +func ApplyFlags(cfg *config.Config) error { // Boolean flags cfg.AutoReloadAll = v.GetBool("auto-reload-all") cfg.SyncAfterRestart = v.GetBool("sync-after-restart") @@ -287,7 +289,7 @@ func ApplyFlags(cfg *Config) error { } // String flags - cfg.ReloadStrategy = ReloadStrategy(v.GetString("reload-strategy")) + cfg.ReloadStrategy = config.ReloadStrategy(v.GetString("reload-strategy")) cfg.WebhookURL = v.GetString("webhook-url") cfg.LogFormat = v.GetString("log-format") cfg.LogLevel = v.GetString("log-level") diff --git a/internal/pkg/config/flags_test.go b/internal/pkg/config/flags/flags_test.go similarity index 93% rename from internal/pkg/config/flags_test.go rename to internal/pkg/config/flags/flags_test.go index f9c6819a2..9bd67fa17 100644 --- a/internal/pkg/config/flags_test.go +++ b/internal/pkg/config/flags/flags_test.go @@ -1,4 +1,4 @@ -package config +package flags import ( "strings" @@ -6,6 +6,8 @@ import ( "github.com/spf13/pflag" "github.com/spf13/viper" + + "github.com/stakater/Reloader/pkg/config" ) // resetViper resets the viper instance for testing. @@ -17,7 +19,7 @@ func resetViper() { func TestBindFlags(t *testing.T) { resetViper() - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -83,7 +85,7 @@ func TestBindFlags(t *testing.T) { func TestBindFlags_DefaultValues(t *testing.T) { resetViper() - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -96,8 +98,8 @@ func TestBindFlags_DefaultValues(t *testing.T) { t.Fatalf("ApplyFlags() error = %v", err) } - if cfg.ReloadStrategy != ReloadStrategyEnvVars { - t.Errorf("ReloadStrategy = %v, want %v", cfg.ReloadStrategy, ReloadStrategyEnvVars) + if cfg.ReloadStrategy != config.ReloadStrategyEnvVars { + t.Errorf("ReloadStrategy = %v, want %v", cfg.ReloadStrategy, config.ReloadStrategyEnvVars) } if cfg.LogLevel != "info" { @@ -107,7 +109,7 @@ func TestBindFlags_DefaultValues(t *testing.T) { func TestBindFlags_CustomValues(t *testing.T) { resetViper() - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -134,8 +136,8 @@ func TestBindFlags_CustomValues(t *testing.T) { t.Error("AutoReloadAll should be true") } - if cfg.ReloadStrategy != ReloadStrategyAnnotations { - t.Errorf("ReloadStrategy = %v, want %v", cfg.ReloadStrategy, ReloadStrategyAnnotations) + if cfg.ReloadStrategy != config.ReloadStrategyAnnotations { + t.Errorf("ReloadStrategy = %v, want %v", cfg.ReloadStrategy, config.ReloadStrategyAnnotations) } if cfg.LogLevel != "debug" { @@ -162,7 +164,7 @@ func TestBindFlags_CustomValues(t *testing.T) { func TestApplyFlags_SecretProviderClassAnnotations(t *testing.T) { // Defaults are preserved when the flags are not provided. resetViper() - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) if err := fs.Parse(nil); err != nil { @@ -171,7 +173,7 @@ func TestApplyFlags_SecretProviderClassAnnotations(t *testing.T) { if err := ApplyFlags(cfg); err != nil { t.Fatalf("ApplyFlags() error = %v", err) } - defaults := DefaultAnnotations() + defaults := config.DefaultAnnotations() if cfg.Annotations.SecretProviderClassAuto != defaults.SecretProviderClassAuto { t.Errorf("SecretProviderClassAuto = %q, want default %q", cfg.Annotations.SecretProviderClassAuto, defaults.SecretProviderClassAuto) } @@ -184,7 +186,7 @@ func TestApplyFlags_SecretProviderClassAnnotations(t *testing.T) { // Custom values are applied from the flags. resetViper() - cfg = NewDefault() + cfg = config.NewDefault() fs = pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) args := []string{ @@ -212,7 +214,7 @@ func TestApplyFlags_SecretProviderClassAnnotations(t *testing.T) { func TestApplyFlags_ExcludeAnnotations(t *testing.T) { // Defaults are preserved when the flags are not provided. resetViper() - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) if err := fs.Parse(nil); err != nil { @@ -221,7 +223,7 @@ func TestApplyFlags_ExcludeAnnotations(t *testing.T) { if err := ApplyFlags(cfg); err != nil { t.Fatalf("ApplyFlags() error = %v", err) } - defaults := DefaultAnnotations() + defaults := config.DefaultAnnotations() if cfg.Annotations.ConfigmapExclude != defaults.ConfigmapExclude { t.Errorf("ConfigmapExclude = %q, want default %q", cfg.Annotations.ConfigmapExclude, defaults.ConfigmapExclude) } @@ -231,7 +233,7 @@ func TestApplyFlags_ExcludeAnnotations(t *testing.T) { // Custom values are applied from the flags. resetViper() - cfg = NewDefault() + cfg = config.NewDefault() fs = pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) args := []string{ @@ -255,7 +257,7 @@ func TestApplyFlags_ExcludeAnnotations(t *testing.T) { func TestApplyFlags_IgnoreAnnotation(t *testing.T) { // Default is preserved when the flag is not provided. resetViper() - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) if err := fs.Parse(nil); err != nil { @@ -264,13 +266,13 @@ func TestApplyFlags_IgnoreAnnotation(t *testing.T) { if err := ApplyFlags(cfg); err != nil { t.Fatalf("ApplyFlags() error = %v", err) } - if cfg.Annotations.Ignore != DefaultAnnotations().Ignore { - t.Errorf("Ignore = %q, want default %q", cfg.Annotations.Ignore, DefaultAnnotations().Ignore) + if cfg.Annotations.Ignore != config.DefaultAnnotations().Ignore { + t.Errorf("Ignore = %q, want default %q", cfg.Annotations.Ignore, config.DefaultAnnotations().Ignore) } // Custom value is applied from the flag. resetViper() - cfg = NewDefault() + cfg = config.NewDefault() fs = pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) if err := fs.Parse([]string{"--ignore-annotation=my.company.com/reloader-ignore"}); err != nil { @@ -305,7 +307,7 @@ func TestApplyFlags_BooleanStrings(t *testing.T) { t.Run( tt.name, func(t *testing.T) { resetViper() - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -329,7 +331,7 @@ func TestApplyFlags_BooleanStrings(t *testing.T) { func TestApplyFlags_CommaSeparatedLists(t *testing.T) { resetViper() - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -365,7 +367,7 @@ func TestApplyFlags_CommaSeparatedLists(t *testing.T) { func TestApplyFlags_Selectors(t *testing.T) { resetViper() - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -397,7 +399,7 @@ func TestApplyFlags_Selectors(t *testing.T) { func TestApplyFlags_InvalidSelector(t *testing.T) { resetViper() - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -453,7 +455,7 @@ func TestApplyFlags_AlertingEnvVars(t *testing.T) { t.Setenv(k, val) } - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -486,7 +488,7 @@ func TestApplyFlags_LegacyProxyEnvVar(t *testing.T) { t.Setenv("ALERT_WEBHOOK_PROXY", "http://legacy-proxy:8080") - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -505,7 +507,7 @@ func TestApplyFlags_LegacyProxyEnvVar(t *testing.T) { func TestApplyFlagsCSIIntegration(t *testing.T) { resetViper() - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) if err := fs.Parse([]string{"--enable-csi-integration=true"}); err != nil { diff --git a/internal/pkg/controller/configmap_reconciler.go b/internal/pkg/controller/configmap_reconciler.go index 04bd3bb3f..96c17b5a1 100644 --- a/internal/pkg/controller/configmap_reconciler.go +++ b/internal/pkg/controller/configmap_reconciler.go @@ -9,10 +9,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/stakater/Reloader/internal/pkg/alerting" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/events" "github.com/stakater/Reloader/internal/pkg/metrics" - "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/pkg/reload" "github.com/stakater/Reloader/internal/pkg/webhook" "github.com/stakater/Reloader/internal/pkg/workload" ) diff --git a/internal/pkg/controller/configmap_reconciler_test.go b/internal/pkg/controller/configmap_reconciler_test.go index 1b1140577..c8c6c2507 100644 --- a/internal/pkg/controller/configmap_reconciler_test.go +++ b/internal/pkg/controller/configmap_reconciler_test.go @@ -3,7 +3,7 @@ package controller_test import ( "testing" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/testutil" ) diff --git a/internal/pkg/controller/deployment_reconciler.go b/internal/pkg/controller/deployment_reconciler.go index ebc1b759a..402b40126 100644 --- a/internal/pkg/controller/deployment_reconciler.go +++ b/internal/pkg/controller/deployment_reconciler.go @@ -10,8 +10,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/predicate" - "github.com/stakater/Reloader/internal/pkg/config" - "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/pkg/config" + "github.com/stakater/Reloader/pkg/reload" ) // DeploymentReconciler reconciles Deployment objects to handle pause expiration. diff --git a/internal/pkg/controller/filter.go b/internal/pkg/controller/filter.go index 7503bc40b..e66939cce 100644 --- a/internal/pkg/controller/filter.go +++ b/internal/pkg/controller/filter.go @@ -6,8 +6,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/predicate" - "github.com/stakater/Reloader/internal/pkg/config" - "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/pkg/config" + "github.com/stakater/Reloader/pkg/reload" ) // BuildEventFilter combines a resource-specific predicate with common filters. diff --git a/internal/pkg/controller/filter_test.go b/internal/pkg/controller/filter_test.go index 16b2ae8ea..420194ae4 100644 --- a/internal/pkg/controller/filter_test.go +++ b/internal/pkg/controller/filter_test.go @@ -8,7 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/event" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" ) func TestCreateEventPredicate_CreateEvent(t *testing.T) { diff --git a/internal/pkg/controller/handler.go b/internal/pkg/controller/handler.go index 062001846..a5732ba12 100644 --- a/internal/pkg/controller/handler.go +++ b/internal/pkg/controller/handler.go @@ -11,7 +11,7 @@ import ( "github.com/stakater/Reloader/internal/pkg/alerting" "github.com/stakater/Reloader/internal/pkg/events" "github.com/stakater/Reloader/internal/pkg/metrics" - "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/pkg/reload" "github.com/stakater/Reloader/internal/pkg/webhook" "github.com/stakater/Reloader/internal/pkg/workload" ) diff --git a/internal/pkg/controller/manager.go b/internal/pkg/controller/manager.go index 869bdf001..d9762d324 100644 --- a/internal/pkg/controller/manager.go +++ b/internal/pkg/controller/manager.go @@ -18,10 +18,10 @@ import ( csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1" "github.com/stakater/Reloader/internal/pkg/alerting" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/events" "github.com/stakater/Reloader/internal/pkg/metrics" - "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/pkg/reload" "github.com/stakater/Reloader/internal/pkg/webhook" "github.com/stakater/Reloader/internal/pkg/workload" ) diff --git a/internal/pkg/controller/namespace_reconciler.go b/internal/pkg/controller/namespace_reconciler.go index 4e220fd5e..5159a1b40 100644 --- a/internal/pkg/controller/namespace_reconciler.go +++ b/internal/pkg/controller/namespace_reconciler.go @@ -11,8 +11,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "github.com/stakater/Reloader/internal/pkg/config" - "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/pkg/config" + "github.com/stakater/Reloader/pkg/reload" ) // NamespaceCache provides thread-safe access to the set of namespaces diff --git a/internal/pkg/controller/namespace_reconciler_test.go b/internal/pkg/controller/namespace_reconciler_test.go index 604dca92a..db1a7c824 100644 --- a/internal/pkg/controller/namespace_reconciler_test.go +++ b/internal/pkg/controller/namespace_reconciler_test.go @@ -5,7 +5,7 @@ import ( "k8s.io/apimachinery/pkg/labels" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/controller" "github.com/stakater/Reloader/internal/pkg/testutil" ) diff --git a/internal/pkg/controller/resource_reconciler.go b/internal/pkg/controller/resource_reconciler.go index 1476d6423..621e759dd 100644 --- a/internal/pkg/controller/resource_reconciler.go +++ b/internal/pkg/controller/resource_reconciler.go @@ -11,10 +11,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/predicate" "github.com/stakater/Reloader/internal/pkg/alerting" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/events" "github.com/stakater/Reloader/internal/pkg/metrics" - "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/pkg/reload" "github.com/stakater/Reloader/internal/pkg/webhook" "github.com/stakater/Reloader/internal/pkg/workload" ) diff --git a/internal/pkg/controller/retry.go b/internal/pkg/controller/retry.go index ffb30615e..802d1b69c 100644 --- a/internal/pkg/controller/retry.go +++ b/internal/pkg/controller/retry.go @@ -7,7 +7,7 @@ import ( "k8s.io/client-go/util/retry" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/pkg/reload" "github.com/stakater/Reloader/internal/pkg/workload" ) diff --git a/internal/pkg/controller/retry_test.go b/internal/pkg/controller/retry_test.go index ff33c0b55..ab3517225 100644 --- a/internal/pkg/controller/retry_test.go +++ b/internal/pkg/controller/retry_test.go @@ -13,9 +13,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/controller" - "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/pkg/reload" "github.com/stakater/Reloader/internal/pkg/testutil" "github.com/stakater/Reloader/internal/pkg/workload" ) diff --git a/internal/pkg/controller/secret_reconciler.go b/internal/pkg/controller/secret_reconciler.go index b50c75476..ac16cc4f6 100644 --- a/internal/pkg/controller/secret_reconciler.go +++ b/internal/pkg/controller/secret_reconciler.go @@ -9,10 +9,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/stakater/Reloader/internal/pkg/alerting" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/events" "github.com/stakater/Reloader/internal/pkg/metrics" - "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/pkg/reload" "github.com/stakater/Reloader/internal/pkg/webhook" "github.com/stakater/Reloader/internal/pkg/workload" ) diff --git a/internal/pkg/controller/secret_reconciler_test.go b/internal/pkg/controller/secret_reconciler_test.go index f55e84a80..e8688801b 100644 --- a/internal/pkg/controller/secret_reconciler_test.go +++ b/internal/pkg/controller/secret_reconciler_test.go @@ -3,7 +3,7 @@ package controller_test import ( "testing" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/testutil" ) diff --git a/internal/pkg/controller/secretproviderclass_filter_test.go b/internal/pkg/controller/secretproviderclass_filter_test.go index 4c49cc5dc..6f569a885 100644 --- a/internal/pkg/controller/secretproviderclass_filter_test.go +++ b/internal/pkg/controller/secretproviderclass_filter_test.go @@ -8,8 +8,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/event" csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1" - "github.com/stakater/Reloader/internal/pkg/config" - "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/pkg/config" + "github.com/stakater/Reloader/pkg/reload" ) // TestSecretProviderClassReconciler_FilterIgnoresResourceLabelSelector pins the diff --git a/internal/pkg/controller/secretproviderclass_reconciler.go b/internal/pkg/controller/secretproviderclass_reconciler.go index 710a1eb9d..e921a8d75 100644 --- a/internal/pkg/controller/secretproviderclass_reconciler.go +++ b/internal/pkg/controller/secretproviderclass_reconciler.go @@ -12,8 +12,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1" - "github.com/stakater/Reloader/internal/pkg/config" - "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/pkg/config" + "github.com/stakater/Reloader/pkg/reload" ) // SecretProviderClassReconciler watches SecretProviderClassPodStatus (the per-pod diff --git a/internal/pkg/controller/secretproviderclass_reconciler_test.go b/internal/pkg/controller/secretproviderclass_reconciler_test.go index 2ba6bae71..7114a8345 100644 --- a/internal/pkg/controller/secretproviderclass_reconciler_test.go +++ b/internal/pkg/controller/secretproviderclass_reconciler_test.go @@ -10,9 +10,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/controller" - "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/pkg/reload" "github.com/stakater/Reloader/internal/pkg/testutil" ) diff --git a/internal/pkg/controller/test_helpers_test.go b/internal/pkg/controller/test_helpers_test.go index 2b0f9e75b..cd23486f0 100644 --- a/internal/pkg/controller/test_helpers_test.go +++ b/internal/pkg/controller/test_helpers_test.go @@ -13,11 +13,11 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" "github.com/stakater/Reloader/internal/pkg/alerting" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/controller" "github.com/stakater/Reloader/internal/pkg/events" "github.com/stakater/Reloader/internal/pkg/metrics" - "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/pkg/reload" "github.com/stakater/Reloader/internal/pkg/testutil" "github.com/stakater/Reloader/internal/pkg/webhook" "github.com/stakater/Reloader/internal/pkg/workload" diff --git a/internal/pkg/config/config.go b/pkg/config/config.go similarity index 100% rename from internal/pkg/config/config.go rename to pkg/config/config.go diff --git a/internal/pkg/config/config_test.go b/pkg/config/config_test.go similarity index 100% rename from internal/pkg/config/config_test.go rename to pkg/config/config_test.go diff --git a/internal/pkg/config/validation.go b/pkg/config/validation.go similarity index 100% rename from internal/pkg/config/validation.go rename to pkg/config/validation.go diff --git a/internal/pkg/config/validation_test.go b/pkg/config/validation_test.go similarity index 100% rename from internal/pkg/config/validation_test.go rename to pkg/config/validation_test.go diff --git a/internal/pkg/metadata/metadata.go b/pkg/metadata/metadata.go similarity index 98% rename from internal/pkg/metadata/metadata.go rename to pkg/metadata/metadata.go index df306af4e..efa238a19 100644 --- a/internal/pkg/metadata/metadata.go +++ b/pkg/metadata/metadata.go @@ -11,7 +11,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" ) const ( diff --git a/internal/pkg/metadata/metadata_test.go b/pkg/metadata/metadata_test.go similarity index 99% rename from internal/pkg/metadata/metadata_test.go rename to pkg/metadata/metadata_test.go index 52c5f1997..9a36f956d 100644 --- a/internal/pkg/metadata/metadata_test.go +++ b/pkg/metadata/metadata_test.go @@ -11,7 +11,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" ) // testLogger returns a no-op logger for testing. diff --git a/internal/pkg/metadata/publisher.go b/pkg/metadata/publisher.go similarity index 98% rename from internal/pkg/metadata/publisher.go rename to pkg/metadata/publisher.go index 6c6a42221..64749459e 100644 --- a/internal/pkg/metadata/publisher.go +++ b/pkg/metadata/publisher.go @@ -10,8 +10,8 @@ import ( "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/stakater/Reloader/internal/pkg/config" "github.com/stakater/Reloader/internal/pkg/workload" + "github.com/stakater/Reloader/pkg/config" ) // Publisher handles creating and updating the metadata ConfigMap. diff --git a/internal/pkg/reload/change.go b/pkg/reload/change.go similarity index 100% rename from internal/pkg/reload/change.go rename to pkg/reload/change.go diff --git a/internal/pkg/reload/change_test.go b/pkg/reload/change_test.go similarity index 100% rename from internal/pkg/reload/change_test.go rename to pkg/reload/change_test.go diff --git a/internal/pkg/reload/csi_dep_check_test.go b/pkg/reload/csi_dep_check_test.go similarity index 100% rename from internal/pkg/reload/csi_dep_check_test.go rename to pkg/reload/csi_dep_check_test.go diff --git a/internal/pkg/reload/decision.go b/pkg/reload/decision.go similarity index 84% rename from internal/pkg/reload/decision.go rename to pkg/reload/decision.go index 625925828..ac3b264bb 100644 --- a/internal/pkg/reload/decision.go +++ b/pkg/reload/decision.go @@ -5,6 +5,9 @@ import ( ) // ReloadDecision contains the result of evaluating whether to reload a workload. +// +// NOTE: not part of the public API — the Workload field is an internal/pkg/workload +// type and is therefore not usable from outside this module. type ReloadDecision struct { // Workload is the workload accessor. Workload workload.Workload diff --git a/internal/pkg/reload/decision_test.go b/pkg/reload/decision_test.go similarity index 100% rename from internal/pkg/reload/decision_test.go rename to pkg/reload/decision_test.go diff --git a/internal/pkg/reload/hasher.go b/pkg/reload/hasher.go similarity index 100% rename from internal/pkg/reload/hasher.go rename to pkg/reload/hasher.go diff --git a/internal/pkg/reload/hasher_test.go b/pkg/reload/hasher_test.go similarity index 100% rename from internal/pkg/reload/hasher_test.go rename to pkg/reload/hasher_test.go diff --git a/internal/pkg/reload/matcher.go b/pkg/reload/matcher.go similarity index 99% rename from internal/pkg/reload/matcher.go rename to pkg/reload/matcher.go index 9fb8ba119..a7ddc50a1 100644 --- a/internal/pkg/reload/matcher.go +++ b/pkg/reload/matcher.go @@ -4,7 +4,7 @@ import ( "regexp" "strings" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" ) // MatchResult contains the result of checking if a workload should be reloaded. diff --git a/internal/pkg/reload/matcher_test.go b/pkg/reload/matcher_test.go similarity index 99% rename from internal/pkg/reload/matcher_test.go rename to pkg/reload/matcher_test.go index b683ffb16..f51c56381 100644 --- a/internal/pkg/reload/matcher_test.go +++ b/pkg/reload/matcher_test.go @@ -3,7 +3,7 @@ package reload import ( "testing" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" ) func TestMatcher_ShouldReload(t *testing.T) { diff --git a/internal/pkg/reload/pause.go b/pkg/reload/pause.go similarity index 94% rename from internal/pkg/reload/pause.go rename to pkg/reload/pause.go index e995dc33c..bc8d02e02 100644 --- a/internal/pkg/reload/pause.go +++ b/pkg/reload/pause.go @@ -6,11 +6,14 @@ import ( appsv1 "k8s.io/api/apps/v1" - "github.com/stakater/Reloader/internal/pkg/config" "github.com/stakater/Reloader/internal/pkg/workload" + "github.com/stakater/Reloader/pkg/config" ) // PauseHandler handles pause deployment logic. +// +// NOTE: not part of the public API — its methods reference internal/pkg/workload +// and are therefore not usable from outside this module. type PauseHandler struct { cfg *config.Config } diff --git a/internal/pkg/reload/pause_test.go b/pkg/reload/pause_test.go similarity index 99% rename from internal/pkg/reload/pause_test.go rename to pkg/reload/pause_test.go index 1962194d1..76bc869dc 100644 --- a/internal/pkg/reload/pause_test.go +++ b/pkg/reload/pause_test.go @@ -7,8 +7,8 @@ import ( appsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/stakater/Reloader/internal/pkg/config" "github.com/stakater/Reloader/internal/pkg/workload" + "github.com/stakater/Reloader/pkg/config" ) func TestPauseHandler_ShouldPause(t *testing.T) { diff --git a/internal/pkg/reload/predicate.go b/pkg/reload/predicate.go similarity index 99% rename from internal/pkg/reload/predicate.go rename to pkg/reload/predicate.go index 38fa58416..21846d0a1 100644 --- a/internal/pkg/reload/predicate.go +++ b/pkg/reload/predicate.go @@ -7,7 +7,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/predicate" csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" ) // resourcePredicates returns predicates for filtering resource events. diff --git a/internal/pkg/reload/predicate_test.go b/pkg/reload/predicate_test.go similarity index 99% rename from internal/pkg/reload/predicate_test.go rename to pkg/reload/predicate_test.go index f62e292cc..fd57c4d2a 100644 --- a/internal/pkg/reload/predicate_test.go +++ b/pkg/reload/predicate_test.go @@ -9,7 +9,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/event" csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" ) func TestNamespaceFilterPredicate_Create(t *testing.T) { diff --git a/internal/pkg/reload/resource_type.go b/pkg/reload/resource_type.go similarity index 100% rename from internal/pkg/reload/resource_type.go rename to pkg/reload/resource_type.go diff --git a/internal/pkg/reload/resource_type_test.go b/pkg/reload/resource_type_test.go similarity index 100% rename from internal/pkg/reload/resource_type_test.go rename to pkg/reload/resource_type_test.go diff --git a/internal/pkg/reload/service.go b/pkg/reload/service.go similarity index 96% rename from internal/pkg/reload/service.go rename to pkg/reload/service.go index 346539d62..88f256660 100644 --- a/internal/pkg/reload/service.go +++ b/pkg/reload/service.go @@ -9,11 +9,15 @@ import ( "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" - "github.com/stakater/Reloader/internal/pkg/config" "github.com/stakater/Reloader/internal/pkg/workload" + "github.com/stakater/Reloader/pkg/config" ) // Service orchestrates the reload logic for ConfigMaps and Secrets. +// +// NOTE: not part of the public API — its methods reference internal/pkg/workload +// and are therefore not usable from outside this module. External, decision-only +// consumers should use Matcher instead. type Service struct { cfg *config.Config log logr.Logger diff --git a/internal/pkg/reload/service_test.go b/pkg/reload/service_test.go similarity index 99% rename from internal/pkg/reload/service_test.go rename to pkg/reload/service_test.go index 9d12554da..b2c868fe9 100644 --- a/internal/pkg/reload/service_test.go +++ b/pkg/reload/service_test.go @@ -10,9 +10,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1" - "github.com/stakater/Reloader/internal/pkg/config" "github.com/stakater/Reloader/internal/pkg/testutil" "github.com/stakater/Reloader/internal/pkg/workload" + "github.com/stakater/Reloader/pkg/config" ) func TestService_ProcessConfigMap_AutoReload(t *testing.T) { diff --git a/internal/pkg/reload/strategy.go b/pkg/reload/strategy.go similarity index 99% rename from internal/pkg/reload/strategy.go rename to pkg/reload/strategy.go index 8881362ea..1e85c6207 100644 --- a/internal/pkg/reload/strategy.go +++ b/pkg/reload/strategy.go @@ -9,7 +9,7 @@ import ( corev1 "k8s.io/api/core/v1" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" ) const ( diff --git a/internal/pkg/reload/strategy_test.go b/pkg/reload/strategy_test.go similarity index 99% rename from internal/pkg/reload/strategy_test.go rename to pkg/reload/strategy_test.go index 305711359..3702ce665 100644 --- a/internal/pkg/reload/strategy_test.go +++ b/pkg/reload/strategy_test.go @@ -6,7 +6,7 @@ import ( corev1 "k8s.io/api/core/v1" - "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/pkg/config" ) func TestEnvVarStrategy_Apply(t *testing.T) { From fcee92dc29192a33d19fb2a2d255bdf0ce61f003 Mon Sep 17 00:00:00 2001 From: Safwan Date: Tue, 21 Jul 2026 19:51:17 +0500 Subject: [PATCH 2/9] refactor: extract matcher into separate package --- .../pkg/controller/configmap_reconciler.go | 7 +-- .../controller/configmap_reconciler_test.go | 2 +- .../pkg/controller/deployment_reconciler.go | 2 +- internal/pkg/controller/filter.go | 2 +- internal/pkg/controller/handler.go | 9 ++-- internal/pkg/controller/manager.go | 4 +- .../pkg/controller/namespace_reconciler.go | 2 +- .../controller/namespace_reconciler_test.go | 2 +- .../pkg/controller/resource_reconciler.go | 7 +-- internal/pkg/controller/retry.go | 13 +++--- internal/pkg/controller/retry_test.go | 37 ++++++++-------- internal/pkg/controller/secret_reconciler.go | 7 +-- .../pkg/controller/secret_reconciler_test.go | 2 +- .../secretproviderclass_filter_test.go | 2 +- .../secretproviderclass_reconciler.go | 5 ++- .../secretproviderclass_reconciler_test.go | 4 +- internal/pkg/controller/test_helpers_test.go | 4 +- {pkg => internal/pkg}/reload/change.go | 36 ++++++++------- {pkg => internal/pkg}/reload/change_test.go | 4 +- .../pkg}/reload/csi_dep_check_test.go | 0 {pkg => internal/pkg}/reload/decision.go | 4 +- {pkg => internal/pkg}/reload/decision_test.go | 0 {pkg => internal/pkg}/reload/hasher.go | 0 {pkg => internal/pkg}/reload/hasher_test.go | 0 {pkg => internal/pkg}/reload/pause.go | 3 -- {pkg => internal/pkg}/reload/pause_test.go | 0 {pkg => internal/pkg}/reload/predicate.go | 0 .../pkg}/reload/predicate_test.go | 0 {pkg => internal/pkg}/reload/service.go | 44 +++++++++---------- {pkg => internal/pkg}/reload/service_test.go | 41 ++++++++--------- {pkg => internal/pkg}/reload/strategy.go | 11 ++--- {pkg => internal/pkg}/reload/strategy_test.go | 37 ++++++++-------- pkg/{reload => matcher}/matcher.go | 6 ++- pkg/{reload => matcher}/matcher_test.go | 2 +- pkg/{reload => matcher}/resource_type.go | 2 +- pkg/{reload => matcher}/resource_type_test.go | 2 +- 36 files changed, 157 insertions(+), 146 deletions(-) rename {pkg => internal/pkg}/reload/change.go (56%) rename {pkg => internal/pkg}/reload/change_test.go (91%) rename {pkg => internal/pkg}/reload/csi_dep_check_test.go (100%) rename {pkg => internal/pkg}/reload/decision.go (84%) rename {pkg => internal/pkg}/reload/decision_test.go (100%) rename {pkg => internal/pkg}/reload/hasher.go (100%) rename {pkg => internal/pkg}/reload/hasher_test.go (100%) rename {pkg => internal/pkg}/reload/pause.go (95%) rename {pkg => internal/pkg}/reload/pause_test.go (100%) rename {pkg => internal/pkg}/reload/predicate.go (100%) rename {pkg => internal/pkg}/reload/predicate_test.go (100%) rename {pkg => internal/pkg}/reload/service.go (89%) rename {pkg => internal/pkg}/reload/service_test.go (95%) rename {pkg => internal/pkg}/reload/strategy.go (95%) rename {pkg => internal/pkg}/reload/strategy_test.go (87%) rename pkg/{reload => matcher}/matcher.go (95%) rename pkg/{reload => matcher}/matcher_test.go (99%) rename pkg/{reload => matcher}/resource_type.go (98%) rename pkg/{reload => matcher}/resource_type_test.go (98%) diff --git a/internal/pkg/controller/configmap_reconciler.go b/internal/pkg/controller/configmap_reconciler.go index 96c17b5a1..44195ca8d 100644 --- a/internal/pkg/controller/configmap_reconciler.go +++ b/internal/pkg/controller/configmap_reconciler.go @@ -9,12 +9,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/stakater/Reloader/internal/pkg/alerting" - "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/events" "github.com/stakater/Reloader/internal/pkg/metrics" - "github.com/stakater/Reloader/pkg/reload" + "github.com/stakater/Reloader/internal/pkg/reload" "github.com/stakater/Reloader/internal/pkg/webhook" "github.com/stakater/Reloader/internal/pkg/workload" + "github.com/stakater/Reloader/pkg/config" + "github.com/stakater/Reloader/pkg/matcher" ) // ConfigMapReconciler watches ConfigMaps and triggers workload reloads. @@ -49,7 +50,7 @@ func NewConfigMapReconciler( NamespaceCache: nsCache, }, ResourceConfig[*corev1.ConfigMap]{ - ResourceType: reload.ResourceTypeConfigMap, + ResourceType: matcher.ResourceTypeConfigMap, NewResource: func() *corev1.ConfigMap { return &corev1.ConfigMap{} }, CreateChange: func(cm *corev1.ConfigMap, eventType reload.EventType) reload.ResourceChange { return reload.ConfigMapChange{ConfigMap: cm, EventType: eventType} diff --git a/internal/pkg/controller/configmap_reconciler_test.go b/internal/pkg/controller/configmap_reconciler_test.go index c8c6c2507..fd530a6c2 100644 --- a/internal/pkg/controller/configmap_reconciler_test.go +++ b/internal/pkg/controller/configmap_reconciler_test.go @@ -3,8 +3,8 @@ package controller_test import ( "testing" - "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/testutil" + "github.com/stakater/Reloader/pkg/config" ) func TestConfigMapReconciler_NotFound(t *testing.T) { diff --git a/internal/pkg/controller/deployment_reconciler.go b/internal/pkg/controller/deployment_reconciler.go index 402b40126..c35330acc 100644 --- a/internal/pkg/controller/deployment_reconciler.go +++ b/internal/pkg/controller/deployment_reconciler.go @@ -10,8 +10,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/predicate" + "github.com/stakater/Reloader/internal/pkg/reload" "github.com/stakater/Reloader/pkg/config" - "github.com/stakater/Reloader/pkg/reload" ) // DeploymentReconciler reconciles Deployment objects to handle pause expiration. diff --git a/internal/pkg/controller/filter.go b/internal/pkg/controller/filter.go index e66939cce..d18fa5b5c 100644 --- a/internal/pkg/controller/filter.go +++ b/internal/pkg/controller/filter.go @@ -6,8 +6,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/predicate" + "github.com/stakater/Reloader/internal/pkg/reload" "github.com/stakater/Reloader/pkg/config" - "github.com/stakater/Reloader/pkg/reload" ) // BuildEventFilter combines a resource-specific predicate with common filters. diff --git a/internal/pkg/controller/handler.go b/internal/pkg/controller/handler.go index a5732ba12..cffcb1b41 100644 --- a/internal/pkg/controller/handler.go +++ b/internal/pkg/controller/handler.go @@ -11,9 +11,10 @@ import ( "github.com/stakater/Reloader/internal/pkg/alerting" "github.com/stakater/Reloader/internal/pkg/events" "github.com/stakater/Reloader/internal/pkg/metrics" - "github.com/stakater/Reloader/pkg/reload" + "github.com/stakater/Reloader/internal/pkg/reload" "github.com/stakater/Reloader/internal/pkg/webhook" "github.com/stakater/Reloader/internal/pkg/workload" + "github.com/stakater/Reloader/pkg/matcher" ) // ReloadHandler handles the common reload workflow. @@ -32,7 +33,7 @@ type ReloadHandler struct { func (h *ReloadHandler) Process( ctx context.Context, namespace, resourceName string, - resourceType reload.ResourceType, + resourceType matcher.ResourceType, getDecisions func([]workload.Workload) []reload.ReloadDecision, log logr.Logger, ) (ctrl.Result, error) { @@ -76,7 +77,7 @@ func (h *ReloadHandler) Process( func (h *ReloadHandler) sendWebhook( ctx context.Context, resourceName, namespace string, - resourceType reload.ResourceType, + resourceType matcher.ResourceType, decisions []reload.ReloadDecision, log logr.Logger, ) (ctrl.Result, error) { @@ -127,7 +128,7 @@ func (h *ReloadHandler) sendWebhook( func (h *ReloadHandler) applyReloads( ctx context.Context, resourceName, resourceNamespace string, - resourceType reload.ResourceType, + resourceType matcher.ResourceType, decisions []reload.ReloadDecision, log logr.Logger, ) { diff --git a/internal/pkg/controller/manager.go b/internal/pkg/controller/manager.go index d9762d324..beed0b7c4 100644 --- a/internal/pkg/controller/manager.go +++ b/internal/pkg/controller/manager.go @@ -18,12 +18,12 @@ import ( csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1" "github.com/stakater/Reloader/internal/pkg/alerting" - "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/events" "github.com/stakater/Reloader/internal/pkg/metrics" - "github.com/stakater/Reloader/pkg/reload" + "github.com/stakater/Reloader/internal/pkg/reload" "github.com/stakater/Reloader/internal/pkg/webhook" "github.com/stakater/Reloader/internal/pkg/workload" + "github.com/stakater/Reloader/pkg/config" ) var runtimeScheme = runtime.NewScheme() diff --git a/internal/pkg/controller/namespace_reconciler.go b/internal/pkg/controller/namespace_reconciler.go index 5159a1b40..c8c658953 100644 --- a/internal/pkg/controller/namespace_reconciler.go +++ b/internal/pkg/controller/namespace_reconciler.go @@ -11,8 +11,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" + "github.com/stakater/Reloader/internal/pkg/reload" "github.com/stakater/Reloader/pkg/config" - "github.com/stakater/Reloader/pkg/reload" ) // NamespaceCache provides thread-safe access to the set of namespaces diff --git a/internal/pkg/controller/namespace_reconciler_test.go b/internal/pkg/controller/namespace_reconciler_test.go index db1a7c824..59d21c503 100644 --- a/internal/pkg/controller/namespace_reconciler_test.go +++ b/internal/pkg/controller/namespace_reconciler_test.go @@ -5,9 +5,9 @@ import ( "k8s.io/apimachinery/pkg/labels" - "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/controller" "github.com/stakater/Reloader/internal/pkg/testutil" + "github.com/stakater/Reloader/pkg/config" ) func TestNamespaceCache_Basic(t *testing.T) { diff --git a/internal/pkg/controller/resource_reconciler.go b/internal/pkg/controller/resource_reconciler.go index 621e759dd..e6c32b002 100644 --- a/internal/pkg/controller/resource_reconciler.go +++ b/internal/pkg/controller/resource_reconciler.go @@ -11,12 +11,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/predicate" "github.com/stakater/Reloader/internal/pkg/alerting" - "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/events" "github.com/stakater/Reloader/internal/pkg/metrics" - "github.com/stakater/Reloader/pkg/reload" + "github.com/stakater/Reloader/internal/pkg/reload" "github.com/stakater/Reloader/internal/pkg/webhook" "github.com/stakater/Reloader/internal/pkg/workload" + "github.com/stakater/Reloader/pkg/config" + "github.com/stakater/Reloader/pkg/matcher" ) // ResourceReconcilerDeps holds shared dependencies for resource reconcilers. @@ -39,7 +40,7 @@ type ResourceReconcilerDeps struct { // ResourceConfig provides type-specific configuration for a resource reconciler. type ResourceConfig[T client.Object] struct { // ResourceType identifies the type of resource (configmap or secret). - ResourceType reload.ResourceType + ResourceType matcher.ResourceType // NewResource creates a new instance of the resource type. NewResource func() T diff --git a/internal/pkg/controller/retry.go b/internal/pkg/controller/retry.go index 802d1b69c..dc3895d57 100644 --- a/internal/pkg/controller/retry.go +++ b/internal/pkg/controller/retry.go @@ -7,8 +7,9 @@ import ( "k8s.io/client-go/util/retry" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/stakater/Reloader/pkg/reload" + "github.com/stakater/Reloader/internal/pkg/reload" "github.com/stakater/Reloader/internal/pkg/workload" + "github.com/stakater/Reloader/pkg/matcher" ) // UpdateObjectWithRetry updates a Kubernetes object with retry on conflict. @@ -58,7 +59,7 @@ func UpdateWorkloadWithRetry( pauseHandler *reload.PauseHandler, wl workload.Workload, resourceName string, - resourceType reload.ResourceType, + resourceType matcher.ResourceType, namespace string, hash string, autoReload bool, @@ -83,7 +84,7 @@ func retryWithReload( reloadService *reload.Service, wl workload.Workload, resourceName string, - resourceType reload.ResourceType, + resourceType matcher.ResourceType, namespace string, hash string, autoReload bool, @@ -131,7 +132,7 @@ func updateStandardWorkload( reloadService *reload.Service, wl workload.Workload, resourceName string, - resourceType reload.ResourceType, + resourceType matcher.ResourceType, namespace string, hash string, autoReload bool, @@ -152,7 +153,7 @@ func updateDeploymentWithPause( pauseHandler *reload.PauseHandler, wl workload.Workload, resourceName string, - resourceType reload.ResourceType, + resourceType matcher.ResourceType, namespace string, hash string, autoReload bool, @@ -180,7 +181,7 @@ func updateWithSpecialStrategy( reloadService *reload.Service, wl workload.Workload, resourceName string, - resourceType reload.ResourceType, + resourceType matcher.ResourceType, namespace string, hash string, autoReload bool, diff --git a/internal/pkg/controller/retry_test.go b/internal/pkg/controller/retry_test.go index ab3517225..c800f61f5 100644 --- a/internal/pkg/controller/retry_test.go +++ b/internal/pkg/controller/retry_test.go @@ -13,11 +13,12 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" - "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/controller" - "github.com/stakater/Reloader/pkg/reload" + "github.com/stakater/Reloader/internal/pkg/reload" "github.com/stakater/Reloader/internal/pkg/testutil" "github.com/stakater/Reloader/internal/pkg/workload" + "github.com/stakater/Reloader/pkg/config" + "github.com/stakater/Reloader/pkg/matcher" ) func TestUpdateWorkloadWithRetry_WorkloadTypes(t *testing.T) { @@ -25,7 +26,7 @@ func TestUpdateWorkloadWithRetry_WorkloadTypes(t *testing.T) { name string object runtime.Object workload func(runtime.Object) workload.Workload - resourceType reload.ResourceType + resourceType matcher.ResourceType verify func(t *testing.T, c client.Client) }{ { @@ -34,7 +35,7 @@ func TestUpdateWorkloadWithRetry_WorkloadTypes(t *testing.T) { workload: func(o runtime.Object) workload.Workload { return workload.NewDeploymentWorkload(o.(*appsv1.Deployment)) }, - resourceType: reload.ResourceTypeConfigMap, + resourceType: matcher.ResourceTypeConfigMap, verify: func(t *testing.T, c client.Client) { var result appsv1.Deployment if err := c.Get(context.Background(), types.NamespacedName{Name: "test-deployment", Namespace: "default"}, &result); err != nil { @@ -51,7 +52,7 @@ func TestUpdateWorkloadWithRetry_WorkloadTypes(t *testing.T) { workload: func(o runtime.Object) workload.Workload { return workload.NewDaemonSetWorkload(o.(*appsv1.DaemonSet)) }, - resourceType: reload.ResourceTypeSecret, + resourceType: matcher.ResourceTypeSecret, verify: func(t *testing.T, c client.Client) { var result appsv1.DaemonSet if err := c.Get(context.Background(), types.NamespacedName{Name: "test-daemonset", Namespace: "default"}, &result); err != nil { @@ -68,7 +69,7 @@ func TestUpdateWorkloadWithRetry_WorkloadTypes(t *testing.T) { workload: func(o runtime.Object) workload.Workload { return workload.NewStatefulSetWorkload(o.(*appsv1.StatefulSet)) }, - resourceType: reload.ResourceTypeConfigMap, + resourceType: matcher.ResourceTypeConfigMap, verify: func(t *testing.T, c client.Client) { var result appsv1.StatefulSet if err := c.Get(context.Background(), types.NamespacedName{Name: "test-statefulset", Namespace: "default"}, &result); err != nil { @@ -85,7 +86,7 @@ func TestUpdateWorkloadWithRetry_WorkloadTypes(t *testing.T) { workload: func(o runtime.Object) workload.Workload { return workload.NewJobWorkload(o.(*batchv1.Job)) }, - resourceType: reload.ResourceTypeConfigMap, + resourceType: matcher.ResourceTypeConfigMap, verify: func(t *testing.T, c client.Client) { var jobs batchv1.JobList if err := c.List(context.Background(), &jobs, client.InNamespace("default")); err != nil { @@ -102,7 +103,7 @@ func TestUpdateWorkloadWithRetry_WorkloadTypes(t *testing.T) { workload: func(o runtime.Object) workload.Workload { return workload.NewCronJobWorkload(o.(*batchv1.CronJob)) }, - resourceType: reload.ResourceTypeSecret, + resourceType: matcher.ResourceTypeSecret, verify: func(t *testing.T, c client.Client) { var jobs batchv1.JobList if err := c.List(context.Background(), &jobs, client.InNamespace("default")); err != nil { @@ -220,7 +221,7 @@ func TestUpdateWorkloadWithRetry_Strategies(t *testing.T) { nil, // no pause handler for this test wl, "test-cm", - reload.ResourceTypeConfigMap, + matcher.ResourceTypeConfigMap, "default", "abc123", false, @@ -272,7 +273,7 @@ func TestUpdateWorkloadWithRetry_NoUpdate(t *testing.T) { nil, // no pause handler wl, "test-cm", - reload.ResourceTypeConfigMap, + matcher.ResourceTypeConfigMap, "default", "abc123", // Same hash as already set false, @@ -288,11 +289,11 @@ func TestUpdateWorkloadWithRetry_NoUpdate(t *testing.T) { func TestResourceTypeKind(t *testing.T) { tests := []struct { - resourceType reload.ResourceType + resourceType matcher.ResourceType expectedKind string }{ - {reload.ResourceTypeConfigMap, "ConfigMap"}, - {reload.ResourceTypeSecret, "Secret"}, + {matcher.ResourceTypeConfigMap, "ConfigMap"}, + {matcher.ResourceTypeSecret, "Secret"}, } for _, tt := range tests { @@ -332,7 +333,7 @@ func TestUpdateWorkloadWithRetry_PauseDeployment(t *testing.T) { pauseHandler, wl, "test-cm", - reload.ResourceTypeConfigMap, + matcher.ResourceTypeConfigMap, "default", "abc123", true, @@ -393,7 +394,7 @@ func TestUpdateWorkloadWithRetry_PauseWithExplicitAnnotation(t *testing.T) { pauseHandler, wl, "test-cm", - reload.ResourceTypeConfigMap, + matcher.ResourceTypeConfigMap, "default", "abc123", false, // NOT auto reload @@ -454,7 +455,7 @@ func TestUpdateWorkloadWithRetry_PauseWithSecretReload(t *testing.T) { pauseHandler, wl, "test-secret", - reload.ResourceTypeSecret, + matcher.ResourceTypeSecret, "default", "abc123", false, @@ -511,7 +512,7 @@ func TestUpdateWorkloadWithRetry_PauseWithAutoSecret(t *testing.T) { pauseHandler, wl, "test-secret", - reload.ResourceTypeSecret, + matcher.ResourceTypeSecret, "default", "abc123", true, @@ -561,7 +562,7 @@ func TestUpdateWorkloadWithRetry_NoPauseWithoutAnnotation(t *testing.T) { pauseHandler, wl, "test-cm", - reload.ResourceTypeConfigMap, + matcher.ResourceTypeConfigMap, "default", "abc123", true, diff --git a/internal/pkg/controller/secret_reconciler.go b/internal/pkg/controller/secret_reconciler.go index ac16cc4f6..1b37cb164 100644 --- a/internal/pkg/controller/secret_reconciler.go +++ b/internal/pkg/controller/secret_reconciler.go @@ -9,12 +9,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/stakater/Reloader/internal/pkg/alerting" - "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/events" "github.com/stakater/Reloader/internal/pkg/metrics" - "github.com/stakater/Reloader/pkg/reload" + "github.com/stakater/Reloader/internal/pkg/reload" "github.com/stakater/Reloader/internal/pkg/webhook" "github.com/stakater/Reloader/internal/pkg/workload" + "github.com/stakater/Reloader/pkg/config" + "github.com/stakater/Reloader/pkg/matcher" ) // SecretReconciler watches Secrets and triggers workload reloads. @@ -49,7 +50,7 @@ func NewSecretReconciler( NamespaceCache: nsCache, }, ResourceConfig[*corev1.Secret]{ - ResourceType: reload.ResourceTypeSecret, + ResourceType: matcher.ResourceTypeSecret, NewResource: func() *corev1.Secret { return &corev1.Secret{} }, CreateChange: func(s *corev1.Secret, eventType reload.EventType) reload.ResourceChange { return reload.SecretChange{Secret: s, EventType: eventType} diff --git a/internal/pkg/controller/secret_reconciler_test.go b/internal/pkg/controller/secret_reconciler_test.go index e8688801b..a34fb24b2 100644 --- a/internal/pkg/controller/secret_reconciler_test.go +++ b/internal/pkg/controller/secret_reconciler_test.go @@ -3,8 +3,8 @@ package controller_test import ( "testing" - "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/testutil" + "github.com/stakater/Reloader/pkg/config" ) func TestSecretReconciler_NotFound(t *testing.T) { diff --git a/internal/pkg/controller/secretproviderclass_filter_test.go b/internal/pkg/controller/secretproviderclass_filter_test.go index 6f569a885..84c305596 100644 --- a/internal/pkg/controller/secretproviderclass_filter_test.go +++ b/internal/pkg/controller/secretproviderclass_filter_test.go @@ -8,8 +8,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/event" csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1" + "github.com/stakater/Reloader/internal/pkg/reload" "github.com/stakater/Reloader/pkg/config" - "github.com/stakater/Reloader/pkg/reload" ) // TestSecretProviderClassReconciler_FilterIgnoresResourceLabelSelector pins the diff --git a/internal/pkg/controller/secretproviderclass_reconciler.go b/internal/pkg/controller/secretproviderclass_reconciler.go index e921a8d75..9abc5eb13 100644 --- a/internal/pkg/controller/secretproviderclass_reconciler.go +++ b/internal/pkg/controller/secretproviderclass_reconciler.go @@ -12,8 +12,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1" + "github.com/stakater/Reloader/internal/pkg/reload" "github.com/stakater/Reloader/pkg/config" - "github.com/stakater/Reloader/pkg/reload" + "github.com/stakater/Reloader/pkg/matcher" ) // SecretProviderClassReconciler watches SecretProviderClassPodStatus (the per-pod @@ -28,7 +29,7 @@ func NewSecretProviderClassReconciler(deps ResourceReconcilerDeps, apiReader cli return NewResourceReconciler( deps, ResourceConfig[*csiv1.SecretProviderClassPodStatus]{ - ResourceType: reload.ResourceTypeSecretProviderClass, + ResourceType: matcher.ResourceTypeSecretProviderClass, NewResource: func() *csiv1.SecretProviderClassPodStatus { return &csiv1.SecretProviderClassPodStatus{} }, ResolveChange: resolveSecretProviderClassChange, SkipOnNotFound: true, diff --git a/internal/pkg/controller/secretproviderclass_reconciler_test.go b/internal/pkg/controller/secretproviderclass_reconciler_test.go index 7114a8345..c655f12dc 100644 --- a/internal/pkg/controller/secretproviderclass_reconciler_test.go +++ b/internal/pkg/controller/secretproviderclass_reconciler_test.go @@ -10,10 +10,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1" - "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/controller" - "github.com/stakater/Reloader/pkg/reload" + "github.com/stakater/Reloader/internal/pkg/reload" "github.com/stakater/Reloader/internal/pkg/testutil" + "github.com/stakater/Reloader/pkg/config" ) // newSecretProviderClassReconcilerWithClient creates a SecretProviderClassReconciler for diff --git a/internal/pkg/controller/test_helpers_test.go b/internal/pkg/controller/test_helpers_test.go index cd23486f0..e88c0cfa7 100644 --- a/internal/pkg/controller/test_helpers_test.go +++ b/internal/pkg/controller/test_helpers_test.go @@ -13,14 +13,14 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" "github.com/stakater/Reloader/internal/pkg/alerting" - "github.com/stakater/Reloader/pkg/config" "github.com/stakater/Reloader/internal/pkg/controller" "github.com/stakater/Reloader/internal/pkg/events" "github.com/stakater/Reloader/internal/pkg/metrics" - "github.com/stakater/Reloader/pkg/reload" + "github.com/stakater/Reloader/internal/pkg/reload" "github.com/stakater/Reloader/internal/pkg/testutil" "github.com/stakater/Reloader/internal/pkg/webhook" "github.com/stakater/Reloader/internal/pkg/workload" + "github.com/stakater/Reloader/pkg/config" ) // testDeps holds shared test dependencies. diff --git a/pkg/reload/change.go b/internal/pkg/reload/change.go similarity index 56% rename from pkg/reload/change.go rename to internal/pkg/reload/change.go index 2b6a2f094..598e898ff 100644 --- a/pkg/reload/change.go +++ b/internal/pkg/reload/change.go @@ -3,6 +3,8 @@ package reload import ( corev1 "k8s.io/api/core/v1" csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1" + + "github.com/stakater/Reloader/pkg/matcher" ) // EventType represents the type of change event. @@ -24,7 +26,7 @@ type ResourceChange interface { GetName() string GetNamespace() string GetAnnotations() map[string]string - GetResourceType() ResourceType + GetResourceType() matcher.ResourceType ComputeHash(hasher *Hasher) string } @@ -34,13 +36,13 @@ type ConfigMapChange struct { EventType EventType } -func (c ConfigMapChange) IsNil() bool { return c.ConfigMap == nil } -func (c ConfigMapChange) GetEventType() EventType { return c.EventType } -func (c ConfigMapChange) GetName() string { return c.ConfigMap.Name } -func (c ConfigMapChange) GetNamespace() string { return c.ConfigMap.Namespace } -func (c ConfigMapChange) GetAnnotations() map[string]string { return c.ConfigMap.Annotations } -func (c ConfigMapChange) GetResourceType() ResourceType { return ResourceTypeConfigMap } -func (c ConfigMapChange) ComputeHash(h *Hasher) string { return h.HashConfigMap(c.ConfigMap) } +func (c ConfigMapChange) IsNil() bool { return c.ConfigMap == nil } +func (c ConfigMapChange) GetEventType() EventType { return c.EventType } +func (c ConfigMapChange) GetName() string { return c.ConfigMap.Name } +func (c ConfigMapChange) GetNamespace() string { return c.ConfigMap.Namespace } +func (c ConfigMapChange) GetAnnotations() map[string]string { return c.ConfigMap.Annotations } +func (c ConfigMapChange) GetResourceType() matcher.ResourceType { return matcher.ResourceTypeConfigMap } +func (c ConfigMapChange) ComputeHash(h *Hasher) string { return h.HashConfigMap(c.ConfigMap) } // SecretChange represents a change event for a Secret. type SecretChange struct { @@ -48,13 +50,13 @@ type SecretChange struct { EventType EventType } -func (c SecretChange) IsNil() bool { return c.Secret == nil } -func (c SecretChange) GetEventType() EventType { return c.EventType } -func (c SecretChange) GetName() string { return c.Secret.Name } -func (c SecretChange) GetNamespace() string { return c.Secret.Namespace } -func (c SecretChange) GetAnnotations() map[string]string { return c.Secret.Annotations } -func (c SecretChange) GetResourceType() ResourceType { return ResourceTypeSecret } -func (c SecretChange) ComputeHash(h *Hasher) string { return h.HashSecret(c.Secret) } +func (c SecretChange) IsNil() bool { return c.Secret == nil } +func (c SecretChange) GetEventType() EventType { return c.EventType } +func (c SecretChange) GetName() string { return c.Secret.Name } +func (c SecretChange) GetNamespace() string { return c.Secret.Namespace } +func (c SecretChange) GetAnnotations() map[string]string { return c.Secret.Annotations } +func (c SecretChange) GetResourceType() matcher.ResourceType { return matcher.ResourceTypeSecret } +func (c SecretChange) ComputeHash(h *Hasher) string { return h.HashSecret(c.Secret) } // SecretProviderClassChange represents a change event derived from a // SecretProviderClassPodStatus update. Name/Annotations refer to the resolved @@ -74,8 +76,8 @@ func (c SecretProviderClassChange) GetNamespace() string { return c.Namespace func (c SecretProviderClassChange) GetAnnotations() map[string]string { return c.Annotations } -func (c SecretProviderClassChange) GetResourceType() ResourceType { - return ResourceTypeSecretProviderClass +func (c SecretProviderClassChange) GetResourceType() matcher.ResourceType { + return matcher.ResourceTypeSecretProviderClass } func (c SecretProviderClassChange) ComputeHash(h *Hasher) string { return h.HashSecretProviderClass(c.Status) diff --git a/pkg/reload/change_test.go b/internal/pkg/reload/change_test.go similarity index 91% rename from pkg/reload/change_test.go rename to internal/pkg/reload/change_test.go index a17b45a4e..d25f90546 100644 --- a/pkg/reload/change_test.go +++ b/internal/pkg/reload/change_test.go @@ -4,6 +4,8 @@ import ( "testing" csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1" + + "github.com/stakater/Reloader/pkg/matcher" ) func TestSecretProviderClassChange(t *testing.T) { @@ -28,7 +30,7 @@ func TestSecretProviderClassChange(t *testing.T) { if c.GetNamespace() != "ns1" { t.Fatalf("GetNamespace() = %q", c.GetNamespace()) } - if c.GetResourceType() != ResourceTypeSecretProviderClass { + if c.GetResourceType() != matcher.ResourceTypeSecretProviderClass { t.Fatalf("GetResourceType() = %q", c.GetResourceType()) } if c.GetEventType() != EventTypeUpdate { diff --git a/pkg/reload/csi_dep_check_test.go b/internal/pkg/reload/csi_dep_check_test.go similarity index 100% rename from pkg/reload/csi_dep_check_test.go rename to internal/pkg/reload/csi_dep_check_test.go diff --git a/pkg/reload/decision.go b/internal/pkg/reload/decision.go similarity index 84% rename from pkg/reload/decision.go rename to internal/pkg/reload/decision.go index ac3b264bb..d0605be14 100644 --- a/pkg/reload/decision.go +++ b/internal/pkg/reload/decision.go @@ -5,9 +5,7 @@ import ( ) // ReloadDecision contains the result of evaluating whether to reload a workload. -// -// NOTE: not part of the public API — the Workload field is an internal/pkg/workload -// type and is therefore not usable from outside this module. +// External, decision-only consumers should use the public matcher package instead. type ReloadDecision struct { // Workload is the workload accessor. Workload workload.Workload diff --git a/pkg/reload/decision_test.go b/internal/pkg/reload/decision_test.go similarity index 100% rename from pkg/reload/decision_test.go rename to internal/pkg/reload/decision_test.go diff --git a/pkg/reload/hasher.go b/internal/pkg/reload/hasher.go similarity index 100% rename from pkg/reload/hasher.go rename to internal/pkg/reload/hasher.go diff --git a/pkg/reload/hasher_test.go b/internal/pkg/reload/hasher_test.go similarity index 100% rename from pkg/reload/hasher_test.go rename to internal/pkg/reload/hasher_test.go diff --git a/pkg/reload/pause.go b/internal/pkg/reload/pause.go similarity index 95% rename from pkg/reload/pause.go rename to internal/pkg/reload/pause.go index bc8d02e02..7d052c91c 100644 --- a/pkg/reload/pause.go +++ b/internal/pkg/reload/pause.go @@ -11,9 +11,6 @@ import ( ) // PauseHandler handles pause deployment logic. -// -// NOTE: not part of the public API — its methods reference internal/pkg/workload -// and are therefore not usable from outside this module. type PauseHandler struct { cfg *config.Config } diff --git a/pkg/reload/pause_test.go b/internal/pkg/reload/pause_test.go similarity index 100% rename from pkg/reload/pause_test.go rename to internal/pkg/reload/pause_test.go diff --git a/pkg/reload/predicate.go b/internal/pkg/reload/predicate.go similarity index 100% rename from pkg/reload/predicate.go rename to internal/pkg/reload/predicate.go diff --git a/pkg/reload/predicate_test.go b/internal/pkg/reload/predicate_test.go similarity index 100% rename from pkg/reload/predicate_test.go rename to internal/pkg/reload/predicate_test.go diff --git a/pkg/reload/service.go b/internal/pkg/reload/service.go similarity index 89% rename from pkg/reload/service.go rename to internal/pkg/reload/service.go index 88f256660..7c2290bdd 100644 --- a/pkg/reload/service.go +++ b/internal/pkg/reload/service.go @@ -11,18 +11,16 @@ import ( "github.com/stakater/Reloader/internal/pkg/workload" "github.com/stakater/Reloader/pkg/config" + "github.com/stakater/Reloader/pkg/matcher" ) // Service orchestrates the reload logic for ConfigMaps and Secrets. -// -// NOTE: not part of the public API — its methods reference internal/pkg/workload -// and are therefore not usable from outside this module. External, decision-only -// consumers should use Matcher instead. +// External, decision-only consumers should use the public matcher package instead. type Service struct { cfg *config.Config log logr.Logger hasher *Hasher - matcher *Matcher + matcher *matcher.Matcher strategy Strategy } @@ -32,7 +30,7 @@ func NewService(cfg *config.Config, log logr.Logger) *Service { cfg: cfg, log: log, hasher: NewHasher(), - matcher: NewMatcher(cfg), + matcher: matcher.NewMatcher(cfg), strategy: NewStrategy(cfg), } } @@ -66,7 +64,7 @@ func (s *Service) processResource( resourceName string, resourceNamespace string, resourceAnnotations map[string]string, - resourceType ResourceType, + resourceType matcher.ResourceType, hash string, workloads []workload.Workload, ) []ReloadDecision { @@ -83,17 +81,17 @@ func (s *Service) processResource( var usesResource bool switch resourceType { - case ResourceTypeConfigMap: + case matcher.ResourceTypeConfigMap: usesResource = wl.UsesConfigMap(resourceName) - case ResourceTypeSecret: + case matcher.ResourceTypeSecret: usesResource = wl.UsesSecret(resourceName) - case ResourceTypeSecretProviderClass: + case matcher.ResourceTypeSecretProviderClass: // Annotation-only matching (parity with master): the workload's // annotations alone decide the reload; no volume-uses scan. usesResource = true } - input := MatchInput{ + input := matcher.MatchInput{ ResourceName: resourceName, ResourceNamespace: resourceNamespace, ResourceType: resourceType, @@ -141,7 +139,7 @@ func (s *Service) ApplyReload( ctx context.Context, wl workload.Workload, resourceName string, - resourceType ResourceType, + resourceType matcher.ResourceType, namespace string, hash string, autoReload bool, @@ -176,7 +174,7 @@ func (s *Service) ApplyReload( func (s *Service) setAttributionAnnotation( wl workload.Workload, resourceName string, - resourceType ResourceType, + resourceType matcher.ResourceType, namespace string, hash string, container *corev1.Container, @@ -207,7 +205,7 @@ func (s *Service) setAttributionAnnotation( func (s *Service) findTargetContainer( wl workload.Workload, resourceName string, - resourceType ResourceType, + resourceType matcher.ResourceType, autoReload bool, ) *corev1.Container { containers := wl.GetContainers() @@ -247,10 +245,10 @@ func (s *Service) findTargetContainer( return &containers[0] } -func (s *Service) findVolumeUsingResource(volumes []corev1.Volume, resourceName string, resourceType ResourceType) string { +func (s *Service) findVolumeUsingResource(volumes []corev1.Volume, resourceName string, resourceType matcher.ResourceType) string { for _, vol := range volumes { switch resourceType { - case ResourceTypeConfigMap: + case matcher.ResourceTypeConfigMap: if vol.ConfigMap != nil && vol.ConfigMap.Name == resourceName { return vol.Name } @@ -261,7 +259,7 @@ func (s *Service) findVolumeUsingResource(volumes []corev1.Volume, resourceName } } } - case ResourceTypeSecret: + case matcher.ResourceTypeSecret: if vol.Secret != nil && vol.Secret.SecretName == resourceName { return vol.Name } @@ -272,7 +270,7 @@ func (s *Service) findVolumeUsingResource(volumes []corev1.Volume, resourceName } } } - case ResourceTypeSecretProviderClass: + case matcher.ResourceTypeSecretProviderClass: // Match the CSI volume that references this SPC. if vol.CSI != nil && vol.CSI.VolumeAttributes["secretProviderClass"] == resourceName { return vol.Name @@ -293,18 +291,18 @@ func (s *Service) findContainerWithVolumeMount(containers []corev1.Container, vo return nil } -func (s *Service) findContainerWithEnvRef(containers []corev1.Container, resourceName string, resourceType ResourceType) *corev1.Container { +func (s *Service) findContainerWithEnvRef(containers []corev1.Container, resourceName string, resourceType matcher.ResourceType) *corev1.Container { for i := range containers { for _, env := range containers[i].Env { if env.ValueFrom == nil { continue } switch resourceType { - case ResourceTypeConfigMap: + case matcher.ResourceTypeConfigMap: if env.ValueFrom.ConfigMapKeyRef != nil && env.ValueFrom.ConfigMapKeyRef.Name == resourceName { return &containers[i] } - case ResourceTypeSecret: + case matcher.ResourceTypeSecret: if env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.Name == resourceName { return &containers[i] } @@ -313,11 +311,11 @@ func (s *Service) findContainerWithEnvRef(containers []corev1.Container, resourc for _, envFrom := range containers[i].EnvFrom { switch resourceType { - case ResourceTypeConfigMap: + case matcher.ResourceTypeConfigMap: if envFrom.ConfigMapRef != nil && envFrom.ConfigMapRef.Name == resourceName { return &containers[i] } - case ResourceTypeSecret: + case matcher.ResourceTypeSecret: if envFrom.SecretRef != nil && envFrom.SecretRef.Name == resourceName { return &containers[i] } diff --git a/pkg/reload/service_test.go b/internal/pkg/reload/service_test.go similarity index 95% rename from pkg/reload/service_test.go rename to internal/pkg/reload/service_test.go index b2c868fe9..a7131fd66 100644 --- a/pkg/reload/service_test.go +++ b/internal/pkg/reload/service_test.go @@ -13,6 +13,7 @@ import ( "github.com/stakater/Reloader/internal/pkg/testutil" "github.com/stakater/Reloader/internal/pkg/workload" "github.com/stakater/Reloader/pkg/config" + "github.com/stakater/Reloader/pkg/matcher" ) func TestService_ProcessConfigMap_AutoReload(t *testing.T) { @@ -319,7 +320,7 @@ func TestService_ApplyReload_EnvVarStrategy(t *testing.T) { accessor := workload.NewDeploymentWorkload(deploy) ctx := context.Background() - updated, err := svc.ApplyReload(ctx, accessor, "test-cm", ResourceTypeConfigMap, "default", "abc123hash", false) + updated, err := svc.ApplyReload(ctx, accessor, "test-cm", matcher.ResourceTypeConfigMap, "default", "abc123hash", false) if err != nil { t.Fatalf("ApplyReload failed: %v", err) @@ -363,7 +364,7 @@ func TestService_ApplyReload_AnnotationStrategy(t *testing.T) { accessor := workload.NewDeploymentWorkload(deploy) ctx := context.Background() - updated, err := svc.ApplyReload(ctx, accessor, "test-cm", ResourceTypeConfigMap, "default", "abc123hash", false) + updated, err := svc.ApplyReload(ctx, accessor, "test-cm", matcher.ResourceTypeConfigMap, "default", "abc123hash", false) if err != nil { t.Fatalf("ApplyReload failed: %v", err) @@ -395,7 +396,7 @@ func TestService_ApplyReload_EnvVarDeletion(t *testing.T) { ctx := context.Background() // Empty hash signals deletion - updated, err := svc.ApplyReload(ctx, accessor, "test-cm", ResourceTypeConfigMap, "default", "", false) + updated, err := svc.ApplyReload(ctx, accessor, "test-cm", matcher.ResourceTypeConfigMap, "default", "", false) if err != nil { t.Fatalf("ApplyReload failed: %v", err) @@ -439,7 +440,7 @@ func TestService_ApplyReload_NoChangeIfSameHash(t *testing.T) { accessor := workload.NewDeploymentWorkload(deploy) ctx := context.Background() - updated, err := svc.ApplyReload(ctx, accessor, "test-cm", ResourceTypeConfigMap, "default", "abc123hash", false) + updated, err := svc.ApplyReload(ctx, accessor, "test-cm", matcher.ResourceTypeConfigMap, "default", "abc123hash", false) if err != nil { t.Fatalf("ApplyReload failed: %v", err) @@ -673,7 +674,7 @@ func TestService_findVolumeUsingResource_ConfigMap(t *testing.T) { name string volumes []corev1.Volume resourceName string - resourceType ResourceType + resourceType matcher.ResourceType wantVolume string }{ { @@ -689,7 +690,7 @@ func TestService_findVolumeUsingResource_ConfigMap(t *testing.T) { }, }, resourceName: "my-cm", - resourceType: ResourceTypeConfigMap, + resourceType: matcher.ResourceTypeConfigMap, wantVolume: "config-vol", }, { @@ -711,7 +712,7 @@ func TestService_findVolumeUsingResource_ConfigMap(t *testing.T) { }, }, resourceName: "projected-cm", - resourceType: ResourceTypeConfigMap, + resourceType: matcher.ResourceTypeConfigMap, wantVolume: "projected-vol", }, { @@ -727,14 +728,14 @@ func TestService_findVolumeUsingResource_ConfigMap(t *testing.T) { }, }, resourceName: "my-cm", - resourceType: ResourceTypeConfigMap, + resourceType: matcher.ResourceTypeConfigMap, wantVolume: "", }, { name: "empty volumes", volumes: []corev1.Volume{}, resourceName: "my-cm", - resourceType: ResourceTypeConfigMap, + resourceType: matcher.ResourceTypeConfigMap, wantVolume: "", }, } @@ -817,7 +818,7 @@ func TestService_findVolumeUsingResource_Secret(t *testing.T) { for _, tt := range tests { t.Run( tt.name, func(t *testing.T) { - got := svc.findVolumeUsingResource(tt.volumes, tt.resourceName, ResourceTypeSecret) + got := svc.findVolumeUsingResource(tt.volumes, tt.resourceName, matcher.ResourceTypeSecret) if got != tt.wantVolume { t.Errorf("findVolumeUsingResource() = %q, want %q", got, tt.wantVolume) } @@ -995,7 +996,7 @@ func TestService_findContainerWithEnvRef_ConfigMap(t *testing.T) { for _, tt := range tests { t.Run( tt.name, func(t *testing.T) { - got := svc.findContainerWithEnvRef(tt.containers, tt.resourceName, ResourceTypeConfigMap) + got := svc.findContainerWithEnvRef(tt.containers, tt.resourceName, matcher.ResourceTypeConfigMap) if tt.shouldMatch { if got == nil { t.Error("Expected to find a container, got nil") @@ -1084,7 +1085,7 @@ func TestService_findContainerWithEnvRef_Secret(t *testing.T) { for _, tt := range tests { t.Run( tt.name, func(t *testing.T) { - got := svc.findContainerWithEnvRef(tt.containers, tt.resourceName, ResourceTypeSecret) + got := svc.findContainerWithEnvRef(tt.containers, tt.resourceName, matcher.ResourceTypeSecret) if tt.shouldMatch { if got == nil { t.Error("Expected to find a container, got nil") @@ -1128,7 +1129,7 @@ func TestService_findTargetContainer_AutoReload(t *testing.T) { } accessor := workload.NewDeploymentWorkload(deploy) - container := svc.findTargetContainer(accessor, "my-cm", ResourceTypeConfigMap, true) + container := svc.findTargetContainer(accessor, "my-cm", matcher.ResourceTypeConfigMap, true) if container == nil { t.Fatal("Expected to find a container") } @@ -1166,7 +1167,7 @@ func TestService_findTargetContainer_AutoReload_EnvRef(t *testing.T) { } accessor := workload.NewDeploymentWorkload(deploy) - container := svc.findTargetContainer(accessor, "my-cm", ResourceTypeConfigMap, true) + container := svc.findTargetContainer(accessor, "my-cm", matcher.ResourceTypeConfigMap, true) if container == nil { t.Fatal("Expected to find a container") } @@ -1208,7 +1209,7 @@ func TestService_findTargetContainer_AutoReload_InitContainer(t *testing.T) { } accessor := workload.NewDeploymentWorkload(deploy) - container := svc.findTargetContainer(accessor, "my-cm", ResourceTypeConfigMap, true) + container := svc.findTargetContainer(accessor, "my-cm", matcher.ResourceTypeConfigMap, true) if container == nil { t.Fatal("Expected to find a container") } @@ -1249,7 +1250,7 @@ func TestService_findTargetContainer_AutoReload_InitContainerEnvRef(t *testing.T } accessor := workload.NewDeploymentWorkload(deploy) - container := svc.findTargetContainer(accessor, "my-cm", ResourceTypeConfigMap, true) + container := svc.findTargetContainer(accessor, "my-cm", matcher.ResourceTypeConfigMap, true) if container == nil { t.Fatal("Expected to find a container") } @@ -1267,7 +1268,7 @@ func TestService_findTargetContainer_NoContainers(t *testing.T) { deploy.Spec.Template.Spec.Containers = []corev1.Container{} accessor := workload.NewDeploymentWorkload(deploy) - container := svc.findTargetContainer(accessor, "my-cm", ResourceTypeConfigMap, false) + container := svc.findTargetContainer(accessor, "my-cm", matcher.ResourceTypeConfigMap, false) if container != nil { t.Error("Expected nil container for empty container list") } @@ -1285,7 +1286,7 @@ func TestService_findTargetContainer_NonAutoReload(t *testing.T) { accessor := workload.NewDeploymentWorkload(deploy) // Without autoReload, should return first container - container := svc.findTargetContainer(accessor, "my-cm", ResourceTypeConfigMap, false) + container := svc.findTargetContainer(accessor, "my-cm", matcher.ResourceTypeConfigMap, false) if container == nil { t.Fatal("Expected to find a container") } @@ -1306,7 +1307,7 @@ func TestService_findTargetContainer_AutoReload_FallbackToFirst(t *testing.T) { } accessor := workload.NewDeploymentWorkload(deploy) - container := svc.findTargetContainer(accessor, "non-existent", ResourceTypeConfigMap, true) + container := svc.findTargetContainer(accessor, "non-existent", matcher.ResourceTypeConfigMap, true) if container == nil { t.Fatal("Expected to find a container") } @@ -1420,7 +1421,7 @@ func TestService_ApplyReload_SPC_TargetsMountingContainer(t *testing.T) { accessor := workload.NewDeploymentWorkload(dep) // autoReload=true exercises volume-based container targeting. - updated, err := svc.ApplyReload(context.Background(), accessor, "my-spc", ResourceTypeSecretProviderClass, "default", "spchash", true) + updated, err := svc.ApplyReload(context.Background(), accessor, "my-spc", matcher.ResourceTypeSecretProviderClass, "default", "spchash", true) if err != nil { t.Fatalf("ApplyReload failed: %v", err) } diff --git a/pkg/reload/strategy.go b/internal/pkg/reload/strategy.go similarity index 95% rename from pkg/reload/strategy.go rename to internal/pkg/reload/strategy.go index 1e85c6207..ce00ac496 100644 --- a/pkg/reload/strategy.go +++ b/internal/pkg/reload/strategy.go @@ -10,6 +10,7 @@ import ( corev1 "k8s.io/api/core/v1" "github.com/stakater/Reloader/pkg/config" + "github.com/stakater/Reloader/pkg/matcher" ) const ( @@ -32,7 +33,7 @@ type Strategy interface { // StrategyInput contains the information needed to apply a reload strategy. type StrategyInput struct { ResourceName string - ResourceType ResourceType + ResourceType matcher.ResourceType Namespace string Hash string Container *corev1.Container @@ -103,14 +104,14 @@ func (s *EnvVarStrategy) removeEnvVar(container *corev1.Container, name string) return false } -func (s *EnvVarStrategy) envVarName(resourceName string, resourceType ResourceType) string { +func (s *EnvVarStrategy) envVarName(resourceName string, resourceType matcher.ResourceType) string { var postfix string switch resourceType { - case ResourceTypeConfigMap: + case matcher.ResourceTypeConfigMap: postfix = ConfigmapEnvVarPostfix - case ResourceTypeSecret: + case matcher.ResourceTypeSecret: postfix = SecretEnvVarPostfix - case ResourceTypeSecretProviderClass: + case matcher.ResourceTypeSecretProviderClass: postfix = SecretProviderClassEnvVarPostfix } return EnvVarPrefix + convertToEnvVarName(resourceName) + "_" + postfix diff --git a/pkg/reload/strategy_test.go b/internal/pkg/reload/strategy_test.go similarity index 87% rename from pkg/reload/strategy_test.go rename to internal/pkg/reload/strategy_test.go index 3702ce665..03becabde 100644 --- a/pkg/reload/strategy_test.go +++ b/internal/pkg/reload/strategy_test.go @@ -7,6 +7,7 @@ import ( corev1 "k8s.io/api/core/v1" "github.com/stakater/Reloader/pkg/config" + "github.com/stakater/Reloader/pkg/matcher" ) func TestEnvVarStrategy_Apply(t *testing.T) { @@ -20,7 +21,7 @@ func TestEnvVarStrategy_Apply(t *testing.T) { input := StrategyInput{ ResourceName: "my-config", - ResourceType: ResourceTypeConfigMap, + ResourceType: matcher.ResourceTypeConfigMap, Namespace: "default", Hash: "abc123", Container: container, @@ -57,7 +58,7 @@ func TestEnvVarStrategy_Apply(t *testing.T) { input := StrategyInput{ ResourceName: "my-config", - ResourceType: ResourceTypeConfigMap, + ResourceType: matcher.ResourceTypeConfigMap, Namespace: "default", Hash: "new-hash", Container: container, @@ -87,7 +88,7 @@ func TestEnvVarStrategy_Apply(t *testing.T) { input := StrategyInput{ ResourceName: "my-config", - ResourceType: ResourceTypeConfigMap, + ResourceType: matcher.ResourceTypeConfigMap, Namespace: "default", Hash: "same-hash", Container: container, @@ -105,7 +106,7 @@ func TestEnvVarStrategy_Apply(t *testing.T) { t.Run("error when container is nil", func(t *testing.T) { input := StrategyInput{ ResourceName: "my-config", - ResourceType: ResourceTypeConfigMap, + ResourceType: matcher.ResourceTypeConfigMap, Namespace: "default", Hash: "abc123", Container: nil, @@ -125,7 +126,7 @@ func TestEnvVarStrategy_Apply(t *testing.T) { input := StrategyInput{ ResourceName: "my-secret", - ResourceType: ResourceTypeSecret, + ResourceType: matcher.ResourceTypeSecret, Namespace: "default", Hash: "abc123", Container: container, @@ -158,15 +159,15 @@ func TestEnvVarStrategy_EnvVarName(t *testing.T) { tests := []struct { resourceName string - resourceType ResourceType + resourceType matcher.ResourceType expected string }{ - {"my-config", ResourceTypeConfigMap, "STAKATER_MY_CONFIG_CONFIGMAP"}, - {"my-secret", ResourceTypeSecret, "STAKATER_MY_SECRET_SECRET"}, - {"app-config-v2", ResourceTypeConfigMap, "STAKATER_APP_CONFIG_V2_CONFIGMAP"}, - {"my.dotted.config", ResourceTypeConfigMap, "STAKATER_MY_DOTTED_CONFIG_CONFIGMAP"}, - {"MyMixedCase", ResourceTypeConfigMap, "STAKATER_MYMIXEDCASE_CONFIGMAP"}, - {"config-with-123-numbers", ResourceTypeConfigMap, "STAKATER_CONFIG_WITH_123_NUMBERS_CONFIGMAP"}, + {"my-config", matcher.ResourceTypeConfigMap, "STAKATER_MY_CONFIG_CONFIGMAP"}, + {"my-secret", matcher.ResourceTypeSecret, "STAKATER_MY_SECRET_SECRET"}, + {"app-config-v2", matcher.ResourceTypeConfigMap, "STAKATER_APP_CONFIG_V2_CONFIGMAP"}, + {"my.dotted.config", matcher.ResourceTypeConfigMap, "STAKATER_MY_DOTTED_CONFIG_CONFIGMAP"}, + {"MyMixedCase", matcher.ResourceTypeConfigMap, "STAKATER_MYMIXEDCASE_CONFIGMAP"}, + {"config-with-123-numbers", matcher.ResourceTypeConfigMap, "STAKATER_CONFIG_WITH_123_NUMBERS_CONFIGMAP"}, } for _, tt := range tests { @@ -218,7 +219,7 @@ func TestAnnotationStrategy_Apply(t *testing.T) { input := StrategyInput{ ResourceName: "my-config", - ResourceType: ResourceTypeConfigMap, + ResourceType: matcher.ResourceTypeConfigMap, Namespace: "default", Hash: "abc123", Container: container, @@ -244,8 +245,8 @@ func TestAnnotationStrategy_Apply(t *testing.T) { if err := json.Unmarshal([]byte(annotationValue), &source); err != nil { t.Fatalf("failed to unmarshal annotation: %v", err) } - if source.Kind != string(ResourceTypeConfigMap) { - t.Errorf("expected kind=%s, got %s", ResourceTypeConfigMap, source.Kind) + if source.Kind != string(matcher.ResourceTypeConfigMap) { + t.Errorf("expected kind=%s, got %s", matcher.ResourceTypeConfigMap, source.Kind) } if source.Name != "my-config" { t.Errorf("expected name=my-config, got %s", source.Name) @@ -259,7 +260,7 @@ func TestAnnotationStrategy_Apply(t *testing.T) { annotations := make(map[string]string) input := StrategyInput{ ResourceName: "my-config", - ResourceType: ResourceTypeConfigMap, + ResourceType: matcher.ResourceTypeConfigMap, Namespace: "default", Hash: "abc123", Container: &corev1.Container{Name: "c"}, @@ -302,7 +303,7 @@ func TestAnnotationStrategy_Apply(t *testing.T) { t.Run("error when annotations map is nil", func(t *testing.T) { input := StrategyInput{ ResourceName: "my-config", - ResourceType: ResourceTypeConfigMap, + ResourceType: matcher.ResourceTypeConfigMap, Namespace: "default", Hash: "abc123", PodAnnotations: nil, @@ -338,7 +339,7 @@ func TestNewStrategy(t *testing.T) { func TestEnvVarNameSecretProviderClass(t *testing.T) { s := NewEnvVarStrategy() - got := s.envVarName("my-vault-spc", ResourceTypeSecretProviderClass) + got := s.envVarName("my-vault-spc", matcher.ResourceTypeSecretProviderClass) want := "STAKATER_MY_VAULT_SPC_SECRETPROVIDERCLASS" if got != want { t.Fatalf("envVarName = %q, want %q", got, want) diff --git a/pkg/reload/matcher.go b/pkg/matcher/matcher.go similarity index 95% rename from pkg/reload/matcher.go rename to pkg/matcher/matcher.go index a7ddc50a1..f3d60af60 100644 --- a/pkg/reload/matcher.go +++ b/pkg/matcher/matcher.go @@ -1,4 +1,8 @@ -package reload +// Package matcher provides the annotation-based reload decision API. Given a +// changed resource and a workload's annotations, Matcher reports whether the +// workload should be reloaded. It is workload-type agnostic and safe to import +// from outside this module. +package matcher import ( "regexp" diff --git a/pkg/reload/matcher_test.go b/pkg/matcher/matcher_test.go similarity index 99% rename from pkg/reload/matcher_test.go rename to pkg/matcher/matcher_test.go index f51c56381..3024ea046 100644 --- a/pkg/reload/matcher_test.go +++ b/pkg/matcher/matcher_test.go @@ -1,4 +1,4 @@ -package reload +package matcher import ( "testing" diff --git a/pkg/reload/resource_type.go b/pkg/matcher/resource_type.go similarity index 98% rename from pkg/reload/resource_type.go rename to pkg/matcher/resource_type.go index 5c0868311..23f07a43b 100644 --- a/pkg/reload/resource_type.go +++ b/pkg/matcher/resource_type.go @@ -1,4 +1,4 @@ -package reload +package matcher // ResourceType represents the type of Kubernetes resource. type ResourceType string diff --git a/pkg/reload/resource_type_test.go b/pkg/matcher/resource_type_test.go similarity index 98% rename from pkg/reload/resource_type_test.go rename to pkg/matcher/resource_type_test.go index 51e2f1b57..d04b07562 100644 --- a/pkg/reload/resource_type_test.go +++ b/pkg/matcher/resource_type_test.go @@ -1,4 +1,4 @@ -package reload +package matcher import ( "testing" From 29e74b4722800de98e5adf1c2ee6f6c0204b5a8a Mon Sep 17 00:00:00 2001 From: Safwan Date: Tue, 21 Jul 2026 20:02:01 +0500 Subject: [PATCH 3/9] separate helm workflow --- .github/workflows/pull_request.yaml | 18 ---------- .github/workflows/pull_request_helm.yaml | 42 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 18 deletions(-) create mode 100644 .github/workflows/pull_request_helm.yaml diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index b395e3136..a87c0ba20 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -49,19 +49,6 @@ jobs: ref: ${{github.event.pull_request.head.sha}} fetch-depth: 0 - # Setting up helm binary - - name: Set up Helm - uses: azure/setup-helm@dda3372f752e03dde6b3237bc9431cdc2f7a02a2 # v5 - with: - version: v3.20.2 - - - name: Helm chart unit tests - uses: d3adb5/helm-unittest-action@850bc76597579183998069830d5fa8c3ef0ea34a # v2 - with: - charts: deployments/kubernetes/chart/reloader - helm-version: v3.20.2 - github-token: ${{ secrets.GITHUB_TOKEN }} - - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: @@ -88,11 +75,6 @@ jobs: - name: Run golangci-lint run: make lint - - name: Helm Lint - run: | - cd deployments/kubernetes/chart/reloader - helm lint - - name: Install kubectl run: | curl -LO "https://storage.googleapis.com/kubernetes-release/release/v${KUBERNETES_VERSION}/bin/linux/amd64/kubectl" diff --git a/.github/workflows/pull_request_helm.yaml b/.github/workflows/pull_request_helm.yaml new file mode 100644 index 000000000..9e7c9498c --- /dev/null +++ b/.github/workflows/pull_request_helm.yaml @@ -0,0 +1,42 @@ +name: Pull Request Workflow for Helm Chart changes + +on: + pull_request: + branches: + - master + - 'v**' + paths: + - 'deployments/kubernetes/chart/reloader/**' + +# Default to no GITHUB_TOKEN permissions; each job opts into the minimum it needs. +permissions: {} + +jobs: + helm: + permissions: + contents: read + runs-on: ubuntu-latest + name: Helm Lint & Unit Tests + steps: + - name: Check out code + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + with: + ref: ${{ github.event.pull_request.head.sha }} + + # Setting up helm binary + - name: Set up Helm + uses: azure/setup-helm@dda3372f752e03dde6b3237bc9431cdc2f7a02a2 # v5 + with: + version: v3.20.2 + + - name: Helm chart unit tests + uses: d3adb5/helm-unittest-action@850bc76597579183998069830d5fa8c3ef0ea34a # v2 + with: + charts: deployments/kubernetes/chart/reloader + helm-version: v3.20.2 + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Helm Lint + run: | + cd deployments/kubernetes/chart/reloader + helm lint From 65d4f12067a5cda721d120319d3b403387536be8 Mon Sep 17 00:00:00 2001 From: Safwan Date: Tue, 21 Jul 2026 20:11:54 +0500 Subject: [PATCH 4/9] fix tests --- internal/pkg/config/flags/flags_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/pkg/config/flags/flags_test.go b/internal/pkg/config/flags/flags_test.go index f14ecf83f..9f9022d5e 100644 --- a/internal/pkg/config/flags/flags_test.go +++ b/internal/pkg/config/flags/flags_test.go @@ -588,7 +588,7 @@ func TestSplitAndTrim(t *testing.T) { func TestApplyFlags_NamespacesScoped(t *testing.T) { resetViper() - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -613,7 +613,7 @@ func TestApplyFlags_NamespacesScoped(t *testing.T) { func TestApplyFlags_NamespacesFromEnv(t *testing.T) { resetViper() t.Setenv("KUBERNETES_NAMESPACE", "single-ns") - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -632,7 +632,7 @@ func TestApplyFlags_NamespacesFromEnv(t *testing.T) { func TestApplyFlags_NamespacesGlobal(t *testing.T) { resetViper() t.Setenv("KUBERNETES_NAMESPACE", "") - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -653,7 +653,7 @@ func TestApplyFlags_NamespacesGlobal(t *testing.T) { func TestApplyFlags_NamespacesTrimsEmptyEntries(t *testing.T) { resetViper() - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -678,7 +678,7 @@ func TestApplyFlags_NamespacesTrimsEmptyEntries(t *testing.T) { func TestApplyFlags_NamespacesAllEmptyIsGlobal(t *testing.T) { resetViper() t.Setenv("KUBERNETES_NAMESPACE", "") - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -702,7 +702,7 @@ func TestApplyFlags_NamespacesAllEmptyIsGlobal(t *testing.T) { // for each dropped setting. func TestApplyFlags_ScopedClearsSelectorsAndIgnores(t *testing.T) { resetViper() - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) @@ -728,7 +728,7 @@ func TestApplyFlags_ScopedClearsSelectorsAndIgnores(t *testing.T) { func TestApplyFlags_GlobalKeepsSelectorsNoWarnings(t *testing.T) { resetViper() t.Setenv("KUBERNETES_NAMESPACE", "") - cfg := NewDefault() + cfg := config.NewDefault() fs := pflag.NewFlagSet("test", pflag.ContinueOnError) BindFlags(fs, cfg) From a213122ee1aa5995140054ec7d6eb835ae0a6a56 Mon Sep 17 00:00:00 2001 From: Safwan Date: Tue, 21 Jul 2026 20:24:59 +0500 Subject: [PATCH 5/9] fix docker file --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index d9ca0edcd..07e17ae95 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,6 +26,7 @@ RUN go mod download # Copy the go source COPY cmd/ cmd/ COPY internal/ internal/ +COPY pkg/ pkg/ # Build RUN CGO_ENABLED=0 \ From 1cee04eeb02d7208cb578490dada7b294f2c9438 Mon Sep 17 00:00:00 2001 From: Safwan Date: Tue, 21 Jul 2026 21:00:57 +0500 Subject: [PATCH 6/9] disable chart dependency for now. --- deployments/kubernetes/chart/reloader/Chart.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/deployments/kubernetes/chart/reloader/Chart.yaml b/deployments/kubernetes/chart/reloader/Chart.yaml index 2e11cd6c0..f7f95001d 100644 --- a/deployments/kubernetes/chart/reloader/Chart.yaml +++ b/deployments/kubernetes/chart/reloader/Chart.yaml @@ -17,9 +17,9 @@ maintainers: email: rasheed@stakater.com - name: faizanahmad055 email: faizan@stakater.com -dependencies: - - name: reloader-enterprise - alias: enterprise - version: 0.1.0 - repository: oci://ghcr.io/stakater/charts - condition: enterprise.enabled +# dependencies: +# - name: reloader-enterprise +# alias: enterprise +# version: 0.1.0 +# repository: oci://ghcr.io/stakater/charts +# condition: enterprise.enabled From a413127b7e587756637c0f15e31627822a00a87d Mon Sep 17 00:00:00 2001 From: Safwan Date: Tue, 21 Jul 2026 21:47:43 +0500 Subject: [PATCH 7/9] fix helm util for tests --- test/e2e/utils/helm.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/test/e2e/utils/helm.go b/test/e2e/utils/helm.go index 320782d2b..31484ca89 100644 --- a/test/e2e/utils/helm.go +++ b/test/e2e/utils/helm.go @@ -106,8 +106,8 @@ func UndeployReloader(namespace, releaseName string) error { kind string name string }{ - {"clusterrole", releaseName + "-reloader-role"}, - {"clusterrolebinding", releaseName + "-reloader-role-binding"}, + {"clusterrole", ReloaderDeploymentName(releaseName) + "-role"}, + {"clusterrolebinding", ReloaderDeploymentName(releaseName) + "-role-binding"}, } for _, res := range clusterResources { @@ -144,8 +144,8 @@ func cleanupClusterResources(releaseName string) { kind string name string }{ - {"clusterrole", releaseName + "-reloader-role"}, - {"clusterrolebinding", releaseName + "-reloader-role-binding"}, + {"clusterrole", ReloaderDeploymentName(releaseName) + "-role"}, + {"clusterrolebinding", ReloaderDeploymentName(releaseName) + "-role-binding"}, } for _, res := range clusterResources { @@ -207,7 +207,10 @@ func ReloaderDeploymentName(releaseName string) string { if releaseName == "" { releaseName = DefaultHelmReleaseName } - return releaseName + "-reloader" + // The chart is named "reloader-v2", so the fullname template renders + // -reloader-v2. Keep this the single source of truth; the + // cluster-role and pod-selector helpers derive their names from it. + return releaseName + "-reloader-v2" } // ReloaderPodSelector returns the label selector for Reloader pods. @@ -215,5 +218,5 @@ func ReloaderPodSelector(releaseName string) string { if releaseName == "" { releaseName = DefaultHelmReleaseName } - return "app=" + releaseName + "-reloader" + return "app=" + ReloaderDeploymentName(releaseName) } From 698e658e09fa8c6f9bb0ed223a34c6aff14985c8 Mon Sep 17 00:00:00 2001 From: Safwan Date: Tue, 21 Jul 2026 22:08:26 +0500 Subject: [PATCH 8/9] fix unit tests --- test/e2e/utils/helm_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/e2e/utils/helm_test.go b/test/e2e/utils/helm_test.go index 2e334ebe6..513be4480 100644 --- a/test/e2e/utils/helm_test.go +++ b/test/e2e/utils/helm_test.go @@ -124,12 +124,12 @@ func TestReloaderDeploymentName(t *testing.T) { { name: "default release name", releaseName: "", - expected: "reloader-reloader", + expected: "reloader-reloader-v2", }, { name: "custom release name", releaseName: "my-reloader", - expected: "my-reloader-reloader", + expected: "my-reloader-reloader-v2", }, } @@ -152,12 +152,12 @@ func TestReloaderPodSelector(t *testing.T) { { name: "default release name", releaseName: "", - expected: "app=reloader-reloader", + expected: "app=reloader-reloader-v2", }, { name: "custom release name", releaseName: "my-reloader", - expected: "app=my-reloader-reloader", + expected: "app=my-reloader-reloader-v2", }, } From 9f6e931723c2efa0de4104ba5e7308e354e8c0f5 Mon Sep 17 00:00:00 2001 From: Safwan Date: Wed, 22 Jul 2026 19:22:09 +0500 Subject: [PATCH 9/9] remove oss postfix from this --- pkg/metadata/metadata.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/metadata/metadata.go b/pkg/metadata/metadata.go index efa238a19..43d1af0a0 100644 --- a/pkg/metadata/metadata.go +++ b/pkg/metadata/metadata.go @@ -20,7 +20,7 @@ const ( // ConfigMapLabelKey is the label key for the metadata ConfigMap. ConfigMapLabelKey = "reloader.stakater.com/meta-info" // ConfigMapLabelValue is the label value for the metadata ConfigMap. - ConfigMapLabelValue = "reloader-oss" + ConfigMapLabelValue = "reloader" // Environment variables for deployment info. EnvReloaderNamespace = "RELOADER_NAMESPACE"