diff --git a/cmd/api-syncagent/main.go b/cmd/api-syncagent/main.go index 9febe46..a04c767 100644 --- a/cmd/api-syncagent/main.go +++ b/cmd/api-syncagent/main.go @@ -21,6 +21,7 @@ import ( "flag" "fmt" golog "log" + "slices" "strings" "github.com/go-logr/zapr" @@ -46,6 +47,7 @@ import ( "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" ctrlruntime "sigs.k8s.io/controller-runtime" @@ -57,6 +59,8 @@ import ( metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" ) +var availableControllers = sets.New("apiexport", "apiresourceschema", "sync") + func main() { ctx := context.Background() @@ -133,16 +137,37 @@ func run(ctx context.Context, log *zap.SugaredLogger, opts *Options) error { return fmt.Errorf("failed to add kcp cluster runnable: %w", err) } - if err := apiresourceschema.Add(mgr, kcpCluster, lcName, log, 4, opts.AgentName, opts.PublishedResourceSelector); err != nil { - return fmt.Errorf("failed to add apiresourceschema controller: %w", err) + startController := func(name string, creator func() error) error { + if slices.Contains(opts.DisabledControllers, name) { + log.Infof("Not starting %s controller because it is disabled.", name) + return nil + } + + if err := creator(); err != nil { + return fmt.Errorf("failed to add %s controller: %w", name, err) + } + + return nil + } + + if err := startController("apiresourceschema", func() error { + return apiresourceschema.Add(mgr, kcpCluster, lcName, log, 4, opts.AgentName, opts.PublishedResourceSelector) + }); err != nil { + return err } - if err := apiexport.Add(mgr, kcpCluster, lcName, log, opts.APIExportRef, opts.AgentName, opts.PublishedResourceSelector); err != nil { - return fmt.Errorf("failed to add apiexport controller: %w", err) + if err := startController("apiexport", func() error { + return apiexport.Add(mgr, kcpCluster, lcName, log, opts.APIExportRef, opts.AgentName, opts.PublishedResourceSelector) + }); err != nil { + return err } - if err := syncmanager.Add(ctx, mgr, kcpCluster, kcpRestConfig, log, apiExport, opts.PublishedResourceSelector, opts.Namespace, opts.AgentName); err != nil { - return fmt.Errorf("failed to add syncmanager controller: %w", err) + // This controller is called "sync" because it makes the most sense to the users, even though internally the relevant + // controller is the syncmanager (which in turn would start/stop the sync controllers). + if err := startController("sync", func() error { + return syncmanager.Add(ctx, mgr, kcpCluster, kcpRestConfig, log, apiExport, opts.PublishedResourceSelector, opts.Namespace, opts.AgentName) + }); err != nil { + return err } log.Info("Starting kcp Sync Agent…") diff --git a/cmd/api-syncagent/options.go b/cmd/api-syncagent/options.go index 1d75f4e..38165d6 100644 --- a/cmd/api-syncagent/options.go +++ b/cmd/api-syncagent/options.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/labels" utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation" ) @@ -68,6 +69,8 @@ type Options struct { MetricsAddr string HealthAddr string + + DisabledControllers []string } func NewOptions() *Options { @@ -91,6 +94,7 @@ func (o *Options) AddFlags(flags *pflag.FlagSet) { flags.StringVar(&o.KubeconfigCAFileOverride, "kubeconfig-ca-file-override", o.KubeconfigCAFileOverride, "override the server CA file configured in the local kubeconfig") flags.StringVar(&o.MetricsAddr, "metrics-address", o.MetricsAddr, "host and port to serve Prometheus metrics via /metrics (HTTP)") flags.StringVar(&o.HealthAddr, "health-address", o.HealthAddr, "host and port to serve probes via /readyz and /healthz (HTTP)") + flags.StringSliceVar(&o.DisabledControllers, "disabled-controllers", o.DisabledControllers, fmt.Sprintf("comma-separated list of controllers (out of %v) to disable (can be given multiple times)", sets.List(availableControllers))) } func (o *Options) Validate() error { @@ -124,6 +128,13 @@ func (o *Options) Validate() error { } } + disabled := sets.New(o.DisabledControllers...) + unknown := disabled.Difference(availableControllers) + + if unknown.Len() > 0 { + errs = append(errs, fmt.Errorf("unknown controller(s) %v, mut be any of %v", sets.List(unknown), sets.List(availableControllers))) + } + return utilerrors.NewAggregate(errs) }