From f269c56afac0b92bd23c8877c5417aae7addce7b Mon Sep 17 00:00:00 2001 From: achimweigel Date: Thu, 18 Jan 2024 06:01:15 +0100 Subject: [PATCH] separate clients - introduce cache (run-int-tests) (#948) --- .../templates/clusterrole.yaml | 15 +- .../helm-deployer/templates/clusterrole.yaml | 3 +- .../templates/clusterrole.yaml | 3 +- .../mock-deployer/templates/clusterrole.yaml | 3 +- .../container-deployer-controller/app/app.go | 7 +- cmd/helm-deployer-controller/app/app.go | 7 +- cmd/landscaper-agent/app/app.go | 10 +- cmd/landscaper-agent/app/options.go | 22 +- cmd/landscaper-controller/app/app.go | 102 +++++----- cmd/landscaper-controller/app/app_test.go | 8 +- cmd/manifest-deployer-controller/app/app.go | 9 +- cmd/mock-deployer-controller/app/app.go | 7 +- cmd/target-sync-controller/app/app.go | 40 ++-- pkg/agent/add.go | 34 ++-- pkg/agent/agent.go | 67 ++++--- pkg/agent/agent_test.go | 7 +- pkg/deployer/container/add.go | 40 ++-- pkg/deployer/container/container.go | 26 +-- pkg/deployer/container/container_delete.go | 4 +- pkg/deployer/container/container_reconcile.go | 22 +- .../container/container_suite_test.go | 3 +- pkg/deployer/container/garbage_collector.go | 66 +++--- .../container/garbage_collector_test.go | 9 +- pkg/deployer/container/pod.go | 2 +- .../container/reconciler_deployitem.go | 43 ++-- pkg/deployer/helm/add.go | 30 +-- pkg/deployer/helm/deletionmanager_test.go | 8 +- pkg/deployer/helm/deployer.go | 32 +-- pkg/deployer/helm/ensure.go | 14 +- pkg/deployer/helm/helm.go | 26 ++- pkg/deployer/helm/helm_suite_test.go | 6 +- pkg/deployer/helm/test/e2e_test.go | 10 +- pkg/deployer/lib/cmd/default.go | 93 +++++++-- pkg/deployer/lib/controller.go | 64 ++++-- pkg/deployer/lib/finished_objects.go | 11 + .../lib/targetselector/e2e_suite_test.go | 44 ++-- pkg/deployer/lib/utils.go | 2 +- pkg/deployer/manifest/add.go | 30 +-- pkg/deployer/manifest/controller.go | 35 ++-- pkg/deployer/manifest/ensure.go | 14 +- pkg/deployer/manifest/manifest.go | 16 +- pkg/deployer/manifest/test/e2e_test.go | 8 +- pkg/deployer/mock/add.go | 43 ++-- pkg/deployer/mock/controller.go | 36 ++-- pkg/deployermanagement/controller/add.go | 27 +-- .../controller/controller.go | 102 +++++----- .../controller/controller_reconcile_test.go | 4 +- .../controller/deployer_management_delete.go | 4 +- .../deployer_management_reconcile.go | 43 ++-- .../controller/deployer_management_test.go | 2 +- pkg/landscaper/controllers/context/add.go | 14 +- .../controllers/context/controller.go | 14 +- .../controllers/context/reconcile_test.go | 4 +- pkg/landscaper/controllers/deployitem/add.go | 13 +- .../controllers/deployitem/controller.go | 24 ++- .../controllers/deployitem/reconcile.go | 4 +- .../controllers/deployitem/reconcile_test.go | 2 +- pkg/landscaper/controllers/execution/add.go | 8 +- pkg/landscaper/controllers/execution/check.go | 29 +++ .../controllers/execution/controller.go | 126 +++++++++--- .../controllers/execution/reconcile_test.go | 2 +- .../controllers/installations/add.go | 13 +- .../controllers/installations/checks.go | 65 ++++++ .../controllers/installations/controller.go | 188 ++++++++++++------ .../installations/controller_test.go | 17 +- .../controllers/installations/reconcile.go | 22 +- .../installations/reconcile_delete.go | 32 +-- .../installations/reconcile_delete_test.go | 8 +- .../controllers/installations/registry.go | 2 +- .../installations/retry_helper_test.go | 6 +- .../targetsync/targetsync_controller.go | 60 +++--- .../targetsync/targetsync_controller_test.go | 2 +- pkg/landscaper/execution/execution.go | 18 +- pkg/landscaper/execution/gc.go | 4 +- pkg/landscaper/execution/helper.go | 6 +- pkg/landscaper/execution/reconcile.go | 10 +- pkg/landscaper/installations/builder.go | 6 +- pkg/landscaper/installations/context.go | 2 +- pkg/landscaper/installations/context_test.go | 10 +- .../installations/executions/complete.go | 4 +- .../executions/executions_test.go | 2 +- .../installations/executions/operation.go | 6 +- .../executions/operation_test.go | 2 +- .../installations/exports/constructor.go | 8 +- .../installations/exports/constructor_test.go | 2 +- .../imports/conditional_imports_test.go | 2 +- .../installations/imports/constructor.go | 4 +- .../installations/imports/constructor_test.go | 2 +- .../installations/imports/importexec_test.go | 2 +- pkg/landscaper/installations/operation.go | 32 +-- .../installations/operation_test.go | 2 +- .../reconcilehelper/reconcilehelper.go | 4 +- .../reconcilehelper/validation_test.go | 2 +- .../subinstallations/subinstallations.go | 10 +- .../subinstallations/subinstallations_test.go | 2 +- pkg/landscaper/operation/builder.go | 10 +- pkg/landscaper/operation/operation.go | 20 +- pkg/utils/constants.go | 21 +- pkg/utils/finished_object_cache.go | 75 +++++++ pkg/utils/performance_measurement.go | 38 ++++ pkg/utils/read_write_layer/consts.go | 12 +- pkg/utils/read_write_layer/read.go | 4 + pkg/utils/uncached_client.go | 30 ++- .../deployers/management/dm_tests.go | 11 +- test/landscaper/e2e/inlinecd_test.go | 13 +- test/landscaper/e2e/simple_test.go | 21 +- 106 files changed, 1455 insertions(+), 860 deletions(-) create mode 100644 pkg/deployer/lib/finished_objects.go create mode 100644 pkg/landscaper/controllers/execution/check.go create mode 100644 pkg/landscaper/controllers/installations/checks.go create mode 100644 pkg/utils/finished_object_cache.go create mode 100644 pkg/utils/performance_measurement.go diff --git a/charts/container-deployer/templates/clusterrole.yaml b/charts/container-deployer/templates/clusterrole.yaml index f628e7664..4d82a8b86 100644 --- a/charts/container-deployer/templates/clusterrole.yaml +++ b/charts/container-deployer/templates/clusterrole.yaml @@ -56,27 +56,24 @@ rules: - patch - update -- apiGroups: - - "" - resources: - - "secrets" - verbs: - - "*" - - apiGroups: - "" resources: - "pods" - "pods/status" + - "secrets" + - "serviceaccounts" verbs: - "*" - apiGroups: - "" resources: - - "serviceaccounts" + - namespaces verbs: - - "*" + - get + - list + - watch - apiGroups: - "rbac.authorization.k8s.io" diff --git a/charts/helm-deployer/templates/clusterrole.yaml b/charts/helm-deployer/templates/clusterrole.yaml index a0edd3dcc..6b4a1b385 100644 --- a/charts/helm-deployer/templates/clusterrole.yaml +++ b/charts/helm-deployer/templates/clusterrole.yaml @@ -37,7 +37,8 @@ rules: - apiGroups: - "" resources: - - "pods" + - namespaces + - pods verbs: - get - watch diff --git a/charts/manifest-deployer/templates/clusterrole.yaml b/charts/manifest-deployer/templates/clusterrole.yaml index 2c5a40f08..02268c509 100644 --- a/charts/manifest-deployer/templates/clusterrole.yaml +++ b/charts/manifest-deployer/templates/clusterrole.yaml @@ -58,7 +58,8 @@ rules: - apiGroups: - "" resources: - - "pods" + - namespaces + - pods verbs: - get - watch diff --git a/charts/mock-deployer/templates/clusterrole.yaml b/charts/mock-deployer/templates/clusterrole.yaml index 979b1153b..0994b6bf2 100644 --- a/charts/mock-deployer/templates/clusterrole.yaml +++ b/charts/mock-deployer/templates/clusterrole.yaml @@ -47,7 +47,8 @@ rules: - apiGroups: - "" resources: - - "pods" + - namespaces + - pods verbs: - get - watch diff --git a/cmd/container-deployer/container-deployer-controller/app/app.go b/cmd/container-deployer/container-deployer-controller/app/app.go index c8fdcd65b..12e7e0e5a 100644 --- a/cmd/container-deployer/container-deployer-controller/app/app.go +++ b/cmd/container-deployer/container-deployer-controller/app/app.go @@ -37,7 +37,10 @@ func NewContainerDeployerControllerCommand(ctx context.Context) *cobra.Command { func (o *options) run(ctx context.Context) error { o.DeployerOptions.Log.Info("Starting Container Deployer", lc.KeyVersion, version.Get().GitVersion) - gc, err := containerctlr.AddControllerToManager(o.DeployerOptions.Log, + gc, err := containerctlr.AddControllerToManager( + o.DeployerOptions.LsUncachedClient, o.DeployerOptions.LsCachedClient, o.DeployerOptions.HostUncachedClient, o.DeployerOptions.HostCachedClient, + o.DeployerOptions.FinishedObjectCache, + o.DeployerOptions.Log, o.DeployerOptions.HostMgr, o.DeployerOptions.LsMgr, o.Config, @@ -46,6 +49,8 @@ func (o *options) run(ctx context.Context) error { return fmt.Errorf("unable to setup container controller") } + o.DeployerOptions.Log.Info("Starting container deployer manager") + if gc == nil { return o.DeployerOptions.StartManagers(ctx) } else { diff --git a/cmd/helm-deployer-controller/app/app.go b/cmd/helm-deployer-controller/app/app.go index a67e5c76d..ebfe90de0 100644 --- a/cmd/helm-deployer-controller/app/app.go +++ b/cmd/helm-deployer-controller/app/app.go @@ -37,9 +37,14 @@ func NewHelmDeployerControllerCommand(ctx context.Context) *cobra.Command { func (o *options) run(ctx context.Context) error { o.DeployerOptions.Log.Info("Starting helm deployer", lc.KeyVersion, version.Get().GitVersion) - if err := helmctrl.AddDeployerToManager(o.DeployerOptions.Log, o.DeployerOptions.LsMgr, o.DeployerOptions.HostMgr, + if err := helmctrl.AddDeployerToManager( + o.DeployerOptions.LsUncachedClient, o.DeployerOptions.LsCachedClient, o.DeployerOptions.HostUncachedClient, o.DeployerOptions.HostCachedClient, + o.DeployerOptions.FinishedObjectCache, + o.DeployerOptions.Log, o.DeployerOptions.LsMgr, o.DeployerOptions.HostMgr, o.Config, "helm"); err != nil { return fmt.Errorf("unable to setup helm controller") } + + o.DeployerOptions.Log.Info("Starting helm deployer manager") return o.DeployerOptions.StartManagers(ctx) } diff --git a/cmd/landscaper-agent/app/app.go b/cmd/landscaper-agent/app/app.go index dc4ea208b..68a73ae97 100644 --- a/cmd/landscaper-agent/app/app.go +++ b/cmd/landscaper-agent/app/app.go @@ -14,7 +14,7 @@ import ( lc "github.com/gardener/landscaper/controller-utils/pkg/logging/constants" "github.com/gardener/landscaper/pkg/agent" - + lsutils "github.com/gardener/landscaper/pkg/utils" "github.com/gardener/landscaper/pkg/version" ) @@ -43,7 +43,13 @@ func NewLandscaperAgentCommand(ctx context.Context) *cobra.Command { func (o *options) run(ctx context.Context) error { o.log.Info("Starting Landscaper Agent", lc.KeyVersion, version.Get().String()) - if err := agent.AddToManager(ctx, o.log, o.LsMgr, o.HostMgr, o.config, "agent-helm"); err != nil { + lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, err := lsutils.ClientsFromManagers(o.LsMgr, o.HostMgr) + if err != nil { + return err + } + + if err := agent.AddToManager(ctx, lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, + o.log, o.LsMgr, o.HostMgr, o.config, "agent-helm"); err != nil { return fmt.Errorf("unable to setup default agent: %w", err) } diff --git a/cmd/landscaper-agent/app/options.go b/cmd/landscaper-agent/app/options.go index 977eef195..aec3fff5b 100644 --- a/cmd/landscaper-agent/app/options.go +++ b/cmd/landscaper-agent/app/options.go @@ -10,9 +10,6 @@ import ( "fmt" "os" - "github.com/gardener/landscaper/controller-utils/pkg/logging" - lsutils "github.com/gardener/landscaper/pkg/utils" - flag "github.com/spf13/pflag" "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/client-go/tools/clientcmd" @@ -21,7 +18,9 @@ import ( "github.com/gardener/landscaper/apis/config" lsinstall "github.com/gardener/landscaper/apis/core/install" + "github.com/gardener/landscaper/controller-utils/pkg/logging" "github.com/gardener/landscaper/pkg/api" + lsutils "github.com/gardener/landscaper/pkg/utils" ) type options struct { @@ -69,31 +68,30 @@ func (o *options) Complete() error { LeaderElection: false, Port: 9443, MetricsBindAddress: "0", - NewClient: lsutils.NewUncachedClient(lsutils.LsHostClientBurstDefault, lsutils.LsHostClientQpsDefault), } + hostRestConfig, err := ctrl.GetConfig() if err != nil { return fmt.Errorf("unable to get host kubeconfig: %w", err) } + hostRestConfig = lsutils.RestConfigWithModifiedClientRequestRestrictions(log, hostRestConfig, lsutils.LsHostClientBurstDefault, lsutils.LsHostClientQpsDefault) + o.HostMgr, err = ctrl.NewManager(hostRestConfig, opts) if err != nil { - return fmt.Errorf("unable to setup manager") + return fmt.Errorf("unable to setup host manager") } data, err := os.ReadFile(o.landscaperKubeconfigPath) if err != nil { return fmt.Errorf("unable to read landscaper kubeconfig from %s: %w", o.landscaperKubeconfigPath, err) } - client, err := clientcmd.NewClientConfigFromBytes(data) - if err != nil { - return fmt.Errorf("unable to build landscaper cluster client from %s: %w", o.landscaperKubeconfigPath, err) - } - lsRestConfig, err := client.ClientConfig() + + lsRestConfig, err := clientcmd.RESTConfigFromKubeConfig(data) if err != nil { - return fmt.Errorf("unable to build landscaper cluster rest client from %s: %w", o.landscaperKubeconfigPath, err) + return fmt.Errorf("unable to build landscaper cluster rest client for agent: %w", err) } + lsRestConfig = lsutils.RestConfigWithModifiedClientRequestRestrictions(log, lsRestConfig, lsutils.LsResourceClientBurstDefault, lsutils.LsResourceClientQpsDefault) - opts.NewClient = lsutils.NewUncachedClient(lsutils.LsResourceClientBurstDefault, lsutils.LsResourceClientQpsDefault) o.LsMgr, err = ctrl.NewManager(lsRestConfig, opts) if err != nil { return fmt.Errorf("unable to setup manager") diff --git a/cmd/landscaper-controller/app/app.go b/cmd/landscaper-controller/app/app.go index ea9995a1f..7d1233851 100644 --- a/cmd/landscaper-controller/app/app.go +++ b/cmd/landscaper-controller/app/app.go @@ -85,7 +85,6 @@ func (o *Options) run(ctx context.Context) error { LeaderElection: false, Port: 9443, MetricsBindAddress: "0", - NewClient: lsutils.NewUncachedClient(burst, qps), } //TODO: investigate whether this is used with an uncached client @@ -97,7 +96,10 @@ func (o *Options) run(ctx context.Context) error { opts.MetricsBindAddress = fmt.Sprintf(":%d", o.Config.Metrics.Port) } - hostMgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), opts) + hostRestConfig := ctrl.GetConfigOrDie() + hostRestConfig = lsutils.RestConfigWithModifiedClientRequestRestrictions(setupLogger, hostRestConfig, burst, qps) + + hostMgr, err := ctrl.NewManager(hostRestConfig, opts) if err != nil { return fmt.Errorf("unable to setup manager: %w", err) } @@ -108,20 +110,15 @@ func (o *Options) run(ctx context.Context) error { if err != nil { return fmt.Errorf("unable to read landscaper kubeconfig from %s: %w", o.landscaperKubeconfigPath, err) } - client, err := clientcmd.NewClientConfigFromBytes(data) - if err != nil { - return fmt.Errorf("unable to build landscaper cluster client from %s: %w", o.landscaperKubeconfigPath, err) - } - lsConfig, err := client.ClientConfig() + + lsRestConfig, err := clientcmd.RESTConfigFromKubeConfig(data) if err != nil { - return fmt.Errorf("unable to build landscaper cluster rest client from %s: %w", o.landscaperKubeconfigPath, err) + return fmt.Errorf("unable to build landscaper cluster rest client: %w", err) } - - opts.MetricsBindAddress = "0" burst, qps = lsutils.GetResourceClientRequestRestrictions(setupLogger) - opts.NewClient = lsutils.NewUncachedClient(burst, qps) + lsRestConfig = lsutils.RestConfigWithModifiedClientRequestRestrictions(setupLogger, lsRestConfig, burst, qps) - lsMgr, err = ctrl.NewManager(lsConfig, opts) + lsMgr, err = ctrl.NewManager(lsRestConfig, opts) if err != nil { return fmt.Errorf("unable to setup landscaper cluster manager from %s: %w", o.landscaperKubeconfigPath, err) } @@ -130,17 +127,33 @@ func (o *Options) run(ctx context.Context) error { metrics.RegisterMetrics(controllerruntimeMetrics.Registry) ctrlLogger := o.Log.WithName("controllers") + if err := o.ensureCRDs(ctx, lsMgr); err != nil { + return err + } + if lsMgr != hostMgr { + if err := o.ensureCRDs(ctx, hostMgr); err != nil { + return err + } + } + install.Install(lsMgr.GetScheme()) + + lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, err := lsutils.ClientsFromManagers(lsMgr, hostMgr) + if err != nil { + return err + } + if os.Getenv("LANDSCAPER_MODE") == "central-landscaper" { - return o.startCentralLandscaper(ctx, lsMgr, hostMgr, ctrlLogger, setupLogger) + return o.startCentralLandscaper(ctx, lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, + lsMgr, hostMgr, ctrlLogger, setupLogger) } else { - return o.startMainController(ctx, lsMgr, hostMgr, ctrlLogger, setupLogger) + return o.startMainController(ctx, lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, + lsMgr, hostMgr, ctrlLogger, setupLogger) } - } -func (o *Options) startMainController(ctx context.Context, lsMgr, hostMgr manager.Manager, - ctrlLogger, setupLogger logging.Logger) error { - install.Install(lsMgr.GetScheme()) +func (o *Options) startMainController(ctx context.Context, + lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + lsMgr, hostMgr manager.Manager, ctrlLogger, setupLogger logging.Logger) error { store, err := blueprint.NewStore(o.Log.WithName("blueprintStore"), osfs.New(), o.Config.BlueprintStore) if err != nil { @@ -148,11 +161,13 @@ func (o *Options) startMainController(ctx context.Context, lsMgr, hostMgr manage } blueprint.SetStore(store) - if err := installationsctrl.AddControllerToManager(ctrlLogger, lsMgr, hostMgr, o.Config, "installations"); err != nil { + if err := installationsctrl.AddControllerToManager(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, + ctrlLogger, lsMgr, o.Config, "installations"); err != nil { return fmt.Errorf("unable to setup installation controller: %w", err) } - if err := executionactrl.AddControllerToManager(ctrlLogger, lsMgr, hostMgr, o.Config); err != nil { + if err := executionactrl.AddControllerToManager(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, + ctrlLogger, lsMgr, hostMgr, o.Config); err != nil { return fmt.Errorf("unable to setup execution controller: %w", err) } @@ -181,27 +196,16 @@ func (o *Options) startMainController(ctx context.Context, lsMgr, hostMgr manage return eg.Wait() } -func (o *Options) startCentralLandscaper(ctx context.Context, lsMgr, hostMgr manager.Manager, - ctrlLogger, setupLogger logging.Logger) error { - - if err := o.ensureCRDs(ctx, lsMgr); err != nil { - return err - } - - if lsMgr != hostMgr { - if err := o.ensureCRDs(ctx, hostMgr); err != nil { - return err - } - } - - install.Install(lsMgr.GetScheme()) +func (o *Options) startCentralLandscaper(ctx context.Context, + lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + lsMgr, hostMgr manager.Manager, ctrlLogger, setupLogger logging.Logger) error { - if err := contextctrl.AddControllerToManager(ctrlLogger, lsMgr, o.Config); err != nil { + if err := contextctrl.AddControllerToManager(lsUncachedClient, lsCachedClient, ctrlLogger, lsMgr, o.Config); err != nil { return fmt.Errorf("unable to setup context controller: %w", err) } if !o.Config.DeployerManagement.Disable { - if err := deployers.AddControllersToManager(ctrlLogger, lsMgr, o.Config); err != nil { + if err := deployers.AddControllersToManager(lsUncachedClient, lsCachedClient, ctrlLogger, lsMgr, o.Config); err != nil { return fmt.Errorf("unable to setup deployer controllers: %w", err) } if !o.Config.DeployerManagement.Agent.Disable { @@ -217,11 +221,12 @@ func (o *Options) startCentralLandscaper(ctx context.Context, lsMgr, hostMgr man }, }, ) - if err := agent.AddToManager(ctx, o.Log, lsMgr, hostMgr, agentConfig, "landscaper-helm"); err != nil { + if err := agent.AddToManager(ctx, lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, + o.Log, lsMgr, hostMgr, agentConfig, "landscaper-helm"); err != nil { return fmt.Errorf("unable to setup default agent: %w", err) } } - if err := o.DeployInternalDeployers(ctx, lsMgr); err != nil { + if err := o.DeployInternalDeployers(ctx, lsUncachedClient); err != nil { return err } @@ -236,21 +241,22 @@ func (o *Options) startCentralLandscaper(ctx context.Context, lsMgr, hostMgr man } } - if err := deployitemctrl.AddControllerToManager(ctrlLogger, + if err := deployitemctrl.AddControllerToManager(lsUncachedClient, lsCachedClient, + ctrlLogger, lsMgr, o.Config.Controllers.DeployItems, o.Config.DeployItemTimeouts.Pickup); err != nil { return fmt.Errorf("unable to setup deployitem controller: %w", err) } - if err := targetsync.AddControllerToManagerForTargetSyncs(ctrlLogger, lsMgr); err != nil { + if err := targetsync.AddControllerToManagerForTargetSyncs(lsUncachedClient, lsCachedClient, ctrlLogger, lsMgr); err != nil { return fmt.Errorf("unable to register target sync controller: %w", err) } eg, ctx := errgroup.WithContext(ctx) eg.Go(func() error { - healthChecker := healthcheck.NewHealthChecker(o.Config.LsDeployments, hostMgr.GetClient()) + healthChecker := healthcheck.NewHealthChecker(o.Config.LsDeployments, hostUncachedClient) if err := healthChecker.StartPeriodicalHealthCheck(ctx, ctrlLogger); err != nil { return err } @@ -258,13 +264,13 @@ func (o *Options) startCentralLandscaper(ctx context.Context, lsMgr, hostMgr man }) eg.Go(func() error { - lockCleaner := lock.NewLockCleaner(lsMgr.GetClient()) + lockCleaner := lock.NewLockCleaner(lsUncachedClient) lockCleaner.StartPeriodicalSyncObjectCleanup(ctx, ctrlLogger) return nil }) eg.Go(func() error { - monitor := monitoring.NewMonitor(lsutils.GetCurrentPodNamespace(), hostMgr.GetClient()) + monitor := monitoring.NewMonitor(lsutils.GetCurrentPodNamespace(), hostUncachedClient) monitor.StartMonitoring(ctx, ctrlLogger) return nil }) @@ -293,15 +299,9 @@ func (o *Options) startCentralLandscaper(ctx context.Context, lsMgr, hostMgr man } // DeployInternalDeployers automatically deploys configured deployers using the new Deployer registrations. -func (o *Options) DeployInternalDeployers(ctx context.Context, mgr manager.Manager) error { - directClient, err := client.New(mgr.GetConfig(), client.Options{ - Scheme: mgr.GetScheme(), - }) - if err != nil { - return fmt.Errorf("unable to create direct client: %q", err) - } +func (o *Options) DeployInternalDeployers(ctx context.Context, lsUncachedClient client.Client) error { ctx = logging.NewContext(ctx, logging.Wrap(ctrl.Log.WithName("deployerManagement"))) - return o.Deployer.DeployInternalDeployers(ctx, directClient, o.Config) + return o.Deployer.DeployInternalDeployers(ctx, lsUncachedClient, o.Config) } func (o *Options) ensureCRDs(ctx context.Context, mgr manager.Manager) error { diff --git a/cmd/landscaper-controller/app/app_test.go b/cmd/landscaper-controller/app/app_test.go index 315f5cfe8..2e698d791 100644 --- a/cmd/landscaper-controller/app/app_test.go +++ b/cmd/landscaper-controller/app/app_test.go @@ -97,7 +97,7 @@ var _ = Describe("Landscaper Controller", func() { opts.Config.DeployerManagement.Namespace = state.Namespace opts.Config.DeployerManagement.Agent.Namespace = state.Namespace - Expect(opts.DeployInternalDeployers(ctx, mgr)).To(Succeed()) + Expect(opts.DeployInternalDeployers(ctx, mgr.GetClient())).To(Succeed()) reg := &lsv1alpha1.DeployerRegistration{} Expect(testenv.Client.Get(ctx, kutil.ObjectKey("container", ""), reg)).To(Succeed()) @@ -116,7 +116,7 @@ var _ = Describe("Landscaper Controller", func() { opts.Config.DeployerManagement.Namespace = state.Namespace opts.Config.DeployerManagement.Agent.Namespace = state.Namespace - Expect(opts.DeployInternalDeployers(ctx, mgr)).To(Succeed()) + Expect(opts.DeployInternalDeployers(ctx, mgr.GetClient())).To(Succeed()) reg := &lsv1alpha1.DeployerRegistration{} Expect(testenv.Client.Get(ctx, kutil.ObjectKey("helm", ""), reg)).To(Succeed()) @@ -145,7 +145,7 @@ var _ = Describe("Landscaper Controller", func() { }, } - Expect(opts.DeployInternalDeployers(ctx, mgr)).To(Succeed()) + Expect(opts.DeployInternalDeployers(ctx, mgr.GetClient())).To(Succeed()) reg := &lsv1alpha1.DeployerRegistration{} Expect(testenv.Client.Get(ctx, kutil.ObjectKey("mock", ""), reg)).To(Succeed()) @@ -185,7 +185,7 @@ somekey: someval "other": lsv1alpha1.NewAnyJSON([]byte("true")), } - Expect(opts.DeployInternalDeployers(ctx, mgr)).To(Succeed()) + Expect(opts.DeployInternalDeployers(ctx, mgr.GetClient())).To(Succeed()) reg = &lsv1alpha1.DeployerRegistration{} Expect(testenv.Client.Get(ctx, kutil.ObjectKey("mock", ""), reg)).To(Succeed()) diff --git a/cmd/manifest-deployer-controller/app/app.go b/cmd/manifest-deployer-controller/app/app.go index 7717323c5..799d99be4 100644 --- a/cmd/manifest-deployer-controller/app/app.go +++ b/cmd/manifest-deployer-controller/app/app.go @@ -37,9 +37,14 @@ func NewManifestDeployerControllerCommand(ctx context.Context) *cobra.Command { func (o *options) run(ctx context.Context) error { o.DeployerOptions.Log.Info("Starting Manifest Deployer", lc.KeyVersion, version.Get().GitVersion) - if err := manifestctlr.AddDeployerToManager(o.DeployerOptions.Log, o.DeployerOptions.LsMgr, + if err := manifestctlr.AddDeployerToManager( + o.DeployerOptions.LsUncachedClient, o.DeployerOptions.LsCachedClient, o.DeployerOptions.HostUncachedClient, o.DeployerOptions.HostCachedClient, + o.DeployerOptions.FinishedObjectCache, + o.DeployerOptions.Log, o.DeployerOptions.LsMgr, o.DeployerOptions.HostMgr, o.Config, "manifest"); err != nil { - return fmt.Errorf("unable to setup helm controller") + return fmt.Errorf("unable to setup manifest controller") } + + o.DeployerOptions.Log.Info("Starting manifest deployer manager") return o.DeployerOptions.StartManagers(ctx) } diff --git a/cmd/mock-deployer-controller/app/app.go b/cmd/mock-deployer-controller/app/app.go index de8091837..d04b1379d 100644 --- a/cmd/mock-deployer-controller/app/app.go +++ b/cmd/mock-deployer-controller/app/app.go @@ -37,9 +37,14 @@ func NewMockDeployerControllerCommand(ctx context.Context) *cobra.Command { func (o *options) run(ctx context.Context) error { o.DeployerOptions.Log.Info("Starting Mock Deployer", lc.KeyVersion, version.Get().GitVersion) - if err := mockctrl.AddDeployerToManager(o.DeployerOptions.Log, o.DeployerOptions.LsMgr, o.DeployerOptions.HostMgr, + if err := mockctrl.AddDeployerToManager( + o.DeployerOptions.LsUncachedClient, o.DeployerOptions.LsCachedClient, o.DeployerOptions.HostUncachedClient, o.DeployerOptions.HostCachedClient, + o.DeployerOptions.FinishedObjectCache, + o.DeployerOptions.Log, o.DeployerOptions.LsMgr, o.DeployerOptions.HostMgr, o.Config, "mock"); err != nil { return fmt.Errorf("unable to setup mock controller") } + + o.DeployerOptions.Log.Info("Starting mock deployer manager") return o.DeployerOptions.StartManagers(ctx) } diff --git a/cmd/target-sync-controller/app/app.go b/cmd/target-sync-controller/app/app.go index 3a0669650..838e1160e 100644 --- a/cmd/target-sync-controller/app/app.go +++ b/cmd/target-sync-controller/app/app.go @@ -9,27 +9,20 @@ import ( "fmt" "os" - "k8s.io/utils/pointer" - - "github.com/gardener/landscaper/controller-utils/pkg/logging" - - "k8s.io/client-go/tools/clientcmd" - - lc "github.com/gardener/landscaper/controller-utils/pkg/logging/constants" - - lsutils "github.com/gardener/landscaper/pkg/utils" - - "github.com/gardener/landscaper/pkg/landscaper/controllers/targetsync" - "github.com/spf13/cobra" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/utils/pointer" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/manager" lsconfig "github.com/gardener/landscaper/apis/config" lsinstall "github.com/gardener/landscaper/apis/core/install" - "github.com/gardener/landscaper/pkg/version" - + "github.com/gardener/landscaper/controller-utils/pkg/logging" + lc "github.com/gardener/landscaper/controller-utils/pkg/logging/constants" + "github.com/gardener/landscaper/pkg/landscaper/controllers/targetsync" "github.com/gardener/landscaper/pkg/landscaper/crdmanager" + lsutils "github.com/gardener/landscaper/pkg/utils" + "github.com/gardener/landscaper/pkg/version" ) // NewTargetSyncControllerCommand creates a new command for the landscaper service controller @@ -63,7 +56,6 @@ func (o *options) run(ctx context.Context) error { LeaderElection: false, Port: 9443, MetricsBindAddress: "0", - NewClient: lsutils.NewUncachedClient(10, 8), } data, err := os.ReadFile(o.landscaperKubeconfigPath) @@ -71,17 +63,13 @@ func (o *options) run(ctx context.Context) error { return fmt.Errorf("unable to read landscaper kubeconfig for target sync controller from %s: %w", o.landscaperKubeconfigPath, err) } - client, err := clientcmd.NewClientConfigFromBytes(data) - if err != nil { - return fmt.Errorf("unable to build landscaper cluster client for target sync controller from %s: %w", o.landscaperKubeconfigPath, err) - } - - lsConfig, err := client.ClientConfig() + lsRestConfig, err := clientcmd.RESTConfigFromKubeConfig(data) if err != nil { return fmt.Errorf("unable to build landscaper cluster rest client for target sync controller from %s: %w", o.landscaperKubeconfigPath, err) } + lsRestConfig = lsutils.RestConfigWithModifiedClientRequestRestrictions(o.Log, lsRestConfig, 10, 8) - lsMgr, err := ctrl.NewManager(lsConfig, opts) + lsMgr, err := ctrl.NewManager(lsRestConfig, opts) if err != nil { return fmt.Errorf("unable to setup manager for target sync controller: %w", err) } @@ -94,7 +82,13 @@ func (o *options) run(ctx context.Context) error { lsinstall.Install(lsMgr.GetScheme()) - if err := targetsync.AddControllerToManagerForTargetSyncs(o.Log, lsMgr); err != nil { + lsUncachedClient, err := lsutils.NewUncachedClientFromManager(lsMgr) + if err != nil { + return fmt.Errorf("unable to build new uncached ls client: %w", err) + } + lsCachedClient := lsMgr.GetClient() + + if err := targetsync.AddControllerToManagerForTargetSyncs(lsUncachedClient, lsCachedClient, o.Log, lsMgr); err != nil { return fmt.Errorf("unable to setup landscaper deployments controller for target sync controller: %w", err) } diff --git a/pkg/agent/add.go b/pkg/agent/add.go index f24969489..3bdf293da 100644 --- a/pkg/agent/add.go +++ b/pkg/agent/add.go @@ -8,6 +8,8 @@ import ( "context" "fmt" + "github.com/gardener/landscaper/pkg/utils" + "k8s.io/apimachinery/pkg/selection" "sigs.k8s.io/controller-runtime/pkg/builder" @@ -26,42 +28,30 @@ import ( ) // AddToManager adds the agent to the provided manager. -func AddToManager(ctx context.Context, logger logging.Logger, lsMgr manager.Manager, hostMgr manager.Manager, +func AddToManager(ctx context.Context, lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + logger logging.Logger, lsMgr manager.Manager, hostMgr manager.Manager, config config.AgentConfiguration, callerName string) error { log := logger.WithName("agent").WithValues("targetEnvironment", config.Name) ctx = logging.NewContext(ctx, log) - // create direct client for the agent to ensure the landscaper resources - lsClient, err := client.New(lsMgr.GetConfig(), client.Options{ - Scheme: lsMgr.GetScheme(), - }) - if err != nil { - return fmt.Errorf("unable to create direct landscaper kubernetes client: %w", err) - } - hostClient, err := client.New(hostMgr.GetConfig(), client.Options{ - Scheme: hostMgr.GetScheme(), - }) - if err != nil { - return fmt.Errorf("unable to create direct landscaper kubernetes client: %w", err) - } - agent := New(lsMgr.GetClient(), + + agent := New(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, lsMgr.GetConfig(), lsMgr.GetScheme(), - hostMgr.GetClient(), hostMgr.GetConfig(), hostMgr.GetScheme(), config, ) - if _, err := agent.EnsureLandscaperResources(ctx, lsClient, hostClient); err != nil { + if _, err := agent.EnsureLandscaperResources(ctx); err != nil { return fmt.Errorf("unable to ensure landscaper resources: %w", err) } - if _, err := agent.EnsureHostResources(ctx, hostClient, lsClient); err != nil { + if _, err := agent.EnsureHostResources(ctx); err != nil { return fmt.Errorf("unable to ensure host resources: %w", err) } - err = builder.ControllerManagedBy(lsMgr). - For(&lsv1alpha1.Environment{}). + err := builder.ControllerManagedBy(lsMgr). + For(&lsv1alpha1.Environment{}, builder.OnlyMetadata). WithLogConstructor(func(r *reconcile.Request) logr.Logger { return log.Reconciles("environment", "Environment").Logr() }). Complete(agent) if err != nil { @@ -88,7 +78,9 @@ func AddToManager(ctx context.Context, logger logging.Logger, lsMgr manager.Mana }, }, } - if err := helmctlr.AddDeployerToManager(log, lsMgr, hostMgr, helmConfig, callerName); err != nil { + if err := helmctlr.AddDeployerToManager(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, + utils.NewFinishedObjectCache(), + log, lsMgr, hostMgr, helmConfig, callerName); err != nil { return err } diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index 20624ca11..6770ceb92 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -38,37 +38,40 @@ import ( // Agent is the internal landscaper agent that contains all landscaper specific code. type Agent struct { - config config.AgentConfiguration - lsClient client.Client - lsRestConfig *rest.Config - lsScheme *runtime.Scheme - hostClient client.Client - hostScheme *runtime.Scheme - hostRestConfig *rest.Config + lsUncachedClient client.Client + lsCachedClient client.Client + hostUncachedClient client.Client + hostCachedClient client.Client + config config.AgentConfiguration + lsRestConfig *rest.Config + lsScheme *runtime.Scheme + hostScheme *runtime.Scheme + hostRestConfig *rest.Config } // New creates a new agent. -func New(lsClient client.Client, +func New(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, lsRestConfig *rest.Config, lsScheme *runtime.Scheme, - hostClient client.Client, hostRestConfig *rest.Config, hostScheme *runtime.Scheme, config config.AgentConfiguration) *Agent { return &Agent{ - config: config, - lsClient: lsClient, - lsRestConfig: lsRestConfig, - lsScheme: lsScheme, - hostClient: hostClient, - hostRestConfig: hostRestConfig, - hostScheme: hostScheme, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + hostUncachedClient: hostUncachedClient, + hostCachedClient: hostCachedClient, + config: config, + lsRestConfig: lsRestConfig, + lsScheme: lsScheme, + hostRestConfig: hostRestConfig, + hostScheme: hostScheme, } } // EnsureLandscaperResources ensures that all landscaper resources // like the Environment and the Target are registered in the landscaper cluster. -func (a *Agent) EnsureLandscaperResources(ctx context.Context, lsClient, hostClient client.Client) (*lsv1alpha1.Environment, error) { +func (a *Agent) EnsureLandscaperResources(ctx context.Context) (*lsv1alpha1.Environment, error) { logger, ctx := logging.FromContextOrNew(ctx, nil, lc.KeyMethod, "EnsureLandscaperResources") target, err := utils.NewTargetBuilder(string(targettypes.KubernetesClusterTargetType)). SecretRef(&lsv1alpha1.LocalSecretReference{ @@ -105,11 +108,11 @@ func (a *Agent) EnsureLandscaperResources(ctx context.Context, lsClient, hostCli env.Spec.HostTarget.TargetSpec = target.Spec } - if err := read_write_layer.GetEnv(ctx, lsClient, kutil.ObjectKeyFromObject(env), env, read_write_layer.R000038); err != nil { + if err := read_write_layer.GetEnv(ctx, a.lsUncachedClient, kutil.ObjectKeyFromObject(env), env, read_write_layer.R000038); err != nil { if apierrors.IsNotFound(err) { logger.Info("Environment not found, creating it") mutateFunc() - if err := lsClient.Create(ctx, env); err != nil { + if err := a.lsUncachedClient.Create(ctx, env); err != nil { return nil, err } return env, nil @@ -125,7 +128,7 @@ func (a *Agent) EnsureLandscaperResources(ctx context.Context, lsClient, hostCli logger.Debug("Cleaning up resources") // cleanup resources but do not remove the finalizer // as we would otherwise just right directly reconcile a new environment. - if err := a.RemoveHostResources(ctx, hostClient); err != nil { + if err := a.RemoveHostResources(ctx); err != nil { return nil, fmt.Errorf("unable to remove host resources: %w", err) } return env, nil @@ -137,7 +140,7 @@ func (a *Agent) EnsureLandscaperResources(ctx context.Context, lsClient, hostCli logger.Info("Updating Environment") mutateFunc() - if err := lsClient.Update(ctx, env); err != nil { + if err := a.lsUncachedClient.Update(ctx, env); err != nil { return nil, err } return env, nil @@ -147,7 +150,7 @@ func (a *Agent) EnsureLandscaperResources(ctx context.Context, lsClient, hostCli // like the Target secret are registered in the landscaper cluster. // The function ensure the following resources: // - the secret containing the kubeconfig for the host kubeconfig -func (a *Agent) EnsureHostResources(ctx context.Context, hostClient, lsClient client.Client) (*rest.Config, error) { +func (a *Agent) EnsureHostResources(ctx context.Context) (*rest.Config, error) { logger, ctx := logging.FromContextOrNew(ctx, nil, lc.KeyMethod, "EnsureHostResources") // create a dedicated service account and rbac rules for the kubeconfig // Currently that kubeconfig has access to all resources as the deployers could install anything. @@ -156,21 +159,21 @@ func (a *Agent) EnsureHostResources(ctx context.Context, hostClient, lsClient cl sa.Name = fmt.Sprintf("deployer-%s", a.config.Name) sa.Namespace = a.config.Namespace logger.Info("Creating/Updating resource", lc.KeyResource, kutil.ObjectKeyFromObject(sa).String(), lc.KeyResourceKind, "ServiceAccount") - if _, err := controllerutil.CreateOrUpdate(ctx, hostClient, sa, func() error { + if _, err := controllerutil.CreateOrUpdate(ctx, a.hostUncachedClient, sa, func() error { return nil }); err != nil { return nil, fmt.Errorf("unable to create service account %q for deployer on host cluster: %w", sa.Name, err) } cr := DeployerClusterRole(a.config.Name) logger.Info("Creating/Updating resource", lc.KeyResource, kutil.ObjectKeyFromObject(cr).String(), lc.KeyResourceKind, "ClusterRole") - if _, err := controllerutil.CreateOrUpdate(ctx, hostClient, cr, func() error { + if _, err := controllerutil.CreateOrUpdate(ctx, a.hostUncachedClient, cr, func() error { return nil }); err != nil { return nil, fmt.Errorf("unable to create cluster role %q for deployer on host cluster: %w", cr.Name, err) } crb := DeployerClusterRoleBinding(sa, a.config.Name) logger.Info("Creating/Updating resource", lc.KeyResource, kutil.ObjectKeyFromObject(crb).String(), lc.KeyResourceKind, "ClusterRoleBinding") - if _, err := controllerutil.CreateOrUpdate(ctx, hostClient, crb, func() error { + if _, err := controllerutil.CreateOrUpdate(ctx, a.hostUncachedClient, crb, func() error { crb.Subjects = DeployerClusterRoleBindingSubjects(sa) return nil }); err != nil { @@ -178,7 +181,7 @@ func (a *Agent) EnsureHostResources(ctx context.Context, hostClient, lsClient cl } hostRestConfig := rest.CopyConfig(a.hostRestConfig) - if err := kutil.AddServiceAccountToken(ctx, hostClient, sa, hostRestConfig); err != nil { + if err := kutil.AddServiceAccountToken(ctx, a.hostUncachedClient, sa, hostRestConfig); err != nil { logger.Error(err, "unable to add a service account token", "service-account", sa.Name) return nil, err } @@ -192,7 +195,7 @@ func (a *Agent) EnsureHostResources(ctx context.Context, hostClient, lsClient cl secret.Name = a.TargetSecretName() secret.Namespace = a.config.LandscaperNamespace - if _, err := controllerutil.CreateOrUpdate(ctx, lsClient, secret, func() error { + if _, err := controllerutil.CreateOrUpdate(ctx, a.lsUncachedClient, secret, func() error { secret.Data = map[string][]byte{ targettypes.DefaultKubeconfigKey: kubeconfigBytes, } @@ -205,7 +208,7 @@ func (a *Agent) EnsureHostResources(ctx context.Context, hostClient, lsClient cl } // RemoveHostResources removes all resources created by the agent from the host. -func (a *Agent) RemoveHostResources(ctx context.Context, kubeClient client.Client) error { +func (a *Agent) RemoveHostResources(ctx context.Context) error { logger, ctx := logging.FromContextOrNew(ctx, nil, lc.KeyMethod, "RemoveHostResources") sa := &corev1.ServiceAccount{} sa.Name = fmt.Sprintf("deployer-%s", a.config.Name) @@ -216,7 +219,7 @@ func (a *Agent) RemoveHostResources(ctx context.Context, kubeClient client.Clien resources := []client.Object{sa, cr, crb} for _, obj := range resources { - if err := kubeClient.Delete(ctx, obj); err != nil { + if err := a.hostUncachedClient.Delete(ctx, obj); err != nil { if apierrors.IsNotFound(err) { continue } @@ -236,7 +239,7 @@ func (a *Agent) RemoveHostResources(ctx context.Context, kubeClient client.Clien err := wait.PollUntilContextTimeout(ctx, 10*time.Second, 5*time.Minute, true, func(ctx context.Context) (done bool, err error) { for _, obj := range resources { - if err := read_write_layer.GetObject(ctx, kubeClient, kutil.ObjectKeyFromObject(obj), obj, read_write_layer.R000039); err != nil { + if err := read_write_layer.GetObject(ctx, a.hostUncachedClient, kutil.ObjectKeyFromObject(obj), obj, read_write_layer.R000039); err != nil { if apierrors.IsNotFound(err) { continue } @@ -256,7 +259,7 @@ func (a *Agent) Reconcile(ctx context.Context, req reconcile.Request) (reconcile return reconcile.Result{}, nil } logger.Info("Ensuring Landscaper resources") - env, err := a.EnsureLandscaperResources(ctx, a.lsClient, a.hostClient) + env, err := a.EnsureLandscaperResources(ctx) if err != nil { return reconcile.Result{}, err } @@ -266,7 +269,7 @@ func (a *Agent) Reconcile(ctx context.Context, req reconcile.Request) (reconcile return reconcile.Result{}, nil } logger.Info("Ensuring host resources") - if _, err := a.EnsureHostResources(ctx, a.hostClient, a.lsClient); err != nil { + if _, err := a.EnsureHostResources(ctx); err != nil { return reconcile.Result{}, err } return reconcile.Result{}, nil diff --git a/pkg/agent/agent_test.go b/pkg/agent/agent_test.go index 1faadb483..61b78e8fc 100644 --- a/pkg/agent/agent_test.go +++ b/pkg/agent/agent_test.go @@ -42,10 +42,9 @@ var _ = Describe("Agent", func() { agConfig.Namespace = state.Namespace agConfig.LandscaperNamespace = state.Namespace - ag = agent.New(testenv.Client, + ag = agent.New(testenv.Client, testenv.Client, testenv.Client, testenv.Client, testenv.Env.Config, api.LandscaperScheme, - testenv.Client, testenv.Env.Config, api.LandscaperScheme, *agConfig, @@ -62,7 +61,7 @@ var _ = Describe("Agent", func() { Context("Init", func() { It("should ensure all landscaper resources", func() { - _, err := ag.EnsureLandscaperResources(ctx, testenv.Client, testenv.Client) + _, err := ag.EnsureLandscaperResources(ctx) Expect(err).To(Succeed()) env := &lsv1alpha1.Environment{} @@ -75,7 +74,7 @@ var _ = Describe("Agent", func() { Namespace: state.Namespace, Token: "test-token", }) - _, err := ag.EnsureHostResources(ctx, testenv.Client, testenv.Client) + _, err := ag.EnsureHostResources(ctx) testutils.ExpectNoError(err) Expect(testenv.Client.Get(ctx, kutil.ObjectKey(agent.DeployerClusterRoleName, ""), &rbacv1.ClusterRole{})).To(Succeed()) diff --git a/pkg/deployer/container/add.go b/pkg/deployer/container/add.go index 98f7cb966..88a5cb58d 100644 --- a/pkg/deployer/container/add.go +++ b/pkg/deployer/container/add.go @@ -19,7 +19,9 @@ import ( ) // AddControllerToManager adds all necessary deployer controllers to a controller manager. -func AddControllerToManager(logger logging.Logger, hostMgr, lsMgr manager.Manager, config containerv1alpha1.Configuration, +func AddControllerToManager(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + finishedObjectCache *utils.FinishedObjectCache, + logger logging.Logger, hostMgr, lsMgr manager.Manager, config containerv1alpha1.Configuration, callerName string) (*GarbageCollector, error) { log := logger.WithName("container") @@ -29,17 +31,9 @@ func AddControllerToManager(logger logging.Logger, hostMgr, lsMgr manager.Manage "numberOfWorkerThreads", config.Controller.Workers, "lockingEnabled", lockingEnabled) - directHostClient, err := client.New(hostMgr.GetConfig(), client.Options{ - Scheme: hostMgr.GetScheme(), - }) - if err != nil { - return nil, fmt.Errorf("unable to create direct client for the host cluster: %w", err) - } containerDeployer, err := NewDeployer( + lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, log, - lsMgr.GetClient(), - hostMgr.GetClient(), - directHostClient, config) if err != nil { return nil, err @@ -52,15 +46,17 @@ func AddControllerToManager(logger logging.Logger, hostMgr, lsMgr manager.Manage options.CacheSyncTimeout = config.Controller.CacheSyncTimeout.Duration } - err = deployerlib.Add(log, lsMgr, hostMgr, deployerlib.DeployerArgs{ - Name: Name, - Version: version.Get().String(), - Identity: config.Identity, - Type: Type, - Deployer: containerDeployer, - TargetSelectors: config.TargetSelector, - Options: options, - }, config.Controller.Workers, lockingEnabled, callerName) + err = deployerlib.Add(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, + finishedObjectCache, + log, lsMgr, hostMgr, deployerlib.DeployerArgs{ + Name: Name, + Version: version.Get().String(), + Identity: config.Identity, + Type: Type, + Deployer: containerDeployer, + TargetSelectors: config.TargetSelector, + Options: options, + }, config.Controller.Workers, lockingEnabled, callerName) if err != nil { return nil, err } @@ -71,9 +67,9 @@ func AddControllerToManager(logger logging.Logger, hostMgr, lsMgr manager.Manage } keepPods := config.DebugOptions != nil && config.DebugOptions.KeepPod - gc := NewGarbageCollector(log.WithName("garbageCollector"), - lsMgr.GetClient(), - hostMgr.GetClient(), + gc := NewGarbageCollector( + lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, + log.WithName("garbageCollector"), config.Identity, config.Namespace, config.GarbageCollection, diff --git a/pkg/deployer/container/container.go b/pkg/deployer/container/container.go index e420c0012..22a2601d1 100644 --- a/pkg/deployer/container/container.go +++ b/pkg/deployer/container/container.go @@ -41,15 +41,12 @@ func NewDeployItemBuilder() *utils.DeployItemBuilder { // Container is the internal representation of a DeployItem of Type Container type Container struct { - lsClient client.Client - // hostClient is a cached client that is used to interact with the host cluster - // The host cluster is the cluster where the pods are executed. - // This client is only used for the pod resource. - hostClient client.Client - // directHostClient is non-cached client that directly interact with the apiserver. - // it is mainly used for secret and rbac resources - directHostClient client.Client - Configuration containerv1alpha1.Configuration + lsUncachedClient client.Client + lsCachedClient client.Client + hostUncachedClient client.Client + hostCachedClient client.Client + + Configuration containerv1alpha1.Configuration DeployItem *lsv1alpha1.DeployItem Context *lsv1alpha1.Context @@ -64,9 +61,7 @@ type Container struct { } // New creates a new internal container item -func New(lsClient, - hostClient, - directHostClient client.Client, +func New(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, config containerv1alpha1.Configuration, item *lsv1alpha1.DeployItem, lsCtx *lsv1alpha1.Context, @@ -96,9 +91,10 @@ func New(lsClient, } return &Container{ - lsClient: lsClient, - hostClient: hostClient, - directHostClient: directHostClient, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + hostUncachedClient: hostUncachedClient, + hostCachedClient: hostCachedClient, Configuration: config, DeployItem: item, Context: lsCtx, diff --git a/pkg/deployer/container/container_delete.go b/pkg/deployer/container/container_delete.go index ce3b244a2..c7a66eb9c 100644 --- a/pkg/deployer/container/container_delete.go +++ b/pkg/deployer/container/container_delete.go @@ -27,11 +27,11 @@ func (c *Container) Delete(ctx context.Context) error { } } - if err := CleanupRBAC(ctx, c.DeployItem, c.hostClient, c.Configuration.Namespace); err != nil { + if err := CleanupRBAC(ctx, c.DeployItem, c.hostUncachedClient, c.Configuration.Namespace); err != nil { return lserrors.NewWrappedError(err, "Delete", "CleanupRBAC", err.Error()) } - if err := CleanupDeployItem(ctx, c.DeployItem, c.lsClient, c.directHostClient, c.Configuration.Namespace); err != nil { + if err := CleanupDeployItem(ctx, c.DeployItem, c.lsUncachedClient, c.hostUncachedClient, c.Configuration.Namespace); err != nil { return lserrors.NewWrappedError(err, "Delete", "CleanupDeployItem", err.Error()) } diff --git a/pkg/deployer/container/container_reconcile.go b/pkg/deployer/container/container_reconcile.go index 5ae4ceb21..fbe364efd 100644 --- a/pkg/deployer/container/container_reconcile.go +++ b/pkg/deployer/container/container_reconcile.go @@ -57,7 +57,7 @@ func (c *Container) Reconcile(ctx context.Context, operation container.Operation "Reconcile", "FetchRunningPod", err.Error()) } - lsWriter := read_write_layer.NewWriter(c.lsClient) + lsWriter := read_write_layer.NewWriter(c.lsUncachedClient) // do nothing if the pod is still running if pod != nil { @@ -89,7 +89,7 @@ func (c *Container) Reconcile(ctx context.Context, operation container.Operation // before we start syncing lets read the current deploy item from the server oldDeployItem := &lsv1alpha1.DeployItem{} - if err := read_write_layer.GetDeployItem(ctx, c.lsClient, kutil.ObjectKey(c.DeployItem.GetName(), + if err := read_write_layer.GetDeployItem(ctx, c.lsUncachedClient, kutil.ObjectKey(c.DeployItem.GetName(), c.DeployItem.GetNamespace()), oldDeployItem, read_write_layer.R000027); err != nil { return lserrors.NewWrappedError(err, operationName, "FetchDeployItem", err.Error()) @@ -112,7 +112,7 @@ func (c *Container) Reconcile(ctx context.Context, operation container.Operation operationName, "ParseAndSyncSecrets", err.Error()) } // ensure new pod - serviceAccountSecrets, err := EnsureServiceAccounts(ctx, c.directHostClient, c.DeployItem, c.Configuration.Namespace, defaultLabels) + serviceAccountSecrets, err := EnsureServiceAccounts(ctx, c.hostUncachedClient, c.DeployItem, c.Configuration.Namespace, defaultLabels) if err != nil { return lserrors.NewWrappedError(err, operationName, "EnsurePodRBAC", err.Error()) @@ -152,7 +152,7 @@ func (c *Container) Reconcile(ctx context.Context, operation container.Operation operationName, "PodGeneration", err.Error()) } - if err := c.hostClient.Create(ctx, pod); err != nil { + if err := c.hostUncachedClient.Create(ctx, pod); err != nil { return lserrors.NewWrappedError(err, operationName, "CreatePod", err.Error()) } @@ -477,7 +477,7 @@ func (c *Container) syncSecrets(ctx context.Context, authSecret.Name = secretName authSecret.Namespace = c.Configuration.Namespace authSecret.Type = corev1.SecretTypeDockerConfigJson - if _, err := controllerutil.CreateOrUpdate(ctx, c.directHostClient, authSecret, func() error { + if _, err := controllerutil.CreateOrUpdate(ctx, c.hostUncachedClient, authSecret, func() error { InjectDefaultLabels(authSecret, defaultLabels) kutil.SetMetaDataLabel(&authSecret.ObjectMeta, container.ContainerDeployerTypeLabel, "registry-pull-secret") authSecret.Data = map[string][]byte{ @@ -522,7 +522,7 @@ func (c *Container) parseAndSyncSecrets(ctx context.Context, defaultLabels map[s for _, secretRef := range secretRefs { secret := &corev1.Secret{} - err := c.lsClient.Get(ctx, secretRef.NamespacedName(), secret) + err := c.lsUncachedClient.Get(ctx, secretRef.NamespacedName(), secret) if err != nil { log.Debug("Unable to get auth config from secret, skipping", lc.KeyResource, secretRef.NamespacedName().String(), lc.KeyError, err.Error()) } @@ -626,7 +626,7 @@ func (c *Container) SyncConfiguration(ctx context.Context, defaultLabels map[str secret := &corev1.Secret{} secret.Name = ConfigurationSecretName(c.DeployItem.Namespace, c.DeployItem.Name) secret.Namespace = c.Configuration.Namespace - if _, err := controllerutil.CreateOrUpdate(ctx, c.directHostClient, secret, func() error { + if _, err := controllerutil.CreateOrUpdate(ctx, c.hostUncachedClient, secret, func() error { InjectDefaultLabels(secret, defaultLabels) kutil.SetMetaDataLabel(&secret.ObjectMeta, container.ContainerDeployerTypeLabel, "configuration") secret.Data = map[string][]byte{ @@ -644,7 +644,7 @@ func (c *Container) SyncTarget(ctx context.Context, defaultLabels map[string]str secret := &corev1.Secret{} secret.Name = TargetSecretName(c.DeployItem.Namespace, c.DeployItem.Name) secret.Namespace = c.Configuration.Namespace - if _, err := controllerutil.CreateOrUpdate(ctx, c.directHostClient, secret, func() error { + if _, err := controllerutil.CreateOrUpdate(ctx, c.hostUncachedClient, secret, func() error { InjectDefaultLabels(secret, defaultLabels) kutil.SetMetaDataLabel(&secret.ObjectMeta, container.ContainerDeployerTypeLabel, "target") data, err := json.Marshal(c.Target) @@ -667,7 +667,7 @@ func (c *Container) SyncExport(ctx context.Context) error { log.Debug("Sync export to landscaper cluster") secret := &corev1.Secret{} key := kutil.ObjectKey(ExportSecretName(c.DeployItem.Namespace, c.DeployItem.Name), c.Configuration.Namespace) - if err := c.directHostClient.Get(ctx, key, secret); err != nil { + if err := c.hostUncachedClient.Get(ctx, key, secret); err != nil { if apierrors.IsNotFound(err) { log.Info("No export found for deploy item", "deployitem", key.String()) return nil @@ -678,7 +678,7 @@ func (c *Container) SyncExport(ctx context.Context) error { expSecret := &corev1.Secret{} expSecret.Name = DeployItemExportSecretName(c.DeployItem.Name) expSecret.Namespace = c.DeployItem.Namespace - if _, err := controllerutil.CreateOrUpdate(ctx, c.lsClient, expSecret, func() error { + if _, err := controllerutil.CreateOrUpdate(ctx, c.lsUncachedClient, expSecret, func() error { expSecret.Data = secret.Data return controllerutil.SetControllerReference(c.DeployItem, expSecret, api.LandscaperScheme) }); err != nil { @@ -695,5 +695,5 @@ func (c *Container) SyncExport(ctx context.Context) error { // CleanupPod cleans up a pod that was started with the container deployer. func (c *Container) CleanupPod(ctx context.Context, pod *corev1.Pod) error { - return CleanupPod(ctx, c.hostClient, pod, c.Configuration.DebugOptions != nil && c.Configuration.DebugOptions.KeepPod) + return CleanupPod(ctx, c.hostUncachedClient, pod, c.Configuration.DebugOptions != nil && c.Configuration.DebugOptions.KeepPod) } diff --git a/pkg/deployer/container/container_suite_test.go b/pkg/deployer/container/container_suite_test.go index 25044875d..a8c436da2 100644 --- a/pkg/deployer/container/container_suite_test.go +++ b/pkg/deployer/container/container_suite_test.go @@ -78,7 +78,8 @@ var _ = Describe("Template", func() { }) Expect(err).ToNot(HaveOccurred()) - _, err = containerctlr.AddControllerToManager(logging.Discard(), mgr, mgr, + _, err = containerctlr.AddControllerToManager(mgr.GetClient(), mgr.GetClient(), mgr.GetClient(), mgr.GetClient(), + lsutils.NewFinishedObjectCache(), logging.Discard(), mgr, mgr, containerv1alpha1.Configuration{}, "template-"+utils.GetNextCounter()) Expect(err).To(BeNil()) diff --git a/pkg/deployer/container/garbage_collector.go b/pkg/deployer/container/garbage_collector.go index caf6951ec..3ecb42445 100644 --- a/pkg/deployer/container/garbage_collector.go +++ b/pkg/deployer/container/garbage_collector.go @@ -31,33 +31,37 @@ import ( ) type GarbageCollector struct { - log logging.Logger - deployerID string - hostNamespace string - config containerv1alpha1.GarbageCollection - lsClient client.Client - hostClient client.Client - requeueAfter time.Duration - keepPods bool + lsUncachedClient client.Client + lsCachedClient client.Client + hostUncachedClient client.Client + hostCachedClient client.Client + log logging.Logger + deployerID string + hostNamespace string + config containerv1alpha1.GarbageCollection + requeueAfter time.Duration + keepPods bool } // NewGarbageCollector creates a new Garbage collector that cleanups leaked service accounts, rbac rules and pods. -func NewGarbageCollector(log logging.Logger, - lsClient, - hostClient client.Client, +func NewGarbageCollector( + lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + log logging.Logger, deployerID, hostNamespace string, config containerv1alpha1.GarbageCollection, keepPods bool) *GarbageCollector { return &GarbageCollector{ - log: log, - deployerID: deployerID, - hostNamespace: hostNamespace, - config: config, - lsClient: lsClient, - hostClient: hostClient, - requeueAfter: time.Duration(config.RequeueTimeSeconds) * time.Second, - keepPods: keepPods, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + hostUncachedClient: hostUncachedClient, + hostCachedClient: hostCachedClient, + log: log, + deployerID: deployerID, + hostNamespace: hostNamespace, + config: config, + requeueAfter: time.Duration(config.RequeueTimeSeconds) * time.Second, + keepPods: keepPods, } } @@ -82,7 +86,7 @@ func (gc *GarbageCollector) Cleanup(ctx context.Context) { // cleanup service accounts saList := &corev1.ServiceAccountList{} - if err := gc.hostClient.List(ctx, saList, listOptions...); err != nil { + if err := gc.hostUncachedClient.List(ctx, saList, listOptions...); err != nil { logger.Error(err, err.Error()) } @@ -95,7 +99,7 @@ func (gc *GarbageCollector) Cleanup(ctx context.Context) { // cleanup roles roleList := &rbacv1.RoleList{} - if err := gc.hostClient.List(ctx, roleList, listOptions...); err != nil { + if err := gc.hostUncachedClient.List(ctx, roleList, listOptions...); err != nil { logger.Error(err, err.Error()) } @@ -108,7 +112,7 @@ func (gc *GarbageCollector) Cleanup(ctx context.Context) { // cleanup rolesbidings roleBindingList := &rbacv1.RoleBindingList{} - if err := gc.hostClient.List(ctx, roleBindingList, listOptions...); err != nil { + if err := gc.hostUncachedClient.List(ctx, roleBindingList, listOptions...); err != nil { logger.Error(err, err.Error()) } @@ -121,7 +125,7 @@ func (gc *GarbageCollector) Cleanup(ctx context.Context) { // cleanup secrets secretList := &corev1.SecretList{} - if err := read_write_layer.ListSecrets(ctx, gc.hostClient, secretList, read_write_layer.R000074, listOptions...); err != nil { + if err := read_write_layer.ListSecrets(ctx, gc.hostUncachedClient, secretList, read_write_layer.R000074, listOptions...); err != nil { logger.Error(err, err.Error()) } @@ -135,7 +139,7 @@ func (gc *GarbageCollector) Cleanup(ctx context.Context) { if !gc.keepPods { // cleanup pods podList := &corev1.PodList{} - if err := read_write_layer.ListPods(ctx, gc.hostClient, podList, read_write_layer.R000075, listOptions...); err != nil { + if err := read_write_layer.ListPods(ctx, gc.hostUncachedClient, podList, read_write_layer.R000075, listOptions...); err != nil { logger.Error(err, err.Error()) } @@ -160,7 +164,7 @@ func (gc *GarbageCollector) cleanupRBACResources(ctx context.Context, obj client di := &lsv1alpha1.DeployItem{} di.Name = obj.GetLabels()[container.ContainerDeployerDeployItemNameLabel] di.Namespace = obj.GetLabels()[container.ContainerDeployerDeployItemNamespaceLabel] - if err := CleanupRBAC(ctx, di, gc.hostClient, obj.GetNamespace()); err != nil { + if err := CleanupRBAC(ctx, di, gc.hostUncachedClient, obj.GetNamespace()); err != nil { return err } return nil @@ -176,7 +180,7 @@ func (gc *GarbageCollector) cleanupSecret(ctx context.Context, obj *corev1.Secre return nil } - if err := gc.hostClient.Delete(ctx, obj); err != nil { + if err := gc.hostUncachedClient.Delete(ctx, obj); err != nil { return err } return nil @@ -197,7 +201,7 @@ func (gc *GarbageCollector) cleanupPod(ctx context.Context, obj *corev1.Pod) err if shouldGC { // always garbage collect pods that do not have a corresponding deployitem anymore logger.Debug("Garbage collected", lc.KeyReason, "deploy item does not exist anymore") - if err := CleanupPod(ctx, gc.hostClient, obj, false); err != nil { + if err := CleanupPod(ctx, gc.hostUncachedClient, obj, false); err != nil { return fmt.Errorf("unable to garbage collect pod %s: %w", kutil.ObjectKeyFromObject(obj).String(), err) } return nil @@ -205,7 +209,7 @@ func (gc *GarbageCollector) cleanupPod(ctx context.Context, obj *corev1.Pod) err if !controllerutil.ContainsFinalizer(obj, container.ContainerDeployerFinalizer) { logger.Debug("Garbage collected", lc.KeyReason, "pod has no finalizer") - err := gc.hostClient.Delete(ctx, obj) + err := gc.hostUncachedClient.Delete(ctx, obj) return err } @@ -218,7 +222,7 @@ func (gc *GarbageCollector) cleanupPod(ctx context.Context, obj *corev1.Pod) err return nil } - if err := CleanupPod(ctx, gc.hostClient, obj, false); err != nil { + if err := CleanupPod(ctx, gc.hostUncachedClient, obj, false); err != nil { return fmt.Errorf("unable to garbage collect pod %s: %w", kutil.ObjectKeyFromObject(obj).String(), err) } logger.Debug("Garbage collected") @@ -233,7 +237,7 @@ func (gc *GarbageCollector) isLatestPod(ctx context.Context, pod *corev1.Pod) (b ) podList := &corev1.PodList{} - if err := read_write_layer.ListPods(ctx, gc.hostClient, podList, read_write_layer.R000076, + if err := read_write_layer.ListPods(ctx, gc.hostUncachedClient, podList, read_write_layer.R000076, client.InNamespace(gc.hostNamespace), client.MatchingLabels{ container.ContainerDeployerDeployItemNameLabel: diName, @@ -282,7 +286,7 @@ func (gc *GarbageCollector) shouldGarbageCollect(ctx context.Context, obj client Name: obj.GetLabels()[container.ContainerDeployerDeployItemNameLabel], } logger := gc.log.WithValues("deployItem", key.String(), lc.KeyResource, kutil.ObjectKeyFromObject(obj).String()) - if err := read_write_layer.GetDeployItem(ctx, gc.lsClient, key, di, read_write_layer.R000036); err != nil { + if err := read_write_layer.GetDeployItem(ctx, gc.lsUncachedClient, key, di, read_write_layer.R000036); err != nil { if apierrors.IsNotFound(err) { return true, nil } diff --git a/pkg/deployer/container/garbage_collector_test.go b/pkg/deployer/container/garbage_collector_test.go index d48e23f3b..91f8465db 100644 --- a/pkg/deployer/container/garbage_collector_test.go +++ b/pkg/deployer/container/garbage_collector_test.go @@ -76,10 +76,11 @@ var _ = Describe("GarbageCollector", func() { Expect(testutils.CreateExampleDefaultContext(ctx, testenv.Client, lsState.Namespace)).To(Succeed()) - gc = containerctlr.NewGarbageCollector(logger, testenv.Client, hostTestEnv.Client, "test", hostState.Namespace, containerv1alpha1.GarbageCollection{ - Worker: 1, - RequeueTimeSeconds: 1, - }, false) + gc = containerctlr.NewGarbageCollector(testenv.Client, testenv.Client, hostTestEnv.Client, hostTestEnv.Client, + logger, "test", hostState.Namespace, containerv1alpha1.GarbageCollection{ + Worker: 1, + RequeueTimeSeconds: 1, + }, false) Expect(testutils.AddMimicKCMSecretControllerToManager(hostMgr)).To(Succeed()) diff --git a/pkg/deployer/container/pod.go b/pkg/deployer/container/pod.go index cde1fae75..e6752e550 100644 --- a/pkg/deployer/container/pod.go +++ b/pkg/deployer/container/pod.go @@ -366,7 +366,7 @@ func generatePod(opts PodOptions) (*corev1.Pod, error) { // Pods that have no finalizer are ignored. func (c *Container) getPod(ctx context.Context) (*corev1.Pod, error) { podList := &corev1.PodList{} - if err := read_write_layer.ListPods(ctx, c.hostClient, podList, read_write_layer.R000077, + if err := read_write_layer.ListPods(ctx, c.hostUncachedClient, podList, read_write_layer.R000077, client.InNamespace(c.Configuration.Namespace), client.MatchingLabels{ container.ContainerDeployerDeployItemNameLabel: c.DeployItem.Name, container.ContainerDeployerDeployItemNamespaceLabel: c.DeployItem.Namespace, diff --git a/pkg/deployer/container/reconciler_deployitem.go b/pkg/deployer/container/reconciler_deployitem.go index 0afe44827..429e70704 100644 --- a/pkg/deployer/container/reconciler_deployitem.go +++ b/pkg/deployer/container/reconciler_deployitem.go @@ -32,10 +32,8 @@ const ( ) // NewDeployer creates a new deployer that reconciles deploy items of type "landscaper.gardener.cloud/container". -func NewDeployer(log logging.Logger, - lsKubeClient client.Client, - hostKubeClient client.Client, - directHostClient client.Client, +func NewDeployer(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + log logging.Logger, config containerv1alpha1.Configuration) (*deployer, error) { var sharedCache cache.Cache @@ -50,30 +48,33 @@ func NewDeployer(log logging.Logger, registries.SetOCMLibraryMode(config.UseOCMLib) dep := &deployer{ - log: log, - lsClient: lsKubeClient, - hostClient: hostKubeClient, - directHostClient: directHostClient, - config: config, - sharedCache: sharedCache, - hooks: extension.ReconcileExtensionHooks{}, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + hostUncachedClient: hostUncachedClient, + hostCachedClient: hostCachedClient, + log: log, + config: config, + sharedCache: sharedCache, + hooks: extension.ReconcileExtensionHooks{}, } dep.hooks.RegisterHookSetup(cr.ContinuousReconcileExtensionSetup(dep.NextReconcile)) return dep, nil } type deployer struct { - log logging.Logger - lsClient client.Client - hostClient client.Client - directHostClient client.Client - config containerv1alpha1.Configuration - sharedCache cache.Cache - hooks extension.ReconcileExtensionHooks + lsUncachedClient client.Client + lsCachedClient client.Client + hostUncachedClient client.Client + hostCachedClient client.Client + + log logging.Logger + config containerv1alpha1.Configuration + sharedCache cache.Cache + hooks extension.ReconcileExtensionHooks } func (d *deployer) Reconcile(ctx context.Context, lsCtx *lsv1alpha1.Context, di *lsv1alpha1.DeployItem, rt *lsv1alpha1.ResolvedTarget) error { - containerOp, err := New(d.lsClient, d.hostClient, d.directHostClient, d.config, di, lsCtx, d.sharedCache, rt) + containerOp, err := New(d.lsUncachedClient, d.lsCachedClient, d.hostUncachedClient, d.hostCachedClient, d.config, di, lsCtx, d.sharedCache, rt) if err != nil { return err } @@ -82,7 +83,7 @@ func (d *deployer) Reconcile(ctx context.Context, lsCtx *lsv1alpha1.Context, di } func (d deployer) Delete(ctx context.Context, lsCtx *lsv1alpha1.Context, di *lsv1alpha1.DeployItem, rt *lsv1alpha1.ResolvedTarget) error { - containerOp, err := New(d.lsClient, d.hostClient, d.directHostClient, d.config, di, lsCtx, d.sharedCache, rt) + containerOp, err := New(d.lsUncachedClient, d.lsCachedClient, d.hostUncachedClient, d.hostCachedClient, d.config, di, lsCtx, d.sharedCache, rt) if err != nil { return err } @@ -101,7 +102,7 @@ func (d *deployer) ExtensionHooks() extension.ReconcileExtensionHooks { func (d *deployer) NextReconcile(ctx context.Context, last time.Time, di *lsv1alpha1.DeployItem) (*time.Time, error) { // TODO: parse provider configuration directly and do not init the container helper struct - containerOp, err := New(d.lsClient, d.hostClient, d.directHostClient, d.config, di, nil, d.sharedCache, nil) + containerOp, err := New(d.lsUncachedClient, d.lsCachedClient, d.hostUncachedClient, d.hostCachedClient, d.config, di, nil, d.sharedCache, nil) if err != nil { return nil, err } diff --git a/pkg/deployer/helm/add.go b/pkg/deployer/helm/add.go index 01afe9877..00ee1ed84 100644 --- a/pkg/deployer/helm/add.go +++ b/pkg/deployer/helm/add.go @@ -7,6 +7,8 @@ package helm import ( "fmt" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/manager" @@ -18,7 +20,9 @@ import ( ) // AddDeployerToManager adds a new helm deployers to a controller manager. -func AddDeployerToManager(logger logging.Logger, lsMgr, hostMgr manager.Manager, +func AddDeployerToManager(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + finishedObjectCache *utils.FinishedObjectCache, + logger logging.Logger, lsMgr, hostMgr manager.Manager, config helmv1alpha1.Configuration, callerName string) error { log := logger.WithName("helm") @@ -28,10 +32,8 @@ func AddDeployerToManager(logger logging.Logger, lsMgr, hostMgr manager.Manager, "numberOfWorkerThreads", config.Controller.Workers, "lockingEnabled", lockingEnabled) - d, err := NewDeployer( + d, err := NewDeployer(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, log, - lsMgr.GetClient(), - hostMgr.GetClient(), config, ) if err != nil { @@ -45,13 +47,15 @@ func AddDeployerToManager(logger logging.Logger, lsMgr, hostMgr manager.Manager, options.CacheSyncTimeout = config.Controller.CacheSyncTimeout.Duration } - return deployerlib.Add(log, lsMgr, hostMgr, deployerlib.DeployerArgs{ - Name: Name, - Version: version.Get().String(), - Identity: config.Identity, - Type: Type, - Deployer: d, - TargetSelectors: config.TargetSelector, - Options: options, - }, config.Controller.Workers, lockingEnabled, callerName) + return deployerlib.Add(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, + finishedObjectCache, + log, lsMgr, hostMgr, deployerlib.DeployerArgs{ + Name: Name, + Version: version.Get().String(), + Identity: config.Identity, + Type: Type, + Deployer: d, + TargetSelectors: config.TargetSelector, + Options: options, + }, config.Controller.Workers, lockingEnabled, callerName) } diff --git a/pkg/deployer/helm/deletionmanager_test.go b/pkg/deployer/helm/deletionmanager_test.go index cb2ac30e6..a924f0991 100644 --- a/pkg/deployer/helm/deletionmanager_test.go +++ b/pkg/deployer/helm/deletionmanager_test.go @@ -6,6 +6,8 @@ import ( "encoding/json" "time" + "github.com/gardener/landscaper/pkg/utils" + "github.com/google/uuid" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -64,14 +66,14 @@ var _ = Describe("Deletion Manager", func() { Expect(err).ToNot(HaveOccurred()) resources = &resourceBuilder{state.Namespace} - deployer, err := helm.NewDeployer(logging.Discard(), testenv.Client, testenv.Client, helmv1alpha1.Configuration{}) + deployer, err := helm.NewDeployer(testenv.Client, testenv.Client, testenv.Client, testenv.Client, logging.Discard(), helmv1alpha1.Configuration{}) Expect(err).ToNot(HaveOccurred()) ctrl = deployerlib.NewController( - testenv.Client, + testenv.Client, testenv.Client, testenv.Client, testenv.Client, + utils.NewFinishedObjectCache(), api.LandscaperScheme, record.NewFakeRecorder(1024), - testenv.Client, api.LandscaperScheme, deployerlib.DeployerArgs{Type: helm.Type, Deployer: deployer}, 5, false, "deletiongroup-test"+testutils.GetNextCounter()) diff --git a/pkg/deployer/helm/deployer.go b/pkg/deployer/helm/deployer.go index 4480f39e0..df822de52 100644 --- a/pkg/deployer/helm/deployer.go +++ b/pkg/deployer/helm/deployer.go @@ -44,9 +44,8 @@ const ( ) // NewDeployer creates a new deployer that reconciles deploy items of type helm. -func NewDeployer(log logging.Logger, - lsKubeClient client.Client, - hostKubeClient client.Client, +func NewDeployer(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + log logging.Logger, config helmv1alpha1.Configuration) (deployerlib.Deployer, error) { var sharedCache cache.Cache @@ -61,21 +60,26 @@ func NewDeployer(log logging.Logger, registries.SetOCMLibraryMode(config.UseOCMLib) dep := &deployer{ - log: log, - lsClient: lsKubeClient, - hostClient: hostKubeClient, - config: config, - sharedCache: sharedCache, - hooks: extension.ReconcileExtensionHooks{}, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + hostUncachedClient: hostUncachedClient, + hostCachedClient: hostCachedClient, + log: log, + config: config, + sharedCache: sharedCache, + hooks: extension.ReconcileExtensionHooks{}, } dep.hooks.RegisterHookSetup(cr.ContinuousReconcileExtensionSetup(dep.NextReconcile)) return dep, nil } type deployer struct { + lsUncachedClient client.Client + lsCachedClient client.Client + hostUncachedClient client.Client + hostCachedClient client.Client + log logging.Logger - lsClient client.Client - hostClient client.Client config helmv1alpha1.Configuration sharedCache cache.Cache hooks extension.ReconcileExtensionHooks @@ -86,7 +90,7 @@ func (d *deployer) Reconcile(ctx context.Context, lsCtx *lsv1alpha1.Context, di return err } - helm, err := New(d.config, d.lsClient, d.hostClient, di, rt, lsCtx, d.sharedCache) + helm, err := New(d.lsUncachedClient, d.lsCachedClient, d.hostUncachedClient, d.hostCachedClient, d.config, di, rt, lsCtx, d.sharedCache) if err != nil { err = lserrors.NewWrappedError(err, "Reconcile", "newRootLogger", err.Error()) return err @@ -122,7 +126,7 @@ func (d *deployer) Delete(ctx context.Context, lsCtx *lsv1alpha1.Context, di *ls return err } - helm, err := New(d.config, d.lsClient, d.hostClient, di, rt, lsCtx, d.sharedCache) + helm, err := New(d.lsUncachedClient, d.lsCachedClient, d.hostUncachedClient, d.hostCachedClient, d.config, di, rt, lsCtx, d.sharedCache) if err != nil { return err } @@ -145,7 +149,7 @@ func (d *deployer) ExtensionHooks() extension.ReconcileExtensionHooks { func (d *deployer) NextReconcile(ctx context.Context, last time.Time, di *lsv1alpha1.DeployItem) (*time.Time, error) { // todo: directly parse deploy items - helm, err := New(d.config, d.lsClient, d.hostClient, di, nil, nil, d.sharedCache) + helm, err := New(d.lsUncachedClient, d.lsCachedClient, d.hostUncachedClient, d.hostCachedClient, d.config, di, nil, nil, d.sharedCache) if err != nil { return nil, err } diff --git a/pkg/deployer/helm/ensure.go b/pkg/deployer/helm/ensure.go index dc67ee73c..4d0ac9db1 100644 --- a/pkg/deployer/helm/ensure.go +++ b/pkg/deployer/helm/ensure.go @@ -146,7 +146,7 @@ func (h *Helm) applyManifests(ctx context.Context, targetClient client.Client, t helmv1alpha1.ManagedDeployItemLabel: h.DeployItem.Name, }, DeletionGroupsDuringUpdate: h.ProviderConfiguration.DeletionGroupsDuringUpdate, - InterruptionChecker: interruption.NewStandardInterruptionChecker(h.DeployItem, h.lsKubeClient), + InterruptionChecker: interruption.NewStandardInterruptionChecker(h.DeployItem, h.lsUncachedClient), }) err := applier.Apply(ctx) @@ -230,7 +230,7 @@ func (h *Helm) checkResourcesReady(ctx context.Context, client client.Client, fa Timeout: &lsv1alpha1.Duration{Duration: t}, ManagedResources: h.ProviderStatus.ManagedResources.TypedObjectReferenceList(), FailOnMissingObject: failOnMissingObject, - InterruptionChecker: interruption.NewStandardInterruptionChecker(h.DeployItem, h.lsKubeClient), + InterruptionChecker: interruption.NewStandardInterruptionChecker(h.DeployItem, h.lsUncachedClient), } err := defaultReadinessCheck.CheckResourcesReady() if err != nil { @@ -251,7 +251,7 @@ func (h *Helm) checkResourcesReady(ctx context.Context, client client.Client, fa Timeout: &lsv1alpha1.Duration{Duration: t}, ManagedResources: h.ProviderStatus.ManagedResources.TypedObjectReferenceList(), Configuration: customReadinessCheckConfig, - InterruptionChecker: interruption.NewStandardInterruptionChecker(h.DeployItem, h.lsKubeClient), + InterruptionChecker: interruption.NewStandardInterruptionChecker(h.DeployItem, h.lsUncachedClient), } err := customReadinessCheck.CheckResourcesReady() if err != nil { @@ -274,7 +274,7 @@ func (h *Helm) readExportValues(ctx context.Context, currOp string, targetClient if len(exportDefinition.Exports) != 0 { opts := resourcemanager.ExporterOptions{ KubeClient: targetClient, - InterruptionChecker: interruption.NewStandardInterruptionChecker(h.DeployItem, h.lsKubeClient), + InterruptionChecker: interruption.NewStandardInterruptionChecker(h.DeployItem, h.lsUncachedClient), DeployItem: h.DeployItem, } @@ -287,7 +287,7 @@ func (h *Helm) readExportValues(ctx context.Context, currOp string, targetClient exports = utils.MergeMaps(exports, resourceExports) } - if err := deployerlib.CreateOrUpdateExport(ctx, h.Writer(), h.lsKubeClient, h.DeployItem, exports); err != nil { + if err := deployerlib.CreateOrUpdateExport(ctx, h.Writer(), h.lsUncachedClient, h.DeployItem, exports); err != nil { return err } @@ -319,7 +319,7 @@ func (h *Helm) deleteManifestsInGroups(ctx context.Context) error { return err } - interruptionChecker := interruption.NewStandardInterruptionChecker(h.DeployItem, h.lsKubeClient) + interruptionChecker := interruption.NewStandardInterruptionChecker(h.DeployItem, h.lsUncachedClient) err = resourcemanager.DeleteManagedResources( ctx, @@ -395,5 +395,5 @@ func (h *Helm) constructExportsFromValues(values map[string]interface{}) (map[st } func (h *Helm) Writer() *read_write_layer.Writer { - return read_write_layer.NewWriter(h.lsKubeClient) + return read_write_layer.NewWriter(h.lsUncachedClient) } diff --git a/pkg/deployer/helm/helm.go b/pkg/deployer/helm/helm.go index e4fceaff0..609a99322 100644 --- a/pkg/deployer/helm/helm.go +++ b/pkg/deployer/helm/helm.go @@ -52,9 +52,12 @@ func NewDeployItemBuilder() *utils.DeployItemBuilder { // Helm is the internal representation of a DeployItem of Type Helm type Helm struct { - lsKubeClient client.Client - hostKubeClient client.Client - Configuration helmv1alpha1.Configuration + lsUncachedClient client.Client + lsCachedClient client.Client + hostUncachedClient client.Client + hostCachedClient client.Client + + Configuration helmv1alpha1.Configuration DeployItem *lsv1alpha1.DeployItem Target *lsv1alpha1.ResolvedTarget @@ -69,9 +72,8 @@ type Helm struct { } // New creates a new internal helm item -func New(helmconfig helmv1alpha1.Configuration, - lsKubeClient client.Client, - hostKubeClient client.Client, +func New(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + helmconfig helmv1alpha1.Configuration, item *lsv1alpha1.DeployItem, rt *lsv1alpha1.ResolvedTarget, lsCtx *lsv1alpha1.Context, @@ -101,8 +103,10 @@ func New(helmconfig helmv1alpha1.Configuration, } return &Helm{ - lsKubeClient: lsKubeClient, - hostKubeClient: hostKubeClient, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + hostUncachedClient: hostUncachedClient, + hostCachedClient: hostCachedClient, Configuration: helmconfig, DeployItem: item, Target: rt, @@ -128,14 +132,14 @@ func (h *Helm) Template(ctx context.Context) (map[string]string, map[string]stri // resolve all registry pull secrets registryPullSecretRefs := lib.GetRegistryPullSecretsFromContext(h.Context) - registryPullSecrets, err := kutil.ResolveSecrets(ctx, h.lsKubeClient, registryPullSecretRefs) + registryPullSecrets, err := kutil.ResolveSecrets(ctx, h.lsUncachedClient, registryPullSecretRefs) if err != nil { return nil, nil, nil, nil, lserrors.NewWrappedError(err, currOp, "ResolveSecrets", err.Error()) } ch, err := chartresolver.GetChart(ctx, &h.ProviderConfiguration.Chart, - h.lsKubeClient, + h.lsUncachedClient, h.Context, registryPullSecrets, h.Configuration.OCI, @@ -216,7 +220,7 @@ func (h *Helm) TargetClient(ctx context.Context) (*rest.Config, client.Client, k return nil, nil, nil, fmt.Errorf("unable to parse target confíguration: %w", err) } - kubeconfigBytes, err := lib.GetKubeconfigFromTargetConfig(ctx, targetConfig, h.Target.Namespace, h.lsKubeClient) + kubeconfigBytes, err := lib.GetKubeconfigFromTargetConfig(ctx, targetConfig, h.Target.Namespace, h.lsUncachedClient) if err != nil { return nil, nil, nil, err } diff --git a/pkg/deployer/helm/helm_suite_test.go b/pkg/deployer/helm/helm_suite_test.go index 2ed375906..16945b666 100644 --- a/pkg/deployer/helm/helm_suite_test.go +++ b/pkg/deployer/helm/helm_suite_test.go @@ -96,7 +96,7 @@ var _ = Describe("Template", func() { lsCtx := &lsv1alpha1.Context{} lsCtx.Name = lsv1alpha1.DefaultContextName lsCtx.Namespace = item.Namespace - h, err := helm.New(helmv1alpha1.Configuration{}, testenv.Client, testenv.Client, item, nil, lsCtx, nil) + h, err := helm.New(testenv.Client, testenv.Client, testenv.Client, testenv.Client, helmv1alpha1.Configuration{}, item, nil, lsCtx, nil) Expect(err).ToNot(HaveOccurred()) files, crds, _, _, err := h.Template(ctx) Expect(err).ToNot(HaveOccurred()) @@ -130,7 +130,9 @@ var _ = Describe("Template", func() { NewClient: lsutils.NewUncachedClient(lsutils.LsResourceClientBurstDefault, lsutils.LsResourceClientQpsDefault), }) Expect(err).ToNot(HaveOccurred()) - Expect(helm.AddDeployerToManager(logging.Wrap(simplelogger.NewIOLogger(GinkgoWriter)), mgr, mgr, helmv1alpha1.Configuration{}, + Expect(helm.AddDeployerToManager(mgr.GetClient(), mgr.GetClient(), mgr.GetClient(), mgr.GetClient(), + lsutils.NewFinishedObjectCache(), + logging.Wrap(simplelogger.NewIOLogger(GinkgoWriter)), mgr, mgr, helmv1alpha1.Configuration{}, "helmintegration"+utils.GetNextCounter())).To(Succeed()) timeout.ActivateStandardTimeoutChecker() diff --git a/pkg/deployer/helm/test/e2e_test.go b/pkg/deployer/helm/test/e2e_test.go index a6b5ef7ef..17fe746e0 100644 --- a/pkg/deployer/helm/test/e2e_test.go +++ b/pkg/deployer/helm/test/e2e_test.go @@ -8,6 +8,8 @@ import ( "context" "time" + "github.com/gardener/landscaper/pkg/utils" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" appsv1 "k8s.io/api/apps/v1" @@ -50,19 +52,17 @@ var _ = Describe("Helm Deployer", func() { ctx := context.Background() defer ctx.Done() - deployer, err := helmctrl.NewDeployer( + deployer, err := helmctrl.NewDeployer(testenv.Client, testenv.Client, testenv.Client, testenv.Client, logging.Discard(), - testenv.Client, - testenv.Client, helmv1alpha1.Configuration{}, ) Expect(err).ToNot(HaveOccurred()) ctrl := deployerlib.NewController( - testenv.Client, + testenv.Client, testenv.Client, testenv.Client, testenv.Client, + utils.NewFinishedObjectCache(), api.LandscaperScheme, record.NewFakeRecorder(1024), - testenv.Client, api.LandscaperScheme, deployerlib.DeployerArgs{ Type: helmctrl.Type, diff --git a/pkg/deployer/lib/cmd/default.go b/pkg/deployer/lib/cmd/default.go index 340a4cbe0..15f03b099 100644 --- a/pkg/deployer/lib/cmd/default.go +++ b/pkg/deployer/lib/cmd/default.go @@ -11,24 +11,32 @@ import ( "fmt" "os" - "github.com/gardener/landscaper/controller-utils/pkg/logging" - lsutils "github.com/gardener/landscaper/pkg/utils" - flag "github.com/spf13/pflag" "golang.org/x/sync/errgroup" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/tools/clientcmd" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/yaml" - "github.com/gardener/landscaper/pkg/api" - lsinstall "github.com/gardener/landscaper/apis/core/install" + lsv1alpha1 "github.com/gardener/landscaper/apis/core/v1alpha1" + "github.com/gardener/landscaper/controller-utils/pkg/logging" + "github.com/gardener/landscaper/pkg/api" + "github.com/gardener/landscaper/pkg/deployer/lib" + lsutils "github.com/gardener/landscaper/pkg/utils" + "github.com/gardener/landscaper/pkg/utils/read_write_layer" ) // DefaultOptions defines all default deployer options. type DefaultOptions struct { + LsUncachedClient client.Client + LsCachedClient client.Client + HostUncachedClient client.Client + HostCachedClient client.Client + configPath string LsKubeconfig string @@ -37,6 +45,8 @@ type DefaultOptions struct { HostMgr manager.Manager decoder runtime.Decoder + + FinishedObjectCache *lsutils.FinishedObjectCache } // NewDefaultOptions creates new default options for a deployer. @@ -63,6 +73,7 @@ func (o *DefaultOptions) Complete() error { log = log.WithName("deployer") o.Log = log ctrl.SetLogger(log.Logr()) + ctx := logging.NewContext(context.Background(), o.Log) hostAndResourceClusterDifferent := len(o.LsKubeconfig) != 0 @@ -71,16 +82,17 @@ func (o *DefaultOptions) Complete() error { opts := manager.Options{ LeaderElection: false, MetricsBindAddress: "0", // disable the metrics serving by default - NewClient: lsutils.NewUncachedClient(burst, qps), } - restConfig, err := ctrl.GetConfig() + hostRestConfig, err := ctrl.GetConfig() if err != nil { return fmt.Errorf("unable to get host kubeconfig: %w", err) } - o.HostMgr, err = ctrl.NewManager(restConfig, opts) + hostRestConfig = lsutils.RestConfigWithModifiedClientRequestRestrictions(log, hostRestConfig, burst, qps) + + o.HostMgr, err = ctrl.NewManager(hostRestConfig, opts) if err != nil { - return fmt.Errorf("unable to setup manager") + return fmt.Errorf("unable to setup host manager") } o.LsMgr = o.HostMgr @@ -89,26 +101,69 @@ func (o *DefaultOptions) Complete() error { if err != nil { return fmt.Errorf("unable to read landscaper kubeconfig from %s: %w", o.LsKubeconfig, err) } - client, err := clientcmd.NewClientConfigFromBytes(data) - if err != nil { - return fmt.Errorf("unable to build landscaper cluster client from %s: %w", o.LsKubeconfig, err) - } - restConfig, err := client.ClientConfig() + + lsRestConfig, err := clientcmd.RESTConfigFromKubeConfig(data) if err != nil { - return fmt.Errorf("unable to build landscaper cluster rest client from %s: %w", o.LsKubeconfig, err) + return fmt.Errorf("unable to build landscaper cluster rest client: %w", err) } - burst, qps = lsutils.GetResourceClientRequestRestrictions(log) - opts.NewClient = lsutils.NewUncachedClient(burst, qps) + lsRestConfig = lsutils.RestConfigWithModifiedClientRequestRestrictions(log, lsRestConfig, burst, qps) - o.LsMgr, err = ctrl.NewManager(restConfig, opts) + o.LsMgr, err = ctrl.NewManager(lsRestConfig, opts) if err != nil { - return fmt.Errorf("unable to setup manager") + return fmt.Errorf("unable to setup ls manager") } } lsinstall.Install(o.LsMgr.GetScheme()) + o.LsUncachedClient, o.LsCachedClient, o.HostUncachedClient, o.HostCachedClient, err = lsutils.ClientsFromManagers(o.LsMgr, o.HostMgr) + if err != nil { + return err + } + + if err := o.prepareFinishedObjectCache(ctx); err != nil { + return err + } + + return nil +} + +func (o *DefaultOptions) prepareFinishedObjectCache(ctx context.Context) error { + log, ctx := logging.FromContextOrNew(ctx, nil) + + o.FinishedObjectCache = lsutils.NewFinishedObjectCache() + namespaces := &v1.NamespaceList{} + if err := read_write_layer.ListNamespaces(ctx, o.LsUncachedClient, namespaces, read_write_layer.R000093); err != nil { + return err + } + + perfTotal := lsutils.StartPerformanceMeasurement(&log, "prepare finished object for dis") + defer perfTotal.Stop() + + for _, namespace := range namespaces.Items { + perf := lsutils.StartPerformanceMeasurement(&log, "prepare finished object cache for dis: fetch from namespace "+namespace.Name) + + diList := &lsv1alpha1.DeployItemList{} + if err := read_write_layer.ListDeployItems(ctx, o.LsUncachedClient, diList, read_write_layer.R000094, + client.InNamespace(namespace.Name)); err != nil { + return err + } + + perf.Stop() + + perf = lsutils.StartPerformanceMeasurement(&log, "prepare finished object cache for dis: add for namespace "+namespace.Name) + + for diIndex := range diList.Items { + di := &diList.Items[diIndex] + if lib.IsDeployItemFinished(di) { + o.FinishedObjectCache.Add(&di.ObjectMeta) + } + } + + perf.Stop() + } + return nil } diff --git a/pkg/deployer/lib/controller.go b/pkg/deployer/lib/controller.go index 620aab6c5..9bf16a1aa 100644 --- a/pkg/deployer/lib/controller.go +++ b/pkg/deployer/lib/controller.go @@ -87,15 +87,18 @@ func (args DeployerArgs) Validate() error { } // Add adds a deployer to the given managers using the given args. -func Add(log logging.Logger, lsMgr, hostMgr manager.Manager, args DeployerArgs, maxNumberOfWorkers int, lockingEnabled bool, callerName string) error { +func Add(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + finishedObjectCache *lsutil.FinishedObjectCache, + log logging.Logger, lsMgr, hostMgr manager.Manager, args DeployerArgs, maxNumberOfWorkers int, lockingEnabled bool, callerName string) error { + args.Default() if err := args.Validate(); err != nil { return err } - con := NewController(lsMgr.GetClient(), + con := NewController(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, + finishedObjectCache, lsMgr.GetScheme(), lsMgr.GetEventRecorderFor(args.Name), - hostMgr.GetClient(), hostMgr.GetScheme(), args, maxNumberOfWorkers, @@ -113,16 +116,21 @@ func Add(log logging.Logger, lsMgr, hostMgr manager.Manager, args DeployerArgs, // controller reconciles deployitems and delegates the business logic to the configured Deployer. type controller struct { + lsUncachedClient client.Client + lsCachedClient client.Client + hostUncachedClient client.Client + hostCachedClient client.Client + + finishedObjectCache *lsutil.FinishedObjectCache + deployer Deployer info lsv1alpha1.DeployerInformation // deployerType defines the deployer type the deployer is responsible for. deployerType lsv1alpha1.DeployItemType targetSelectors []lsv1alpha1.TargetSelector - lsClient client.Client lsScheme *runtime.Scheme lsEventRecorder record.EventRecorder - hostClient client.Client hostScheme *runtime.Scheme workerCounter *lsutil.WorkerCounter @@ -132,10 +140,10 @@ type controller struct { } // NewController creates a new generic deployitem controller. -func NewController(lsClient client.Client, +func NewController(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + finishedObjectCache *lsutil.FinishedObjectCache, lsScheme *runtime.Scheme, lsEventRecorder record.EventRecorder, - hostClient client.Client, hostScheme *runtime.Scheme, args DeployerArgs, maxNumberOfWorkers int, @@ -145,23 +153,26 @@ func NewController(lsClient client.Client, wc := lsutil.NewWorkerCounter(maxNumberOfWorkers) return &controller{ - deployerType: args.Type, - deployer: args.Deployer, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + hostUncachedClient: hostUncachedClient, + hostCachedClient: hostCachedClient, + finishedObjectCache: finishedObjectCache, + deployerType: args.Type, + deployer: args.Deployer, info: lsv1alpha1.DeployerInformation{ Identity: args.Identity, Name: args.Name, Version: args.Version, }, targetSelectors: args.TargetSelectors, - lsClient: lsClient, lsScheme: lsScheme, lsEventRecorder: lsEventRecorder, - hostClient: hostClient, hostScheme: hostScheme, workerCounter: wc, lockingEnabled: lockingEnabled, callerName: callerName, - locker: *lock.NewLocker(lsClient, hostClient, callerName), + locker: *lock.NewLocker(lsUncachedClient, hostUncachedClient, callerName), } } @@ -171,8 +182,23 @@ func (c *controller) Reconcile(ctx context.Context, req reconcile.Request) (reco c.workerCounter.EnterWithLog(logger, 70, c.callerName) defer c.workerCounter.Exit() + if c.finishedObjectCache.IsContained(req) { + cachedMetadata := lsutil.EmptyDeployItemMetadata() + if err := read_write_layer.GetMetaData(ctx, c.lsCachedClient, req.NamespacedName, cachedMetadata, read_write_layer.R000095); err != nil { + if apierrors.IsNotFound(err) { + logger.Debug(err.Error()) + return reconcile.Result{}, nil + } + return lsutil.LogHelper{}.LogStandardErrorAndGetReconcileResult(ctx, err) + } + + if c.finishedObjectCache.IsFinishedAndRemove(cachedMetadata) { + return reconcile.Result{}, nil + } + } + metadata := lsutil.EmptyDeployItemMetadata() - if err := read_write_layer.GetMetaData(ctx, c.lsClient, req.NamespacedName, metadata, read_write_layer.R000042); err != nil { + if err := read_write_layer.GetMetaData(ctx, c.lsUncachedClient, req.NamespacedName, metadata, read_write_layer.R000042); err != nil { if apierrors.IsNotFound(err) { logger.Debug(err.Error()) return reconcile.Result{}, nil @@ -181,7 +207,7 @@ func (c *controller) Reconcile(ctx context.Context, req reconcile.Request) (reco } // this check is only for compatibility reasons - rt, responsible, targetNotFound, err := CheckResponsibility(ctx, c.lsClient, metadata, c.deployerType, c.targetSelectors) + rt, responsible, targetNotFound, err := CheckResponsibility(ctx, c.lsUncachedClient, metadata, c.deployerType, c.targetSelectors) if err != nil { return lsutil.LogHelper{}.LogErrorAndGetReconcileResult(ctx, err) } @@ -215,7 +241,7 @@ func (c *controller) reconcilePrivate(ctx context.Context, metadata *metav1.Part logger, ctx := logging.FromContextOrNew(ctx, nil) di := &lsv1alpha1.DeployItem{} - if err := read_write_layer.GetDeployItem(ctx, c.lsClient, client.ObjectKeyFromObject(metadata), di, read_write_layer.R000035); err != nil { + if err := read_write_layer.GetDeployItem(ctx, c.lsUncachedClient, client.ObjectKeyFromObject(metadata), di, read_write_layer.R000035); err != nil { if apierrors.IsNotFound(err) { logger.Debug(err.Error()) return reconcile.Result{}, nil @@ -235,7 +261,7 @@ func (c *controller) reconcilePrivate(ctx context.Context, metadata *metav1.Part hasTestReconcileAnnotation := lsv1alpha1helper.HasOperation(di.ObjectMeta, lsv1alpha1.TestReconcileOperation) - if !hasTestReconcileAnnotation && di.Status.GetJobID() == di.Status.JobIDFinished { + if IsDeployItemFinished(di) { logger.Debug("deploy item not reconciled because no new job ID or test reconcile annotation") return reconcile.Result{}, nil } @@ -302,7 +328,7 @@ func (c *controller) reconcilePrivate(ctx context.Context, metadata *metav1.Part } func (c *controller) handleReconcileResult(ctx context.Context, err lserrors.LsError, oldDeployItem, deployItem *lsv1alpha1.DeployItem) error { - return HandleReconcileResult(ctx, err, oldDeployItem, deployItem, c.lsClient, c.lsEventRecorder) + return HandleReconcileResult(ctx, err, oldDeployItem, deployItem, c.lsUncachedClient, c.lsEventRecorder, c.finishedObjectCache) } func (c *controller) buildResult(ctx context.Context, phase lsv1alpha1.DeployItemPhase, lsError lserrors.LsError) (reconcile.Result, error) { @@ -329,7 +355,7 @@ func (c *controller) getContext(ctx context.Context, deployItem *lsv1alpha1.Depl } lsCtx := &lsv1alpha1.Context{} - if err := read_write_layer.GetContext(ctx, c.lsClient, kutil.ObjectKey(contextName, deployItem.Namespace), lsCtx, + if err := read_write_layer.GetContext(ctx, c.lsUncachedClient, kutil.ObjectKey(contextName, deployItem.Namespace), lsCtx, read_write_layer.R000043); err != nil { return nil, lserrors.NewWrappedError(err, operation, "GetLandscaperContext", err.Error()) } @@ -394,7 +420,7 @@ func (c *controller) delete(ctx context.Context, deployItem *lsv1alpha1.DeployIt } func (c *controller) Writer() *read_write_layer.Writer { - return read_write_layer.NewWriter(c.lsClient) + return read_write_layer.NewWriter(c.lsUncachedClient) } func (c *controller) initAndUpdateStatus(ctx context.Context, di *lsv1alpha1.DeployItem) error { diff --git a/pkg/deployer/lib/finished_objects.go b/pkg/deployer/lib/finished_objects.go new file mode 100644 index 000000000..8eabf480f --- /dev/null +++ b/pkg/deployer/lib/finished_objects.go @@ -0,0 +1,11 @@ +package lib + +import ( + lsv1alpha1 "github.com/gardener/landscaper/apis/core/v1alpha1" + lsv1alpha1helper "github.com/gardener/landscaper/apis/core/v1alpha1/helper" +) + +func IsDeployItemFinished(di *lsv1alpha1.DeployItem) bool { + hasTestReconcileAnnotation := lsv1alpha1helper.HasOperation(di.ObjectMeta, lsv1alpha1.TestReconcileOperation) + return !hasTestReconcileAnnotation && di.Status.GetJobID() == di.Status.JobIDFinished +} diff --git a/pkg/deployer/lib/targetselector/e2e_suite_test.go b/pkg/deployer/lib/targetselector/e2e_suite_test.go index 2dc914007..a628af486 100644 --- a/pkg/deployer/lib/targetselector/e2e_suite_test.go +++ b/pkg/deployer/lib/targetselector/e2e_suite_test.go @@ -87,19 +87,21 @@ var _ = Describe("E2E", func() { defaultContext.Namespace = state.Namespace testutils.ExpectNoError(state.Create(ctx, defaultContext)) - ctrl, err := mock.NewController(logging.Discard(), testenv.Client, api.LandscaperScheme, record.NewFakeRecorder(1024), mockv1alpha1.Configuration{ - TargetSelector: []lsv1alpha1.TargetSelector{ - { - Annotations: []lsv1alpha1.Requirement{ - { - Key: AnnotationKey, - Operator: selection.Equals, - Values: []string{AnnotationValue}, + ctrl, err := mock.NewController(testenv.Client, testenv.Client, testenv.Client, testenv.Client, + utils.NewFinishedObjectCache(), + logging.Discard(), api.LandscaperScheme, record.NewFakeRecorder(1024), mockv1alpha1.Configuration{ + TargetSelector: []lsv1alpha1.TargetSelector{ + { + Annotations: []lsv1alpha1.Requirement{ + { + Key: AnnotationKey, + Operator: selection.Equals, + Values: []string{AnnotationValue}, + }, }, }, }, - }, - }, "test-e2e"+testutils.GetNextCounter()) + }, "test-e2e"+testutils.GetNextCounter()) testutils.ExpectNoError(err) testutils.ShouldReconcile(ctx, ctrl, kutil.ReconcileRequestFromObject(di)) @@ -137,19 +139,21 @@ var _ = Describe("E2E", func() { testutils.ExpectNoError(err) testutils.ExpectNoError(state.Create(ctx, di)) - ctrl, err := mock.NewController(logging.Discard(), testenv.Client, api.LandscaperScheme, record.NewFakeRecorder(1024), mockv1alpha1.Configuration{ - TargetSelector: []lsv1alpha1.TargetSelector{ - { - Annotations: []lsv1alpha1.Requirement{ - { - Key: AnnotationKey, - Operator: selection.Equals, - Values: []string{"someother"}, + ctrl, err := mock.NewController(testenv.Client, testenv.Client, testenv.Client, testenv.Client, + utils.NewFinishedObjectCache(), + logging.Discard(), api.LandscaperScheme, record.NewFakeRecorder(1024), mockv1alpha1.Configuration{ + TargetSelector: []lsv1alpha1.TargetSelector{ + { + Annotations: []lsv1alpha1.Requirement{ + { + Key: AnnotationKey, + Operator: selection.Equals, + Values: []string{"someother"}, + }, }, }, }, - }, - }, "test-annot"+testutils.GetNextCounter()) + }, "test-annot"+testutils.GetNextCounter()) testutils.ExpectNoError(err) testutils.ShouldReconcile(ctx, ctrl, kutil.ReconcileRequestFromObject(di)) diff --git a/pkg/deployer/lib/utils.go b/pkg/deployer/lib/utils.go index 82489ac23..28c33e180 100644 --- a/pkg/deployer/lib/utils.go +++ b/pkg/deployer/lib/utils.go @@ -142,7 +142,7 @@ func GetRegistryPullSecretsFromContext(lsCtx *lsv1alpha1.Context) []lsv1alpha1.O } func HandleReconcileResult(ctx context.Context, err lserrors.LsError, oldDeployItem, deployItem *lsv1alpha1.DeployItem, - lsClient client.Client, lsEventRecorder record.EventRecorder) error { + lsClient client.Client, lsEventRecorder record.EventRecorder, finishedObjectCache *lsutil.FinishedObjectCache) error { logger, ctx := logging.FromContextOrNew(ctx, nil) lsutil.SetLastError(&deployItem.Status, lserrors.TryUpdateLsError(deployItem.Status.GetLastError(), err)) diff --git a/pkg/deployer/manifest/add.go b/pkg/deployer/manifest/add.go index 2496a6f2e..e1da30d46 100644 --- a/pkg/deployer/manifest/add.go +++ b/pkg/deployer/manifest/add.go @@ -7,6 +7,8 @@ package manifest import ( "fmt" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/manager" @@ -18,7 +20,9 @@ import ( ) // AddDeployerToManager adds a new helm deployers to a controller manager. -func AddDeployerToManager(logger logging.Logger, lsMgr, hostMgr manager.Manager, config manifestv1alpha2.Configuration, +func AddDeployerToManager(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + finishedObjectCache *utils.FinishedObjectCache, + logger logging.Logger, lsMgr, hostMgr manager.Manager, config manifestv1alpha2.Configuration, callerName string) error { log := logger.WithName("k8sManifest") @@ -28,10 +32,8 @@ func AddDeployerToManager(logger logging.Logger, lsMgr, hostMgr manager.Manager, "numberOfWorkerThreads", config.Controller.Workers, "lockingEnabled", lockingEnabled) - d, err := NewDeployer( + d, err := NewDeployer(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, log, - lsMgr.GetClient(), - hostMgr.GetClient(), config, ) if err != nil { @@ -45,13 +47,15 @@ func AddDeployerToManager(logger logging.Logger, lsMgr, hostMgr manager.Manager, options.CacheSyncTimeout = config.Controller.CacheSyncTimeout.Duration } - return deployerlib.Add(log, lsMgr, hostMgr, deployerlib.DeployerArgs{ - Name: Name, - Version: version.Get().String(), - Identity: config.Identity, - Type: Type, - Deployer: d, - TargetSelectors: config.TargetSelector, - Options: options, - }, config.Controller.Workers, lockingEnabled, callerName) + return deployerlib.Add(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, + finishedObjectCache, + log, lsMgr, hostMgr, deployerlib.DeployerArgs{ + Name: Name, + Version: version.Get().String(), + Identity: config.Identity, + Type: Type, + Deployer: d, + TargetSelectors: config.TargetSelector, + Options: options, + }, config.Controller.Workers, lockingEnabled, callerName) } diff --git a/pkg/deployer/manifest/controller.go b/pkg/deployer/manifest/controller.go index ba9880530..29a48a0c2 100644 --- a/pkg/deployer/manifest/controller.go +++ b/pkg/deployer/manifest/controller.go @@ -30,32 +30,35 @@ const ( ) // NewDeployer creates a new deployer that reconciles deploy items of type helm. -func NewDeployer(log logging.Logger, - lsKubeClient client.Client, - hostKubeClient client.Client, +func NewDeployer(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + log logging.Logger, config manifestv1alpha2.Configuration) (deployerlib.Deployer, error) { dep := &deployer{ - log: log, - lsClient: lsKubeClient, - hostClient: hostKubeClient, - config: config, - hooks: extension.ReconcileExtensionHooks{}, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + hostUncachedClient: hostUncachedClient, + hostCachedClient: hostCachedClient, + log: log, + config: config, + hooks: extension.ReconcileExtensionHooks{}, } dep.hooks.RegisterHookSetup(cr.ContinuousReconcileExtensionSetup(dep.NextReconcile)) return dep, nil } type deployer struct { - log logging.Logger - lsClient client.Client - hostClient client.Client - config manifestv1alpha2.Configuration - hooks extension.ReconcileExtensionHooks + lsUncachedClient client.Client + lsCachedClient client.Client + hostUncachedClient client.Client + hostCachedClient client.Client + log logging.Logger + config manifestv1alpha2.Configuration + hooks extension.ReconcileExtensionHooks } func (d *deployer) Reconcile(ctx context.Context, _ *lsv1alpha1.Context, di *lsv1alpha1.DeployItem, rt *lsv1alpha1.ResolvedTarget) error { - manifest, err := New(d.lsClient, d.hostClient, &d.config, di, rt) + manifest, err := New(d.lsUncachedClient, d.hostUncachedClient, &d.config, di, rt) if err != nil { return err } @@ -63,7 +66,7 @@ func (d *deployer) Reconcile(ctx context.Context, _ *lsv1alpha1.Context, di *lsv } func (d deployer) Delete(ctx context.Context, _ *lsv1alpha1.Context, di *lsv1alpha1.DeployItem, rt *lsv1alpha1.ResolvedTarget) error { - manifest, err := New(d.lsClient, d.hostClient, &d.config, di, rt) + manifest, err := New(d.lsUncachedClient, d.hostUncachedClient, &d.config, di, rt) if err != nil { return err } @@ -80,7 +83,7 @@ func (d *deployer) ExtensionHooks() extension.ReconcileExtensionHooks { } func (d *deployer) NextReconcile(ctx context.Context, last time.Time, di *lsv1alpha1.DeployItem) (*time.Time, error) { - manifest, err := New(d.lsClient, d.hostClient, &d.config, di, nil) + manifest, err := New(d.lsUncachedClient, d.hostUncachedClient, &d.config, di, nil) if err != nil { return nil, err } diff --git a/pkg/deployer/manifest/ensure.go b/pkg/deployer/manifest/ensure.go index 971eaf6f8..03634c2b1 100644 --- a/pkg/deployer/manifest/ensure.go +++ b/pkg/deployer/manifest/ensure.go @@ -71,7 +71,7 @@ func (m *Manifest) Reconcile(ctx context.Context) error { manifestv1alpha2.ManagedDeployItemLabel: m.DeployItem.Name, }, DeletionGroupsDuringUpdate: m.ProviderConfiguration.DeletionGroupsDuringUpdate, - InterruptionChecker: interruption.NewStandardInterruptionChecker(m.DeployItem, m.lsKubeClient), + InterruptionChecker: interruption.NewStandardInterruptionChecker(m.DeployItem, m.lsUncachedClient), }) err = applier.Apply(ctx) @@ -110,7 +110,7 @@ func (m *Manifest) Reconcile(ctx context.Context) error { opts := resourcemanager.ExporterOptions{ KubeClient: targetClient, - InterruptionChecker: interruption.NewStandardInterruptionChecker(m.DeployItem, m.lsKubeClient), + InterruptionChecker: interruption.NewStandardInterruptionChecker(m.DeployItem, m.lsUncachedClient), DeployItem: m.DeployItem, } @@ -120,7 +120,7 @@ func (m *Manifest) Reconcile(ctx context.Context) error { return lserrors.NewWrappedError(err, currOp, "ReadExportValues", err.Error()) } - if err := deployerlib.CreateOrUpdateExport(ctx, m.Writer(), m.lsKubeClient, m.DeployItem, exports); err != nil { + if err := deployerlib.CreateOrUpdateExport(ctx, m.Writer(), m.lsUncachedClient, m.DeployItem, exports); err != nil { return err } } @@ -147,7 +147,7 @@ func (m *Manifest) CheckResourcesReady(ctx context.Context, client client.Client Timeout: &lsv1alpha1.Duration{Duration: timeout}, ManagedResources: managedresources, FailOnMissingObject: true, - InterruptionChecker: interruption.NewStandardInterruptionChecker(m.DeployItem, m.lsKubeClient), + InterruptionChecker: interruption.NewStandardInterruptionChecker(m.DeployItem, m.lsUncachedClient), } err := defaultReadinessCheck.CheckResourcesReady() if err != nil { @@ -169,7 +169,7 @@ func (m *Manifest) CheckResourcesReady(ctx context.Context, client client.Client Timeout: &lsv1alpha1.Duration{Duration: timeout}, ManagedResources: managedresources, Configuration: customReadinessCheckConfig, - InterruptionChecker: interruption.NewStandardInterruptionChecker(m.DeployItem, m.lsKubeClient), + InterruptionChecker: interruption.NewStandardInterruptionChecker(m.DeployItem, m.lsUncachedClient), } err := customReadinessCheck.CheckResourcesReady() if err != nil { @@ -234,7 +234,7 @@ func (m *Manifest) deleteManifestsInGroups(ctx context.Context) error { managedResources = append(managedResources, *mr) } - interruptionChecker := interruption.NewStandardInterruptionChecker(m.DeployItem, m.lsKubeClient) + interruptionChecker := interruption.NewStandardInterruptionChecker(m.DeployItem, m.lsUncachedClient) err = resourcemanager.DeleteManagedResources( ctx, @@ -302,5 +302,5 @@ func annotateBeforeDelete(ctx context.Context, mr *managedresource.ManagedResour } func (m *Manifest) Writer() *read_write_layer.Writer { - return read_write_layer.NewWriter(m.lsKubeClient) + return read_write_layer.NewWriter(m.lsUncachedClient) } diff --git a/pkg/deployer/manifest/manifest.go b/pkg/deployer/manifest/manifest.go index 571be2f79..691e47c17 100644 --- a/pkg/deployer/manifest/manifest.go +++ b/pkg/deployer/manifest/manifest.go @@ -46,9 +46,10 @@ func init() { // Manifest is the internal representation of a DeployItem of Type Manifest type Manifest struct { - lsKubeClient client.Client - hostKubeClient client.Client - Configuration *manifestv1alpha2.Configuration + lsUncachedClient client.Client + hostUncachedClient client.Client + + Configuration *manifestv1alpha2.Configuration DeployItem *lsv1alpha1.DeployItem Target *lsv1alpha1.ResolvedTarget @@ -66,8 +67,7 @@ func NewDeployItemBuilder() *utils.DeployItemBuilder { } // New creates a new internal manifest item -func New(lsKubeClient client.Client, - hostKubeClient client.Client, +func New(lsUncachedClient client.Client, hostUncachedClient client.Client, configuration *manifestv1alpha2.Configuration, item *lsv1alpha1.DeployItem, rt *lsv1alpha1.ResolvedTarget) (*Manifest, error) { @@ -97,8 +97,8 @@ func New(lsKubeClient client.Client, } return &Manifest{ - lsKubeClient: lsKubeClient, - hostKubeClient: hostKubeClient, + lsUncachedClient: lsUncachedClient, + hostUncachedClient: hostUncachedClient, Configuration: configuration, DeployItem: item, Target: rt, @@ -146,7 +146,7 @@ func (m *Manifest) TargetClient(ctx context.Context) (*rest.Config, client.Clien return nil, nil, nil, fmt.Errorf("unable to parse target confíguration: %w", err) } - kubeconfigBytes, err := lib.GetKubeconfigFromTargetConfig(ctx, targetConfig, m.Target.Namespace, m.lsKubeClient) + kubeconfigBytes, err := lib.GetKubeconfigFromTargetConfig(ctx, targetConfig, m.Target.Namespace, m.lsUncachedClient) if err != nil { return nil, nil, nil, err } diff --git a/pkg/deployer/manifest/test/e2e_test.go b/pkg/deployer/manifest/test/e2e_test.go index febcc204e..b83b813df 100644 --- a/pkg/deployer/manifest/test/e2e_test.go +++ b/pkg/deployer/manifest/test/e2e_test.go @@ -52,19 +52,17 @@ var _ = Describe("Manifest Deployer", func() { state, err = testenv.InitState(context.TODO()) Expect(err).ToNot(HaveOccurred()) - deployer, err := manifestctlr.NewDeployer( + deployer, err := manifestctlr.NewDeployer(testenv.Client, testenv.Client, testenv.Client, testenv.Client, logging.Discard(), - testenv.Client, - testenv.Client, manifestv1alpha2.Configuration{}, ) Expect(err).ToNot(HaveOccurred()) ctrl = deployerlib.NewController( - testenv.Client, + testenv.Client, testenv.Client, testenv.Client, testenv.Client, + utils.NewFinishedObjectCache(), api.LandscaperScheme, record.NewFakeRecorder(1024), - testenv.Client, api.LandscaperScheme, deployerlib.DeployerArgs{ Type: manifestctlr.Type, diff --git a/pkg/deployer/mock/add.go b/pkg/deployer/mock/add.go index b28caea96..ca078d291 100644 --- a/pkg/deployer/mock/add.go +++ b/pkg/deployer/mock/add.go @@ -7,9 +7,10 @@ package mock import ( "fmt" + "sigs.k8s.io/controller-runtime/pkg/client" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/tools/record" - "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -21,49 +22,51 @@ import ( ) // AddDeployerToManager adds a new helm deployers to a controller manager. -func AddDeployerToManager(logger logging.Logger, lsMgr, hostMgr manager.Manager, config mockv1alpha1.Configuration, +func AddDeployerToManager(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + finishedObjectCache *utils.FinishedObjectCache, + logger logging.Logger, lsMgr, hostMgr manager.Manager, config mockv1alpha1.Configuration, callerName string) error { log := logger.WithName("mock") log.Info(fmt.Sprintf("Running on pod %s in namespace %s", utils.GetCurrentPodName(), utils.GetCurrentPodNamespace())) - d, err := NewDeployer( + d, err := NewDeployer(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, log, - lsMgr.GetClient(), - hostMgr.GetClient(), config, ) if err != nil { return err } - return deployerlib.Add(log, lsMgr, hostMgr, deployerlib.DeployerArgs{ - Name: Name, - Version: version.Get().String(), - Identity: config.Identity, - Type: Type, - Deployer: d, - TargetSelectors: config.TargetSelector, - }, 5, false, callerName) + return deployerlib.Add(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, + finishedObjectCache, + log, lsMgr, hostMgr, deployerlib.DeployerArgs{ + Name: Name, + Version: version.Get().String(), + Identity: config.Identity, + Type: Type, + Deployer: d, + TargetSelectors: config.TargetSelector, + }, 5, false, callerName) } // NewController creates a new simple controller. // This method should only be used for testing. -func NewController(log logging.Logger, kubeClient client.Client, scheme *runtime.Scheme, eventRecorder record.EventRecorder, +func NewController(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + finishedObjectCache *utils.FinishedObjectCache, + log logging.Logger, scheme *runtime.Scheme, eventRecorder record.EventRecorder, config mockv1alpha1.Configuration, callerName string) (reconcile.Reconciler, error) { - d, err := NewDeployer( + d, err := NewDeployer(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, log, - kubeClient, - kubeClient, config, ) if err != nil { return nil, err } - return deployerlib.NewController(kubeClient, - scheme, eventRecorder, - kubeClient, scheme, + return deployerlib.NewController(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, + finishedObjectCache, + scheme, eventRecorder, scheme, deployerlib.DeployerArgs{ Type: Type, Deployer: d, diff --git a/pkg/deployer/mock/controller.go b/pkg/deployer/mock/controller.go index 30b93238d..86b1172f7 100644 --- a/pkg/deployer/mock/controller.go +++ b/pkg/deployer/mock/controller.go @@ -30,28 +30,32 @@ import ( ) // NewDeployer creates a new deployer that reconciles deploy items of type mock. -func NewDeployer(log logging.Logger, - lsKubeClient client.Client, - hostKubeClient client.Client, +func NewDeployer(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + log logging.Logger, config mockv1alpha1.Configuration) (deployerlib.Deployer, error) { dep := &deployer{ - log: log, - lsClient: lsKubeClient, - hostClient: hostKubeClient, - config: config, - hooks: extension.ReconcileExtensionHooks{}, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + hostUncachedClient: hostUncachedClient, + hostCachedClient: hostCachedClient, + log: log, + config: config, + hooks: extension.ReconcileExtensionHooks{}, } dep.hooks.RegisterHookSetup(cr.ContinuousReconcileExtensionSetup(dep.NextReconcile)) return dep, nil } type deployer struct { - log logging.Logger - lsClient client.Client - hostClient client.Client - config mockv1alpha1.Configuration - hooks extension.ReconcileExtensionHooks + lsUncachedClient client.Client + lsCachedClient client.Client + hostUncachedClient client.Client + hostCachedClient client.Client + + log logging.Logger + config mockv1alpha1.Configuration + hooks extension.ReconcileExtensionHooks } func (d *deployer) Reconcile(ctx context.Context, lsCtx *lsv1alpha1.Context, di *lsv1alpha1.DeployItem, _ *lsv1alpha1.ResolvedTarget) error { @@ -104,7 +108,7 @@ func (d *deployer) ensureDeletion(ctx context.Context, item *lsv1alpha1.DeployIt secret.Name = item.Status.ExportReference.Name secret.Namespace = item.Status.ExportReference.Namespace - if err := d.lsClient.Delete(ctx, secret); err != nil { + if err := d.lsUncachedClient.Delete(ctx, secret); err != nil { if apierrors.IsNotFound(err) { return nil } @@ -126,7 +130,7 @@ func (d *deployer) ensureExport(ctx context.Context, item *lsv1alpha1.DeployItem secret.Namespace = item.Status.ExportReference.Namespace } - _, err := kubernetesutil.CreateOrUpdate(ctx, d.lsClient, secret, func() error { + _, err := kubernetesutil.CreateOrUpdate(ctx, d.lsUncachedClient, secret, func() error { secret.Data = map[string][]byte{ lsv1alpha1.DataObjectSecretDataKey: *config.Export, } @@ -179,5 +183,5 @@ func (d *deployer) NextReconcile(ctx context.Context, last time.Time, di *lsv1al } func (d *deployer) Writer() *read_write_layer.Writer { - return read_write_layer.NewWriter(d.lsClient) + return read_write_layer.NewWriter(d.lsUncachedClient) } diff --git a/pkg/deployermanagement/controller/add.go b/pkg/deployermanagement/controller/add.go index 39e550363..e7f7fdcaf 100644 --- a/pkg/deployermanagement/controller/add.go +++ b/pkg/deployermanagement/controller/add.go @@ -7,6 +7,8 @@ package deployers import ( "fmt" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -20,16 +22,17 @@ import ( ) // AddControllersToManager adds all deployer registration related deployers to the manager. -func AddControllersToManager(logger logging.Logger, mgr manager.Manager, config *config.LandscaperConfiguration) error { +func AddControllersToManager(lsUncachedClient, lsCachedClient client.Client, + logger logging.Logger, lsMgr manager.Manager, config *config.LandscaperConfiguration) error { log := logger.Reconciles("environment", "Environment") env := NewEnvironmentController( + lsUncachedClient, lsCachedClient, log, - mgr.GetClient(), - mgr.GetScheme(), + lsMgr.GetScheme(), config, ) - err := builder.ControllerManagedBy(mgr). + err := builder.ControllerManagedBy(lsMgr). For(&lsv1alpha1.Environment{}). WithLogConstructor(func(r *reconcile.Request) logr.Logger { return log.Logr() }). Complete(env) @@ -39,14 +42,14 @@ func AddControllersToManager(logger logging.Logger, mgr manager.Manager, config log = logger.Reconciles("deployerRegistration", "DeployerRegistration") deployerReg := NewDeployerRegistrationController( + lsUncachedClient, lsCachedClient, log, - mgr.GetClient(), - mgr.GetScheme(), + lsMgr.GetScheme(), config, ) - err = builder.ControllerManagedBy(mgr). - For(&lsv1alpha1.DeployerRegistration{}). + err = builder.ControllerManagedBy(lsMgr). + For(&lsv1alpha1.DeployerRegistration{}, builder.OnlyMetadata). WithLogConstructor(func(r *reconcile.Request) logr.Logger { return log.Logr() }). Complete(deployerReg) if err != nil { @@ -55,14 +58,14 @@ func AddControllersToManager(logger logging.Logger, mgr manager.Manager, config log = logger.Reconciles("deployerRegistration", "Installation") inst := NewInstallationController( + lsUncachedClient, lsCachedClient, log, - mgr.GetClient(), - mgr.GetScheme(), + lsMgr.GetScheme(), config, ) - err = builder.ControllerManagedBy(mgr). - For(&lsv1alpha1.Installation{}). + err = builder.ControllerManagedBy(lsMgr). + For(&lsv1alpha1.Installation{}, builder.OnlyMetadata). WithLogConstructor(func(r *reconcile.Request) logr.Logger { return log.Logr() }). Complete(inst) if err != nil { diff --git a/pkg/deployermanagement/controller/controller.go b/pkg/deployermanagement/controller/controller.go index e99785f77..3b7b82523 100644 --- a/pkg/deployermanagement/controller/controller.go +++ b/pkg/deployermanagement/controller/controller.go @@ -24,38 +24,41 @@ import ( ) // NewEnvironmentController creates a new landscaper agent EnvironmentController. -func NewEnvironmentController(log logging.Logger, c client.Client, scheme *runtime.Scheme, config *config.LandscaperConfiguration) reconcile.Reconciler { +func NewEnvironmentController(lsUncachedClient, lsCachedClient client.Client, log logging.Logger, scheme *runtime.Scheme, config *config.LandscaperConfiguration) reconcile.Reconciler { return &EnvironmentController{ - log: log, - client: c, - scheme: scheme, - config: config, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + log: log, + scheme: scheme, + config: config, dm: &DeployerManagement{ - log: log, - client: c, - scheme: scheme, - config: config.DeployerManagement, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + log: log, + scheme: scheme, + config: config.DeployerManagement, }, } } type EnvironmentController struct { - log logging.Logger - config *config.LandscaperConfiguration - client client.Client - scheme *runtime.Scheme - dm *DeployerManagement + lsUncachedClient client.Client + lsCachedClient client.Client + log logging.Logger + config *config.LandscaperConfiguration + scheme *runtime.Scheme + dm *DeployerManagement } func (con *EnvironmentController) Writer() *read_write_layer.Writer { - return read_write_layer.NewWriter(con.client) + return read_write_layer.NewWriter(con.lsUncachedClient) } func (con *EnvironmentController) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) { logger, ctx := con.log.StartReconcileAndAddToContext(ctx, req) env := &lsv1alpha1.Environment{} - if err := con.client.Get(ctx, req.NamespacedName, env); err != nil { + if err := con.lsUncachedClient.Get(ctx, req.NamespacedName, env); err != nil { if apierrors.IsNotFound(err) { logger.Info(err.Error()) return reconcile.Result{}, nil @@ -64,7 +67,7 @@ func (con *EnvironmentController) Reconcile(ctx context.Context, req reconcile.R } registrations := &lsv1alpha1.DeployerRegistrationList{} - if err := con.client.List(ctx, registrations); err != nil { + if err := con.lsUncachedClient.List(ctx, registrations); err != nil { return reconcile.Result{}, err } @@ -92,7 +95,7 @@ func (con *EnvironmentController) Reconcile(ctx context.Context, req reconcile.R return reconcile.Result{}, err } controllerutil.RemoveFinalizer(env, lsv1alpha1.LandscaperDMFinalizer) - if err := con.client.Update(ctx, env); err != nil { + if err := con.lsUncachedClient.Update(ctx, env); err != nil { return reconcile.Result{}, fmt.Errorf("unable to remove finalizer: %w", err) } return reconcile.Result{}, nil @@ -102,7 +105,7 @@ func (con *EnvironmentController) Reconcile(ctx context.Context, req reconcile.R if !controllerutil.ContainsFinalizer(env, lsv1alpha1.LandscaperDMFinalizer) { controllerutil.AddFinalizer(env, lsv1alpha1.LandscaperDMFinalizer) - if err := con.client.Update(ctx, env); err != nil { + if err := con.lsUncachedClient.Update(ctx, env); err != nil { return reconcile.Result{}, fmt.Errorf("unable to add finalizer: %w", err) } } @@ -136,30 +139,34 @@ func (con *EnvironmentController) Reconcile(ctx context.Context, req reconcile.R } // NewDeployerRegistrationController creates a new landscaper agent DeployerRegistrationController. -func NewDeployerRegistrationController(log logging.Logger, c client.Client, scheme *runtime.Scheme, config *config.LandscaperConfiguration) reconcile.Reconciler { +func NewDeployerRegistrationController(lsUncachedClient, lsCachedClient client.Client, log logging.Logger, + scheme *runtime.Scheme, config *config.LandscaperConfiguration) reconcile.Reconciler { return &DeployerRegistrationController{ - log: log, - client: c, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + log: log, dm: &DeployerManagement{ - log: log, - client: c, - scheme: scheme, - config: config.DeployerManagement, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + log: log, + scheme: scheme, + config: config.DeployerManagement, }, } } type DeployerRegistrationController struct { - log logging.Logger - client client.Client - dm *DeployerManagement + lsUncachedClient client.Client + lsCachedClient client.Client + log logging.Logger + dm *DeployerManagement } func (con *DeployerRegistrationController) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) { logger, ctx := con.log.StartReconcileAndAddToContext(ctx, req) registration := &lsv1alpha1.DeployerRegistration{} - if err := con.client.Get(ctx, req.NamespacedName, registration); err != nil { + if err := con.lsUncachedClient.Get(ctx, req.NamespacedName, registration); err != nil { if apierrors.IsNotFound(err) { logger.Info(err.Error()) return reconcile.Result{}, nil @@ -170,13 +177,13 @@ func (con *DeployerRegistrationController) Reconcile(ctx context.Context, req re if !controllerutil.ContainsFinalizer(registration, lsv1alpha1.LandscaperDMFinalizer) { controllerutil.AddFinalizer(registration, lsv1alpha1.LandscaperDMFinalizer) - if err := con.client.Update(ctx, registration); err != nil { + if err := con.lsUncachedClient.Update(ctx, registration); err != nil { return reconcile.Result{}, fmt.Errorf("unable to add finalizer: %w", err) } } environments := &lsv1alpha1.EnvironmentList{} - if err := con.client.List(ctx, environments); err != nil { + if err := con.lsUncachedClient.List(ctx, environments); err != nil { return reconcile.Result{}, err } @@ -204,7 +211,7 @@ func (con *DeployerRegistrationController) Reconcile(ctx context.Context, req re return reconcile.Result{}, err } controllerutil.RemoveFinalizer(registration, lsv1alpha1.LandscaperDMFinalizer) - if err := con.client.Update(ctx, registration); err != nil { + if err := con.lsUncachedClient.Update(ctx, registration); err != nil { return reconcile.Result{}, fmt.Errorf("unable to remove finalizer: %w", err) } return reconcile.Result{}, nil @@ -221,24 +228,27 @@ func (con *DeployerRegistrationController) Reconcile(ctx context.Context, req re } type InstallationController struct { - log logging.Logger - config *config.LandscaperConfiguration - client client.Client - dm *DeployerManagement + lsUncachedClient client.Client + lsCachedClient client.Client + log logging.Logger + config *config.LandscaperConfiguration + dm *DeployerManagement } // NewInstallationController creates a new landscaper agent InstallationController. // This controller only reconciles deployer installations and its main purpose is cleanup. -func NewInstallationController(log logging.Logger, c client.Client, scheme *runtime.Scheme, config *config.LandscaperConfiguration) reconcile.Reconciler { +func NewInstallationController(lsUncachedClient, lsCachedClient client.Client, log logging.Logger, scheme *runtime.Scheme, config *config.LandscaperConfiguration) reconcile.Reconciler { return &InstallationController{ - log: log, - config: config, - client: c, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + log: log, + config: config, dm: &DeployerManagement{ - log: log, - client: c, - scheme: scheme, - config: config.DeployerManagement, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + log: log, + scheme: scheme, + config: config.DeployerManagement, }, } } @@ -251,7 +261,7 @@ func (con *InstallationController) Reconcile(ctx context.Context, req reconcile. } inst := &lsv1alpha1.Installation{} - if err := read_write_layer.GetInstallation(ctx, con.client, req.NamespacedName, inst, read_write_layer.R000005); err != nil { + if err := read_write_layer.GetInstallation(ctx, con.lsUncachedClient, req.NamespacedName, inst, read_write_layer.R000005); err != nil { if apierrors.IsNotFound(err) { logger.Info(err.Error()) return reconcile.Result{}, nil diff --git a/pkg/deployermanagement/controller/controller_reconcile_test.go b/pkg/deployermanagement/controller/controller_reconcile_test.go index 45875cf00..fcf674aad 100644 --- a/pkg/deployermanagement/controller/controller_reconcile_test.go +++ b/pkg/deployermanagement/controller/controller_reconcile_test.go @@ -41,14 +41,14 @@ var _ = Describe("EnvironmentController Reconcile Test", func() { ctx = context.Background() lsConfig = &config.LandscaperConfiguration{} envController = deployers.NewEnvironmentController( + testenv.Client, testenv.Client, logging.Discard(), - testenv.Client, api.LandscaperScheme, lsConfig, ) regController = deployers.NewDeployerRegistrationController( + testenv.Client, testenv.Client, logging.Discard(), - testenv.Client, api.LandscaperScheme, lsConfig, ) diff --git a/pkg/deployermanagement/controller/deployer_management_delete.go b/pkg/deployermanagement/controller/deployer_management_delete.go index 4308c3d92..9620772ee 100644 --- a/pkg/deployermanagement/controller/deployer_management_delete.go +++ b/pkg/deployermanagement/controller/deployer_management_delete.go @@ -25,7 +25,7 @@ func (dm *DeployerManagement) Delete(ctx context.Context, registration *lsv1alph } instKey := kutil.ObjectKeyFromObject(inst) - if err := read_write_layer.GetInstallation(ctx, dm.client, instKey, inst, read_write_layer.R000013); err != nil { + if err := read_write_layer.GetInstallation(ctx, dm.lsUncachedClient, instKey, inst, read_write_layer.R000013); err != nil { if apierrors.IsNotFound(err) { // installation is already deleted // nothing to do. @@ -40,7 +40,7 @@ func (dm *DeployerManagement) Delete(ctx context.Context, registration *lsv1alph } // wait for installation deletion. return wait.PollUntilContextTimeout(ctx, 20*time.Second, 5*time.Minute, true, func(ctx context.Context) (done bool, err error) { - if err := read_write_layer.GetInstallation(ctx, dm.client, instKey, inst, read_write_layer.R000007); err != nil { + if err := read_write_layer.GetInstallation(ctx, dm.lsUncachedClient, instKey, inst, read_write_layer.R000007); err != nil { if apierrors.IsNotFound(err) { return true, nil } diff --git a/pkg/deployermanagement/controller/deployer_management_reconcile.go b/pkg/deployermanagement/controller/deployer_management_reconcile.go index a586a9dfa..fa7f28d90 100644 --- a/pkg/deployermanagement/controller/deployer_management_reconcile.go +++ b/pkg/deployermanagement/controller/deployer_management_reconcile.go @@ -38,19 +38,21 @@ import ( const DeployerClusterRoleName = "landscaper:deployer" type DeployerManagement struct { - log logging.Logger - client client.Client - scheme *runtime.Scheme - config config.DeployerManagementConfiguration + lsUncachedClient client.Client + lsCachedClient client.Client + log logging.Logger + scheme *runtime.Scheme + config config.DeployerManagementConfiguration } // NewDeployerManagement creates a new deployer manager. -func NewDeployerManagement(log logging.Logger, client client.Client, scheme *runtime.Scheme, config config.DeployerManagementConfiguration) *DeployerManagement { +func NewDeployerManagement(lsUncachedClient, lsCachedClient client.Client, log logging.Logger, scheme *runtime.Scheme, config config.DeployerManagementConfiguration) *DeployerManagement { return &DeployerManagement{ - log: log, - client: client, - scheme: scheme, - config: config, + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + log: log, + scheme: scheme, + config: config, } } @@ -133,7 +135,7 @@ func (dm *DeployerManagement) getInstallation(ctx context.Context, log, ctx := logging.FromContextOrNew(ctx, nil, lc.KeyMethod, "getInstallation") installations := &lsv1alpha1.InstallationList{} - if err := read_write_layer.ListInstallations(ctx, dm.client, installations, read_write_layer.R000017, + if err := read_write_layer.ListInstallations(ctx, dm.lsUncachedClient, installations, read_write_layer.R000017, client.InNamespace(dm.config.Namespace), client.MatchingLabels{ lsv1alpha1.DeployerEnvironmentLabelName: env.Name, @@ -153,7 +155,7 @@ func (dm *DeployerManagement) getInstallation(ctx context.Context, fmt.Sprintf("installation name %q in namespace %q exceeds maximum length of %d (environment %q)", inst.Name, dm.config.Namespace, validation.InstallationNameMaxLength, env.Name)) registration.Status.LastError = lserrors.TryUpdateError(inst.Status.LastError, err) - if err := dm.client.Status().Update(ctx, registration); err != nil { + if err := dm.lsUncachedClient.Status().Update(ctx, registration); err != nil { log.Error(err, "failed to update status for deployer registration") } @@ -194,7 +196,7 @@ func (dm *DeployerManagement) createDeployerTarget(ctx context.Context, sa.Name = FQName(registration, env) sa.Namespace = dm.config.Namespace - if _, err := controllerutil.CreateOrUpdate(ctx, dm.client, sa, func() error { + if _, err := controllerutil.CreateOrUpdate(ctx, dm.lsUncachedClient, sa, func() error { return controllerutil.SetControllerReference(inst, sa, dm.scheme) }); err != nil { return err @@ -207,7 +209,7 @@ func (dm *DeployerManagement) createDeployerTarget(ctx context.Context, restConfig.TLSClientConfig.ServerName = env.Spec.LandscaperClusterRestConfig.TLSClientConfig.ServerName restConfig.TLSClientConfig.CAData = env.Spec.LandscaperClusterRestConfig.TLSClientConfig.CAData - if err := kutil.AddServiceAccountToken(ctx, dm.client, sa, restConfig); err != nil { + if err := kutil.AddServiceAccountToken(ctx, dm.lsUncachedClient, sa, restConfig); err != nil { log.Error(err, "unable to add service account token", lc.KeyServiceAccount, client.ObjectKeyFromObject(sa).String()) return err } @@ -218,7 +220,7 @@ func (dm *DeployerManagement) createDeployerTarget(ctx context.Context, crb := &rbacv1.ClusterRoleBinding{} crb.Name = FQName(registration, env) - if _, err := controllerutil.CreateOrUpdate(ctx, dm.client, crb, func() error { + if _, err := controllerutil.CreateOrUpdate(ctx, dm.lsUncachedClient, crb, func() error { crb.RoleRef = rbacv1.RoleRef{ APIGroup: rbacv1.SchemeGroupVersion.Group, Kind: "ClusterRole", @@ -262,13 +264,13 @@ func (dm *DeployerManagement) CleanupInstallation(ctx context.Context, inst *lsv crb := &rbacv1.ClusterRoleBinding{} crb.Name = FQNameFromName(regName, envName) - if err := dm.client.Delete(ctx, crb); err != nil && !apierrors.IsNotFound(err) { + if err := dm.lsUncachedClient.Delete(ctx, crb); err != nil && !apierrors.IsNotFound(err) { return fmt.Errorf("unable to delete clusterrolebinding %q: %w", crb.Name, err) } err := wait.PollUntilContextTimeout(ctx, 10*time.Second, 2*time.Minute, true, func(ctx context.Context) (done bool, err error) { obj := crb.DeepCopy() - if err := dm.client.Get(ctx, kutil.ObjectKeyFromObject(obj), obj); err != nil { + if err := dm.lsUncachedClient.Get(ctx, kutil.ObjectKeyFromObject(obj), obj); err != nil { if apierrors.IsNotFound(err) { return true, nil } @@ -290,7 +292,7 @@ func (dm *DeployerManagement) EnsureRBACRoles(ctx context.Context) error { clusterrole := &rbacv1.ClusterRole{} clusterrole.Name = DeployerClusterRoleName - if _, err := controllerutil.CreateOrUpdate(ctx, dm.client, clusterrole, func() error { + if _, err := controllerutil.CreateOrUpdate(ctx, dm.lsUncachedClient, clusterrole, func() error { // secrets to interact with the deploy items clusterrole.Rules = []rbacv1.PolicyRule{ { @@ -324,6 +326,11 @@ func (dm *DeployerManagement) EnsureRBACRoles(ctx context.Context) error { Resources: []string{"events"}, Verbs: []string{"create", "get", "watch", "patch", "update"}, }, + { + APIGroups: []string{corev1.SchemeGroupVersion.Group}, + Resources: []string{"namespaces"}, + Verbs: []string{"get", "watch", "list"}, + }, } return nil }); err != nil { @@ -333,7 +340,7 @@ func (dm *DeployerManagement) EnsureRBACRoles(ctx context.Context) error { } func (dm *DeployerManagement) Writer() *read_write_layer.Writer { - return read_write_layer.NewWriter(dm.client) + return read_write_layer.NewWriter(dm.lsUncachedClient) } // FQName defines the fully qualified name for the resources created for a deployer installation. diff --git a/pkg/deployermanagement/controller/deployer_management_test.go b/pkg/deployermanagement/controller/deployer_management_test.go index ced181e31..35dbee003 100644 --- a/pkg/deployermanagement/controller/deployer_management_test.go +++ b/pkg/deployermanagement/controller/deployer_management_test.go @@ -42,7 +42,7 @@ var _ = Describe("Deployer Management Test", func() { Expect(err).ToNot(HaveOccurred()) dmConfig = &config.DeployerManagementConfiguration{} dmConfig.Namespace = state.Namespace - dm = deployers.NewDeployerManagement(logging.Discard(), testenv.Client, api.LandscaperScheme, *dmConfig) + dm = deployers.NewDeployerManagement(testenv.Client, testenv.Client, logging.Discard(), api.LandscaperScheme, *dmConfig) }) AfterEach(func() { diff --git a/pkg/landscaper/controllers/context/add.go b/pkg/landscaper/controllers/context/add.go index 34dc4dd8a..2edfcb85c 100644 --- a/pkg/landscaper/controllers/context/add.go +++ b/pkg/landscaper/controllers/context/add.go @@ -7,6 +7,7 @@ package context import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/builder" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -20,7 +21,8 @@ import ( // AddControllerToManager adds the context defaulterController to the defaulterController manager. // That defaulterController watches namespaces and creates the default context object in every namespace. -func AddControllerToManager(logger logging.Logger, mgr manager.Manager, config *config.LandscaperConfiguration) error { +func AddControllerToManager(lsUncachedClient, lsCachedClient client.Client, + logger logging.Logger, lsMgr manager.Manager, config *config.LandscaperConfiguration) error { log := logger.Reconciles("context", "Namespace") if config.Controllers.Contexts.Config.Default.Disable { log.Info("Default Context controller is disabled") @@ -28,18 +30,18 @@ func AddControllerToManager(logger logging.Logger, mgr manager.Manager, config * } a, err := NewDefaulterController( + lsUncachedClient, lsCachedClient, log, - mgr.GetClient(), - mgr.GetScheme(), - mgr.GetEventRecorderFor("Landscaper"), + lsMgr.GetScheme(), + lsMgr.GetEventRecorderFor("Landscaper"), config.Controllers.Contexts.Config, ) if err != nil { return err } - return builder.ControllerManagedBy(mgr). - For(&corev1.Namespace{}). + return builder.ControllerManagedBy(lsMgr). + For(&corev1.Namespace{}, builder.OnlyMetadata). WithOptions(utils.ConvertCommonControllerConfigToControllerOptions(config.Controllers.Contexts.CommonControllerConfig)). WithLogConstructor(func(r *reconcile.Request) logr.Logger { return log.Logr() }). Complete(a) diff --git a/pkg/landscaper/controllers/context/controller.go b/pkg/landscaper/controllers/context/controller.go index 93d9b4ffc..68fb1a8d9 100644 --- a/pkg/landscaper/controllers/context/controller.go +++ b/pkg/landscaper/controllers/context/controller.go @@ -24,14 +24,15 @@ import ( ) // NewDefaulterController creates a new context controller that reconciles the default context object in the namespaces. -func NewDefaulterController(logger logging.Logger, - kubeClient client.Client, +func NewDefaulterController(lsUncachedClient, lsCachedClient client.Client, + logger logging.Logger, scheme *runtime.Scheme, eventRecorder record.EventRecorder, config config.ContextControllerConfig) (reconcile.Reconciler, error) { return &defaulterController{ + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, log: logger, - client: kubeClient, scheme: scheme, eventRecorder: eventRecorder, config: config, @@ -40,8 +41,9 @@ func NewDefaulterController(logger logging.Logger, } type defaulterController struct { + lsUncachedClient client.Client + lsCachedClient client.Client log logging.Logger - client client.Client eventRecorder record.EventRecorder scheme *runtime.Scheme config config.ContextControllerConfig @@ -57,7 +59,7 @@ func (c *defaulterController) Reconcile(ctx context.Context, req reconcile.Reque ctx = logging.NewContext(ctx, logger) ns := &corev1.Namespace{} - if err := c.client.Get(ctx, req.NamespacedName, ns); err != nil { + if err := c.lsUncachedClient.Get(ctx, req.NamespacedName, ns); err != nil { if apierrors.IsNotFound(err) { logger.Info(err.Error()) return reconcile.Result{}, nil @@ -90,5 +92,5 @@ func (c *defaulterController) Reconcile(ctx context.Context, req reconcile.Reque } func (c *defaulterController) Writer() *read_write_layer.Writer { - return read_write_layer.NewWriter(c.client) + return read_write_layer.NewWriter(c.lsUncachedClient) } diff --git a/pkg/landscaper/controllers/context/reconcile_test.go b/pkg/landscaper/controllers/context/reconcile_test.go index c3a4aed9f..f652d14e3 100644 --- a/pkg/landscaper/controllers/context/reconcile_test.go +++ b/pkg/landscaper/controllers/context/reconcile_test.go @@ -39,8 +39,8 @@ var _ = Describe("Reconcile", func() { Expect(err).ToNot(HaveOccurred()) ctrl, err = contextctrl.NewDefaulterController( + testenv.Client, testenv.Client, logging.Discard(), - testenv.Client, api.Scheme, record.NewFakeRecorder(1024), config.ContextControllerConfig{ @@ -93,8 +93,8 @@ var _ = Describe("Reconcile", func() { ctx := context.Background() ctrl, err := contextctrl.NewDefaulterController( + testenv.Client, testenv.Client, logging.Discard(), - testenv.Client, api.Scheme, record.NewFakeRecorder(1024), config.ContextControllerConfig{ diff --git a/pkg/landscaper/controllers/deployitem/add.go b/pkg/landscaper/controllers/deployitem/add.go index fca176734..613872c99 100644 --- a/pkg/landscaper/controllers/deployitem/add.go +++ b/pkg/landscaper/controllers/deployitem/add.go @@ -7,6 +7,8 @@ package deployitem import ( "fmt" + "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/go-logr/logr" "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/manager" @@ -19,8 +21,9 @@ import ( "github.com/gardener/landscaper/pkg/utils" ) -func AddControllerToManager(logger logging.Logger, - mgr manager.Manager, +func AddControllerToManager(lsUncachedClient, lsCachedClient client.Client, + logger logging.Logger, + lsMgr manager.Manager, config config.DeployItemsController, deployItemPickupTimeout *lscore.Duration) error { @@ -30,9 +33,9 @@ func AddControllerToManager(logger logging.Logger, "numberOfWorkerThreads", config.CommonControllerConfig.Workers) a, err := NewController( + lsUncachedClient, lsCachedClient, log, - mgr.GetClient(), - mgr.GetScheme(), + lsMgr.GetScheme(), deployItemPickupTimeout, config.CommonControllerConfig.Workers, ) @@ -40,7 +43,7 @@ func AddControllerToManager(logger logging.Logger, return err } - return builder.ControllerManagedBy(mgr). + return builder.ControllerManagedBy(lsMgr). For(&lsv1alpha1.DeployItem{}, builder.OnlyMetadata). WithOptions(utils.ConvertCommonControllerConfigToControllerOptions(config.CommonControllerConfig)). WithLogConstructor(func(r *reconcile.Request) logr.Logger { return log.Logr() }). diff --git a/pkg/landscaper/controllers/deployitem/controller.go b/pkg/landscaper/controllers/deployitem/controller.go index 5e01187ca..43451aebc 100644 --- a/pkg/landscaper/controllers/deployitem/controller.go +++ b/pkg/landscaper/controllers/deployitem/controller.go @@ -23,12 +23,19 @@ import ( // It is expected that deployers remove the timestamp annotation from deploy items during reconciliation. If the timestamp annotation exists and is older than a specified duration, // the controller marks the deploy item as failed. // pickupTimeout is a string containing the pickup timeout duration, either as 'none' or as a duration that can be parsed by time.ParseDuration. -func NewController(logger logging.Logger, c client.Client, scheme *runtime.Scheme, pickupTimeout *lscore.Duration, +func NewController(lsUncachedClient, lsCachedClient client.Client, + logger logging.Logger, scheme *runtime.Scheme, pickupTimeout *lscore.Duration, maxNumberOfWorkers int) (reconcile.Reconciler, error) { wc := utils.NewWorkerCounter(maxNumberOfWorkers) - con := controller{log: logger, c: c, scheme: scheme, workerCounter: wc} + con := controller{ + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + log: logger, + scheme: scheme, + workerCounter: wc, + } if pickupTimeout != nil { con.pickupTimeout = pickupTimeout.Duration @@ -43,15 +50,16 @@ func NewController(logger logging.Logger, c client.Client, scheme *runtime.Schem } type controller struct { - log logging.Logger - c client.Client - scheme *runtime.Scheme - pickupTimeout time.Duration - workerCounter *utils.WorkerCounter + lsUncachedClient client.Client + lsCachedClient client.Client + log logging.Logger + scheme *runtime.Scheme + pickupTimeout time.Duration + workerCounter *utils.WorkerCounter } func (con *controller) Writer() *read_write_layer.Writer { - return read_write_layer.NewWriter(con.c) + return read_write_layer.NewWriter(con.lsUncachedClient) } func HasBeenPickedUp(di *lsv1alpha1.DeployItem) bool { diff --git a/pkg/landscaper/controllers/deployitem/reconcile.go b/pkg/landscaper/controllers/deployitem/reconcile.go index ed7bd02b1..b76c0c38f 100644 --- a/pkg/landscaper/controllers/deployitem/reconcile.go +++ b/pkg/landscaper/controllers/deployitem/reconcile.go @@ -30,7 +30,7 @@ func (con *controller) Reconcile(ctx context.Context, req reconcile.Request) (re defer con.workerCounter.Exit() di := &lsv1alpha1.DeployItem{} - if err := read_write_layer.GetDeployItem(ctx, con.c, req.NamespacedName, di, read_write_layer.R000028); err != nil { + if err := read_write_layer.GetDeployItem(ctx, con.lsUncachedClient, req.NamespacedName, di, read_write_layer.R000028); err != nil { if apierrors.IsNotFound(err) { logger.Info(err.Error()) return reconcile.Result{}, nil @@ -59,7 +59,7 @@ func (con *controller) Reconcile(ctx context.Context, req reconcile.Request) (re target := &lsv1alpha1.Target{} target.SetName(di.Spec.Target.Name) target.SetNamespace(di.Namespace) - if err := con.c.Get(ctx, client.ObjectKeyFromObject(target), target); err != nil { + if err := con.lsUncachedClient.Get(ctx, client.ObjectKeyFromObject(target), target); err != nil { if apierrors.IsNotFound(err) { targetNotFound = true } diff --git a/pkg/landscaper/controllers/deployitem/reconcile_test.go b/pkg/landscaper/controllers/deployitem/reconcile_test.go index e83dd847a..9d99c5f98 100644 --- a/pkg/landscaper/controllers/deployitem/reconcile_test.go +++ b/pkg/landscaper/controllers/deployitem/reconcile_test.go @@ -33,7 +33,7 @@ var _ = Describe("Deploy Item Controller Reconcile Test", func() { BeforeEach(func() { var err error - deployItemController, err = dictrl.NewController(logging.Discard(), testenv.Client, api.LandscaperScheme, + deployItemController, err = dictrl.NewController(testenv.Client, testenv.Client, logging.Discard(), api.LandscaperScheme, &testPickupTimeoutDuration, 1000) Expect(err).ToNot(HaveOccurred()) }) diff --git a/pkg/landscaper/controllers/execution/add.go b/pkg/landscaper/controllers/execution/add.go index 71fbf0082..61f72a8e5 100644 --- a/pkg/landscaper/controllers/execution/add.go +++ b/pkg/landscaper/controllers/execution/add.go @@ -7,6 +7,8 @@ package execution import ( "fmt" + "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/go-logr/logr" "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/manager" @@ -20,7 +22,8 @@ import ( ) // AddControllerToManager adds the execution controller to the controller manager -func AddControllerToManager(logger logging.Logger, lsMgr, hostMgr manager.Manager, config *config.LandscaperConfiguration) error { +func AddControllerToManager(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + logger logging.Logger, lsMgr, hostMgr manager.Manager, config *config.LandscaperConfiguration) error { log := logger.Reconciles("execution", "Execution") lockingEnabled := lock.IsLockingEnabledForMainControllers(config) @@ -30,9 +33,8 @@ func AddControllerToManager(logger logging.Logger, lsMgr, hostMgr manager.Manage "lockingEnabled", lockingEnabled) a, err := NewController( + lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, log, - lsMgr.GetClient(), - hostMgr.GetClient(), lsMgr.GetScheme(), lsMgr.GetEventRecorderFor("Landscaper"), config.Controllers.Executions.CommonControllerConfig.Workers, diff --git a/pkg/landscaper/controllers/execution/check.go b/pkg/landscaper/controllers/execution/check.go new file mode 100644 index 000000000..c4d020055 --- /dev/null +++ b/pkg/landscaper/controllers/execution/check.go @@ -0,0 +1,29 @@ +package execution + +import ( + lsv1alpha1 "github.com/gardener/landscaper/apis/core/v1alpha1" + lsv1alpha1helper "github.com/gardener/landscaper/apis/core/v1alpha1/helper" + kutil "github.com/gardener/landscaper/controller-utils/pkg/kubernetes" +) + +func isExecFinished(exec *lsv1alpha1.Execution) bool { + if needsFinalizer(exec) || + hasInterruptOperation(exec) || + isDifferentJobIDs(exec) { + return false + } + + return true +} + +func needsFinalizer(exec *lsv1alpha1.Execution) bool { + return exec.DeletionTimestamp.IsZero() && !kutil.HasFinalizer(exec, lsv1alpha1.LandscaperFinalizer) +} + +func hasInterruptOperation(exec *lsv1alpha1.Execution) bool { + return lsv1alpha1helper.HasOperation(exec.ObjectMeta, lsv1alpha1.InterruptOperation) +} + +func isDifferentJobIDs(exec *lsv1alpha1.Execution) bool { + return exec.Status.JobID != exec.Status.JobIDFinished +} diff --git a/pkg/landscaper/controllers/execution/controller.go b/pkg/landscaper/controllers/execution/controller.go index b50aa777e..f6a523f7e 100644 --- a/pkg/landscaper/controllers/execution/controller.go +++ b/pkg/landscaper/controllers/execution/controller.go @@ -8,6 +8,8 @@ import ( "context" "fmt" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -29,28 +31,43 @@ import ( ) // NewController creates a new execution controller that reconcile Execution resources. -func NewController(logger logging.Logger, lsClient, hostClient client.Client, scheme *runtime.Scheme, - eventRecorder record.EventRecorder, maxNumberOfWorker int, lockingEnabled bool, callerName string) (reconcile.Reconciler, error) { +func NewController(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + logger logging.Logger, scheme *runtime.Scheme, eventRecorder record.EventRecorder, maxNumberOfWorker int, + lockingEnabled bool, callerName string) (reconcile.Reconciler, error) { + + ctx := logging.NewContext(context.Background(), logger) wc := lsutil.NewWorkerCounter(maxNumberOfWorker) + finishedObjectCache, err := prepareFinishedObjectCache(ctx, lsUncachedClient) + if err != nil { + return nil, err + } + return &controller{ - log: logger, - lsClient: lsClient, - hostClient: hostClient, - scheme: scheme, - eventRecorder: eventRecorder, - workerCounter: wc, - lockingEnabled: lockingEnabled, - callerName: callerName, - locker: *lock.NewLocker(lsClient, hostClient, callerName), + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, + hostUncachedClient: hostUncachedClient, + hostCachedClient: hostCachedClient, + finishedObjectCache: finishedObjectCache, + log: logger, + scheme: scheme, + eventRecorder: eventRecorder, + workerCounter: wc, + lockingEnabled: lockingEnabled, + callerName: callerName, + locker: *lock.NewLocker(lsUncachedClient, hostUncachedClient, callerName), }, nil } type controller struct { + lsUncachedClient client.Client + lsCachedClient client.Client + hostUncachedClient client.Client + hostCachedClient client.Client + finishedObjectCache *lsutil.FinishedObjectCache + log logging.Logger - lsClient client.Client - hostClient client.Client eventRecorder record.EventRecorder scheme *runtime.Scheme workerCounter *lsutil.WorkerCounter @@ -59,6 +76,44 @@ type controller struct { locker lock.Locker } +func prepareFinishedObjectCache(ctx context.Context, lsUncachedClient client.Client) (*lsutil.FinishedObjectCache, error) { + log, ctx := logging.FromContextOrNew(ctx, nil) + + finishedObjectCache := lsutil.NewFinishedObjectCache() + namespaces := &corev1.NamespaceList{} + if err := read_write_layer.ListNamespaces(ctx, lsUncachedClient, namespaces, read_write_layer.R000099); err != nil { + return nil, err + } + + perfTotal := lsutil.StartPerformanceMeasurement(&log, "prepare finished object for executions") + defer perfTotal.Stop() + + for _, namespace := range namespaces.Items { + perf := lsutil.StartPerformanceMeasurement(&log, "prepare finished object cache for executions: fetch from namespace "+namespace.Name) + + execList := &lsv1alpha1.ExecutionList{} + if err := read_write_layer.ListExecutions(ctx, lsUncachedClient, execList, read_write_layer.R000100, + client.InNamespace(namespace.Name)); err != nil { + return nil, err + } + + perf.Stop() + + perf = lsutil.StartPerformanceMeasurement(&log, "prepare finished object cache for executions: add for namespace "+namespace.Name) + + for execIndex := range execList.Items { + exec := &execList.Items[execIndex] + if isExecFinished(exec) { + finishedObjectCache.Add(&exec.ObjectMeta) + } + } + + perf.Stop() + } + + return finishedObjectCache, nil +} + func (c *controller) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) { logger := c.log.StartReconcile(req) ctx = logging.NewContext(ctx, logger) @@ -66,9 +121,24 @@ func (c *controller) Reconcile(ctx context.Context, req reconcile.Request) (reco c.workerCounter.EnterWithLog(logger, 70, "executions") defer c.workerCounter.Exit() + if c.finishedObjectCache.IsContained(req) { + cachedMetadata := lsutil.EmptyExecutionMetadata() + if err := read_write_layer.GetMetaData(ctx, c.lsCachedClient, req.NamespacedName, cachedMetadata, read_write_layer.R000101); err != nil { + if apierrors.IsNotFound(err) { + logger.Debug(err.Error()) + return reconcile.Result{}, nil + } + return lsutil.LogHelper{}.LogStandardErrorAndGetReconcileResult(ctx, err) + } + + if c.finishedObjectCache.IsFinishedAndRemove(cachedMetadata) { + return reconcile.Result{}, nil + } + } + if c.lockingEnabled { metadata := lsutil.EmptyExecutionMetadata() - if err := c.lsClient.Get(ctx, req.NamespacedName, metadata); err != nil { + if err := c.lsUncachedClient.Get(ctx, req.NamespacedName, metadata); err != nil { if apierrors.IsNotFound(err) { logger.Debug(err.Error()) return reconcile.Result{}, nil @@ -91,7 +161,7 @@ func (c *controller) Reconcile(ctx context.Context, req reconcile.Request) (reco } exec := &lsv1alpha1.Execution{} - if err := read_write_layer.GetExecution(ctx, c.lsClient, req.NamespacedName, exec, read_write_layer.R000019); err != nil { + if err := read_write_layer.GetExecution(ctx, c.lsUncachedClient, req.NamespacedName, exec, read_write_layer.R000019); err != nil { if apierrors.IsNotFound(err) { logger.Info(err.Error()) return reconcile.Result{}, nil @@ -99,21 +169,21 @@ func (c *controller) Reconcile(ctx context.Context, req reconcile.Request) (reco return lsutil.LogHelper{}.LogStandardErrorAndGetReconcileResult(ctx, err) } - if exec.DeletionTimestamp.IsZero() && !kutil.HasFinalizer(exec, lsv1alpha1.LandscaperFinalizer) { + if needsFinalizer(exec) { controllerutil.AddFinalizer(exec, lsv1alpha1.LandscaperFinalizer) if err := c.Writer().UpdateExecution(ctx, read_write_layer.W000086, exec); err != nil { return lsutil.LogHelper{}.LogStandardErrorAndGetReconcileResult(ctx, err) } } - if lsv1alpha1helper.HasOperation(exec.ObjectMeta, lsv1alpha1.InterruptOperation) { + if hasInterruptOperation(exec) { if err := c.handleInterruptOperation(ctx, exec); err != nil { return lsutil.LogHelper{}.LogStandardErrorAndGetReconcileResult(ctx, err) } return reconcile.Result{}, nil } - if exec.Status.JobID != exec.Status.JobIDFinished { + if isDifferentJobIDs(exec) { // Execution is unfinished err := c.handleReconcilePhase(ctx, exec) @@ -252,7 +322,7 @@ func (c *controller) handleReconcilePhase(ctx context.Context, exec *lsv1alpha1. func (c *controller) handlePhaseInit(ctx context.Context, exec *lsv1alpha1.Execution, deployItemCache *lsv1alpha1.DeployItemCache) lserrors.LsError { forceReconcile := false - o := execution.NewOperation(operation.NewOperation(c.lsClient, c.scheme, c.eventRecorder), exec, forceReconcile) + o := execution.NewOperation(operation.NewOperation(c.scheme, c.eventRecorder, c.lsUncachedClient), exec, forceReconcile) return o.UpdateDeployItems(ctx, deployItemCache) } @@ -260,7 +330,7 @@ func (c *controller) handlePhaseInit(ctx context.Context, exec *lsv1alpha1.Execu func (c *controller) handlePhaseProgressing(ctx context.Context, exec *lsv1alpha1.Execution) ( *execution.DeployItemClassification, lserrors.LsError) { forceReconcile := false - o := execution.NewOperation(operation.NewOperation(c.lsClient, c.scheme, c.eventRecorder), exec, forceReconcile) + o := execution.NewOperation(operation.NewOperation(c.scheme, c.eventRecorder, c.lsUncachedClient), exec, forceReconcile) return o.TriggerDeployItems(ctx) } @@ -272,7 +342,7 @@ func (c *controller) handlePhaseCompleting(ctx context.Context, exec *lsv1alpha1 } forceReconcile := false - o := execution.NewOperation(operation.NewOperation(c.lsClient, c.scheme, c.eventRecorder), exec, forceReconcile) + o := execution.NewOperation(operation.NewOperation(c.scheme, c.eventRecorder, c.lsUncachedClient), exec, forceReconcile) return o.CollectAndUpdateExportsNew(ctx) } @@ -281,7 +351,7 @@ func (c *controller) handlePhaseInitDelete(ctx context.Context, exec *lsv1alpha1 op := "handlePhaseInitDelete" forceReconcile := false - o := execution.NewOperation(operation.NewOperation(c.lsClient, c.scheme, c.eventRecorder), exec, forceReconcile) + o := execution.NewOperation(operation.NewOperation(c.scheme, c.eventRecorder, c.lsUncachedClient), exec, forceReconcile) managedItems, err := o.ListManagedDeployItems(ctx, read_write_layer.R000083, exec.Status.DeployItemCache) if err != nil { @@ -301,7 +371,7 @@ func (c *controller) handlePhaseInitDelete(ctx context.Context, exec *lsv1alpha1 } if item.DeletionTimestamp.IsZero() { - if err := o.Writer().DeleteDeployItem(ctx, read_write_layer.W000112, item); client.IgnoreNotFound(err) != nil { + if err := o.WriterToLsUncachedClient().DeleteDeployItem(ctx, read_write_layer.W000112, item); client.IgnoreNotFound(err) != nil { return lserrors.NewWrappedError(err, "DeleteDeployItem", fmt.Sprintf("unable to delete deploy item %s / %s", item.Namespace, item.Name), err.Error()) } @@ -314,13 +384,13 @@ func (c *controller) handlePhaseInitDelete(ctx context.Context, exec *lsv1alpha1 func (c *controller) handlePhaseDeleting(ctx context.Context, exec *lsv1alpha1.Execution) ( *execution.DeployItemClassification, lserrors.LsError) { forceReconcile := false - o := execution.NewOperation(operation.NewOperation(c.lsClient, c.scheme, c.eventRecorder), exec, forceReconcile) + o := execution.NewOperation(operation.NewOperation(c.scheme, c.eventRecorder, c.lsUncachedClient), exec, forceReconcile) return o.TriggerDeployItemsForDelete(ctx) } func (c *controller) Writer() *read_write_layer.Writer { - return read_write_layer.NewWriter(c.lsClient) + return read_write_layer.NewWriter(c.lsUncachedClient) } func (c *controller) handleInterruptOperation(ctx context.Context, exec *lsv1alpha1.Execution) error { @@ -332,7 +402,7 @@ func (c *controller) handleInterruptOperation(ctx context.Context, exec *lsv1alp op := "handleInterruptOperation" forceReconcile := false - o := execution.NewOperation(operation.NewOperation(c.lsClient, c.scheme, c.eventRecorder), exec, forceReconcile) + o := execution.NewOperation(operation.NewOperation(c.scheme, c.eventRecorder, c.lsUncachedClient), exec, forceReconcile) managedItems, err := o.ListManagedDeployItems(ctx, read_write_layer.R000058, nil) if err != nil { @@ -352,7 +422,7 @@ func (c *controller) handleInterruptOperation(ctx context.Context, exec *lsv1alp "InterruptOperation", "operation was interrupted")) - if err := o.Writer().UpdateDeployItemStatus(ctx, read_write_layer.W000101, item); err != nil { + if err := o.WriterToLsUncachedClient().UpdateDeployItemStatus(ctx, read_write_layer.W000101, item); err != nil { return lserrors.NewWrappedError(err, "UpdateDeployItemStatus", fmt.Sprintf("unable to update deploy item %s / %s for interrupt", item.Namespace, item.Name), err.Error()) } @@ -385,7 +455,7 @@ func (c *controller) setExecutionPhaseAndUpdate(ctx context.Context, exec *lsv1a if exec.Status.ExecutionPhase == lsv1alpha1.ExecutionPhases.Deleting { // recheck if already deleted execRecheck := &lsv1alpha1.Execution{} - errRecheck := read_write_layer.GetExecution(ctx, c.lsClient, kutil.ObjectKey(exec.Name, exec.Namespace), + errRecheck := read_write_layer.GetExecution(ctx, c.lsUncachedClient, kutil.ObjectKey(exec.Name, exec.Namespace), execRecheck, read_write_layer.R000021) if errRecheck != nil && apierrors.IsNotFound(errRecheck) { return nil diff --git a/pkg/landscaper/controllers/execution/reconcile_test.go b/pkg/landscaper/controllers/execution/reconcile_test.go index 249f0bd59..86179ad23 100644 --- a/pkg/landscaper/controllers/execution/reconcile_test.go +++ b/pkg/landscaper/controllers/execution/reconcile_test.go @@ -34,7 +34,7 @@ var _ = Describe("Reconcile", func() { ) BeforeEach(func() { var err error - ctrl, err = execution.NewController(logging.Discard(), testenv.Client, testenv.Client, api.Scheme, + ctrl, err = execution.NewController(testenv.Client, testenv.Client, testenv.Client, testenv.Client, logging.Discard(), api.Scheme, record.NewFakeRecorder(1024), 1000, false, "exec-test-"+testutils.GetNextCounter()) Expect(err).ToNot(HaveOccurred()) state, err = testenv.InitState(context.TODO()) diff --git a/pkg/landscaper/controllers/installations/add.go b/pkg/landscaper/controllers/installations/add.go index 4bbc0b542..d44a7f09b 100644 --- a/pkg/landscaper/controllers/installations/add.go +++ b/pkg/landscaper/controllers/installations/add.go @@ -5,8 +5,11 @@ package installations import ( + "context" "fmt" + "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/gardener/landscaper/pkg/utils/lock" "github.com/go-logr/logr" @@ -21,8 +24,11 @@ import ( ) // AddControllerToManager register the installation Controller in a manager. -func AddControllerToManager(logger logging.Logger, lsMgr, hostMgr manager.Manager, config *config.LandscaperConfiguration, callerName string) error { +func AddControllerToManager(lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + logger logging.Logger, lsMgr manager.Manager, config *config.LandscaperConfiguration, callerName string) error { + log := logger.Reconciles("installation", "Installation") + ctx := logging.NewContext(context.Background(), log) lockingEnabled := lock.IsLockingEnabledForMainControllers(config) @@ -30,10 +36,9 @@ func AddControllerToManager(logger logging.Logger, lsMgr, hostMgr manager.Manage "numberOfWorkerThreads", config.Controllers.Installations.CommonControllerConfig.Workers, "lockingEnabled", lockingEnabled) - a, err := NewController( - hostMgr.GetClient(), + a, err := NewController(ctx, + lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, log, - lsMgr.GetClient(), lsMgr.GetScheme(), lsMgr.GetEventRecorderFor("Landscaper"), config, diff --git a/pkg/landscaper/controllers/installations/checks.go b/pkg/landscaper/controllers/installations/checks.go new file mode 100644 index 000000000..36f4325e3 --- /dev/null +++ b/pkg/landscaper/controllers/installations/checks.go @@ -0,0 +1,65 @@ +package installations + +import ( + lsv1alpha1 "github.com/gardener/landscaper/apis/core/v1alpha1" + lsv1alpha1helper "github.com/gardener/landscaper/apis/core/v1alpha1/helper" + kutil "github.com/gardener/landscaper/controller-utils/pkg/kubernetes" + "github.com/gardener/landscaper/pkg/landscaper/installations" +) + +func isInstFinished(inst *lsv1alpha1.Installation) bool { + if isAutomaticReconcileOnSpecChange(inst) || + isAutomaticReconcileConfigured(inst) || + needsFinalizer(inst) || + hasDependentsToTrigger(inst) || + hasInterruptOperation(inst) || + isNotRootWithReconcileOperation(inst) || + isCreateNewJobID(inst) || + isDifferentJobIDs(inst) { + return false + } + + return true +} + +func isAutomaticReconcileOnSpecChange(inst *lsv1alpha1.Installation) bool { + return installations.IsRootInstallation(inst) && + lsv1alpha1helper.HasReconcileIfChangedAnnotation(inst.ObjectMeta) && + !lsv1alpha1helper.HasOperation(inst.ObjectMeta, lsv1alpha1.ReconcileOperation) && + inst.Status.JobID == inst.Status.JobIDFinished && + inst.GetGeneration() != inst.Status.ObservedGeneration +} + +func isAutomaticReconcileConfigured(inst *lsv1alpha1.Installation) bool { + retryHelper := newRetryHelper(nil, nil) + return retryHelper.isRetryActivatedForSucceeded(inst) || retryHelper.isRetryActivatedForFailed(inst) +} + +func needsFinalizer(inst *lsv1alpha1.Installation) bool { + return inst.DeletionTimestamp.IsZero() && !kutil.HasFinalizer(inst, lsv1alpha1.LandscaperFinalizer) + +} + +func hasDependentsToTrigger(inst *lsv1alpha1.Installation) bool { + return len(inst.Status.DependentsToTrigger) > 0 +} + +func hasInterruptOperation(inst *lsv1alpha1.Installation) bool { + return lsv1alpha1helper.HasOperation(inst.ObjectMeta, lsv1alpha1.InterruptOperation) +} + +func isNotRootWithReconcileOperation(inst *lsv1alpha1.Installation) bool { + return !installations.IsRootInstallation(inst) && lsv1alpha1helper.HasOperation(inst.ObjectMeta, lsv1alpha1.ReconcileOperation) +} + +func isCreateNewJobID(inst *lsv1alpha1.Installation) bool { + isFirstDelete := !inst.DeletionTimestamp.IsZero() && !inst.Status.InstallationPhase.IsDeletion() + + return installations.IsRootInstallation(inst) && + (lsv1alpha1helper.HasOperation(inst.ObjectMeta, lsv1alpha1.ReconcileOperation) || isFirstDelete) && + inst.Status.JobID == inst.Status.JobIDFinished +} + +func isDifferentJobIDs(inst *lsv1alpha1.Installation) bool { + return inst.Status.JobID != inst.Status.JobIDFinished +} diff --git a/pkg/landscaper/controllers/installations/controller.go b/pkg/landscaper/controllers/installations/controller.go index bde487b13..1819bfc82 100644 --- a/pkg/landscaper/controllers/installations/controller.go +++ b/pkg/landscaper/controllers/installations/controller.go @@ -46,8 +46,9 @@ const ( ) // NewController creates a new Controller that reconciles Installation resources. -func NewController(hostClient client.Client, logger logging.Logger, - lsClient client.Client, +func NewController(ctx context.Context, + lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + logger logging.Logger, scheme *runtime.Scheme, eventRecorder record.EventRecorder, lsConfig *config.LandscaperConfiguration, @@ -58,14 +59,16 @@ func NewController(hostClient client.Client, logger logging.Logger, ws := utils.NewWorkerCounter(maxNumberOfWorkers) ctrl := &Controller{ - hostClient: hostClient, - log: logger, - clock: clock.RealClock{}, - LsConfig: lsConfig, - workerCounter: ws, - lockingEnabled: lockingEnabled, - callerName: callerName, - locker: *lock.NewLocker(lsClient, hostClient, callerName), + lsCachedClient: lsCachedClient, + hostUncachedClient: hostUncachedClient, + hostCachedClient: hostCachedClient, + log: logger, + clock: clock.RealClock{}, + LsConfig: lsConfig, + workerCounter: ws, + lockingEnabled: lockingEnabled, + callerName: callerName, + locker: *lock.NewLocker(lsUncachedClient, hostUncachedClient, callerName), } if lsConfig != nil && lsConfig.Registry.OCI != nil { @@ -79,40 +82,92 @@ func NewController(hostClient client.Client, logger logging.Logger, registries.SetOCMLibraryMode(lsConfig.UseOCMLib) - op := operation.NewOperation(lsClient, scheme, eventRecorder) + op := operation.NewOperation(scheme, eventRecorder, lsUncachedClient) ctrl.Operation = *op + + finishedObjectCache, err := prepareFinishedObjectCache(ctx, lsUncachedClient) + if err != nil { + return nil, err + } + ctrl.finishedObjectCache = finishedObjectCache + return ctrl, nil } +func prepareFinishedObjectCache(ctx context.Context, lsUncachedClient client.Client) (*utils.FinishedObjectCache, error) { + log, ctx := logging.FromContextOrNew(ctx, nil) + + finishedObjectCache := utils.NewFinishedObjectCache() + namespaces := &corev1.NamespaceList{} + if err := read_write_layer.ListNamespaces(ctx, lsUncachedClient, namespaces, read_write_layer.R000096); err != nil { + return nil, err + } + + perfTotal := utils.StartPerformanceMeasurement(&log, "prepare finished object for installations") + defer perfTotal.Stop() + + for _, namespace := range namespaces.Items { + perf := utils.StartPerformanceMeasurement(&log, "prepare finished object cache for installations: fetch from namespace "+namespace.Name) + + instList := &lsv1alpha1.InstallationList{} + if err := read_write_layer.ListInstallations(ctx, lsUncachedClient, instList, read_write_layer.R000097, + client.InNamespace(namespace.Name)); err != nil { + return nil, err + } + + perf.Stop() + + perf = utils.StartPerformanceMeasurement(&log, "prepare finished object cache for installations: add for namespace "+namespace.Name) + + for instIndex := range instList.Items { + inst := &instList.Items[instIndex] + if isInstFinished(inst) { + finishedObjectCache.Add(&inst.ObjectMeta) + } + } + + perf.Stop() + } + + return finishedObjectCache, nil +} + // NewTestActuator creates a new Controller that is only meant for testing. -func NewTestActuator(op operation.Operation, hostClient client.Client, logger logging.Logger, passiveClock clock.PassiveClock, +func NewTestActuator(lsCachedClient, hostUncachedClient, hostCachedClient client.Client, + op operation.Operation, logger logging.Logger, passiveClock clock.PassiveClock, configuration *config.LandscaperConfiguration, callerName string) *Controller { return &Controller{ - log: logger, - clock: passiveClock, - Operation: op, - LsConfig: configuration, - workerCounter: utils.NewWorkerCounter(1000), - hostClient: hostClient, - lockingEnabled: lock.IsLockingEnabledForMainControllers(configuration), - callerName: callerName, - locker: *lock.NewLocker(hostClient, hostClient, callerName), + lsCachedClient: lsCachedClient, + hostUncachedClient: hostUncachedClient, + hostCachedClient: hostCachedClient, + finishedObjectCache: utils.NewFinishedObjectCache(), + log: logger, + clock: passiveClock, + Operation: op, + LsConfig: configuration, + workerCounter: utils.NewWorkerCounter(1000), + lockingEnabled: lock.IsLockingEnabledForMainControllers(configuration), + callerName: callerName, + locker: *lock.NewLocker(op.LsUncachedClient(), hostUncachedClient, callerName), } } // Controller is the controller that reconciles a installation resource. type Controller struct { operation.Operation - hostClient client.Client - log logging.Logger - clock clock.PassiveClock - LsConfig *config.LandscaperConfiguration - SharedCache cache.Cache - workerCounter *utils.WorkerCounter - lockingEnabled bool - callerName string - locker lock.Locker + lsCachedClient client.Client + hostUncachedClient client.Client + hostCachedClient client.Client + finishedObjectCache *utils.FinishedObjectCache + log logging.Logger + clock clock.PassiveClock + LsConfig *config.LandscaperConfiguration + SharedCache cache.Cache + workerCounter *utils.WorkerCounter + lockingEnabled bool + callerName string + locker lock.Locker } func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) { @@ -121,9 +176,24 @@ func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (reco c.workerCounter.EnterWithLog(logger, 70, "installations") defer c.workerCounter.Exit() + if c.finishedObjectCache.IsContained(req) { + cachedMetadata := utils.EmptyInstallationMetadata() + if err := read_write_layer.GetMetaData(ctx, c.lsCachedClient, req.NamespacedName, cachedMetadata, read_write_layer.R000098); err != nil { + if apierrors.IsNotFound(err) { + logger.Debug(err.Error()) + return reconcile.Result{}, nil + } + return utils.LogHelper{}.LogStandardErrorAndGetReconcileResult(ctx, err) + } + + if c.finishedObjectCache.IsFinishedAndRemove(cachedMetadata) { + return reconcile.Result{}, nil + } + } + if c.lockingEnabled { metadata := utils.EmptyInstallationMetadata() - if err := c.Client().Get(ctx, req.NamespacedName, metadata); err != nil { + if err := c.LsUncachedClient().Get(ctx, req.NamespacedName, metadata); err != nil { if apierrors.IsNotFound(err) { logger.Debug(err.Error()) return reconcile.Result{}, nil @@ -146,7 +216,7 @@ func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (reco } inst := &lsv1alpha1.Installation{} - if err := read_write_layer.GetInstallation(ctx, c.Client(), req.NamespacedName, inst, read_write_layer.R000010); err != nil { + if err := read_write_layer.GetInstallation(ctx, c.LsUncachedClient(), req.NamespacedName, inst, read_write_layer.R000010); err != nil { if apierrors.IsNotFound(err) { logger.Info(err.Error()) return reconcile.Result{}, nil @@ -170,7 +240,7 @@ func (c *Controller) updateInstallationWithDefaults(ctx context.Context, inst *l api.LandscaperScheme.Default(inst) if !reflect.DeepEqual(&inst.Spec, &oldInst.Spec) { - if err := c.Writer().UpdateInstallation(ctx, read_write_layer.W000065, inst); err != nil { + if err := c.WriterToLsUncachedClient().UpdateInstallation(ctx, read_write_layer.W000065, inst); err != nil { logger.Error(err, "failed to update installation with defaults") return err } @@ -183,17 +253,13 @@ func (c *Controller) handleAutomaticReconcile(ctx context.Context, inst *lsv1alp logger, _ := logging.FromContextOrNew(ctx, nil, lc.KeyMethod, "handleAutomaticReconcile") - if installations.IsRootInstallation(inst) && - lsv1alpha1helper.HasReconcileIfChangedAnnotation(inst.ObjectMeta) && - !lsv1alpha1helper.HasOperation(inst.ObjectMeta, lsv1alpha1.ReconcileOperation) && - inst.Status.JobID == inst.Status.JobIDFinished && - inst.GetGeneration() != inst.Status.ObservedGeneration { + if isAutomaticReconcileOnSpecChange(inst) { if err := c.addReconcileAnnotation(ctx, inst); err != nil { return reconcile.Result{}, err } } - retryHelper := newRetryHelper(c.Client(), c.clock) + retryHelper := newRetryHelper(c.LsUncachedClient(), c.clock) if err := retryHelper.preProcessRetry(ctx, inst); err != nil { return utils.LogHelper{}.LogStandardErrorAndGetReconcileResult(ctx, err) @@ -213,26 +279,28 @@ func (c *Controller) reconcileInstallation(ctx context.Context, inst *lsv1alpha1 logger, ctx := logging.FromContextOrNew(ctx, nil) - if inst.DeletionTimestamp.IsZero() && !kutil.HasFinalizer(inst, lsv1alpha1.LandscaperFinalizer) { + if needsFinalizer(inst) { controllerutil.AddFinalizer(inst, lsv1alpha1.LandscaperFinalizer) - if err := c.Writer().UpdateInstallation(ctx, read_write_layer.W000107, inst); err != nil { + if err := c.WriterToLsUncachedClient().UpdateInstallation(ctx, read_write_layer.W000107, inst); err != nil { return reconcile.Result{}, err } return reconcile.Result{}, nil } - if err := installations.NewInstallationTrigger(c.Client(), inst).TriggerDependents(ctx); err != nil { - return reconcile.Result{}, err + if len(inst.Status.DependentsToTrigger) > 0 { + if err := installations.NewInstallationTrigger(c.LsUncachedClient(), inst).TriggerDependents(ctx); err != nil { + return reconcile.Result{}, err + } } - if lsv1alpha1helper.HasOperation(inst.ObjectMeta, lsv1alpha1.InterruptOperation) { + if hasInterruptOperation(inst) { if err := c.handleInterruptOperation(ctx, inst); err != nil { return reconcile.Result{}, err } return reconcile.Result{}, nil } - if !installations.IsRootInstallation(inst) && lsv1alpha1helper.HasOperation(inst.ObjectMeta, lsv1alpha1.ReconcileOperation) { + if isNotRootWithReconcileOperation(inst) { // only root installations could be triggered with operation annotation to prevent that end users interfere with overall // algorithm logger.Info("Removing reconcile annotation from non-root installation. A reconcile annotation at a non-root installation has no effect") @@ -243,15 +311,11 @@ func (c *Controller) reconcileInstallation(ctx context.Context, inst *lsv1alpha1 } // generate new jobID - isFirstDelete := !inst.DeletionTimestamp.IsZero() && !inst.Status.InstallationPhase.IsDeletion() - if installations.IsRootInstallation(inst) && - (lsv1alpha1helper.HasOperation(inst.ObjectMeta, lsv1alpha1.ReconcileOperation) || isFirstDelete) && - inst.Status.JobID == inst.Status.JobIDFinished { - + if isCreateNewJobID(inst) { inst.Status.JobID = uuid.New().String() inst.Status.TransitionTimes = utils.NewTransitionTimes() - if err := c.Writer().UpdateInstallationStatus(ctx, read_write_layer.W000082, inst); err != nil { + if err := c.WriterToLsUncachedClient().UpdateInstallationStatus(ctx, read_write_layer.W000082, inst); err != nil { return reconcile.Result{}, err } @@ -263,7 +327,7 @@ func (c *Controller) reconcileInstallation(ctx context.Context, inst *lsv1alpha1 } // handle reconcile - if inst.Status.JobID != inst.Status.JobIDFinished { + if isDifferentJobIDs(inst) { err := c.handleReconcilePhase(ctx, inst) return utils.LogHelper{}.LogErrorAndGetReconcileResult(ctx, err) } else { @@ -278,7 +342,7 @@ func (c *Controller) initPrerequisites(ctx context.Context, inst *lsv1alpha1.Ins currOp := "InitPrerequisites" op := c.Operation.Copy() - lsCtx, err := installations.GetInstallationContext(ctx, c.Client(), inst) + lsCtx, err := installations.GetInstallationContext(ctx, c.LsUncachedClient(), inst) if err != nil { return nil, lserrors.NewWrappedError(err, currOp, "CalculateContext", err.Error()) } @@ -327,11 +391,11 @@ func (c *Controller) compareJobIDs(predecessorMap, predecessorMapNew map[string] func (c *Controller) handleInterruptOperation(ctx context.Context, inst *lsv1alpha1.Installation) error { delete(inst.Annotations, lsv1alpha1.OperationAnnotation) - if err := c.Writer().UpdateInstallation(ctx, read_write_layer.W000097, inst); err != nil { + if err := c.WriterToLsUncachedClient().UpdateInstallation(ctx, read_write_layer.W000097, inst); err != nil { return err } - exec, err := executions.GetExecutionForInstallation(ctx, c.Client(), inst) + exec, err := executions.GetExecutionForInstallation(ctx, c.LsUncachedClient(), inst) if err != nil { return err } @@ -340,12 +404,12 @@ func (c *Controller) handleInterruptOperation(ctx context.Context, inst *lsv1alp lsv1alpha1helper.SetOperation(&exec.ObjectMeta, lsv1alpha1.InterruptOperation) lsv1alpha1helper.Touch(&exec.ObjectMeta) - if err = c.Writer().UpdateExecution(ctx, read_write_layer.W000098, exec); err != nil { + if err = c.WriterToLsUncachedClient().UpdateExecution(ctx, read_write_layer.W000098, exec); err != nil { return err } } - subInsts, err := installations.ListSubinstallations(ctx, c.Client(), inst, inst.Status.SubInstCache, read_write_layer.R000090) + subInsts, err := installations.ListSubinstallations(ctx, c.LsUncachedClient(), inst, inst.Status.SubInstCache, read_write_layer.R000090) if err != nil { return nil } @@ -354,7 +418,7 @@ func (c *Controller) handleInterruptOperation(ctx context.Context, inst *lsv1alp lsv1alpha1helper.SetOperation(&subInst.ObjectMeta, lsv1alpha1.InterruptOperation) lsv1alpha1helper.Touch(&subInst.ObjectMeta) - if err = c.Writer().UpdateInstallation(ctx, read_write_layer.W000099, subInst); err != nil { + if err = c.WriterToLsUncachedClient().UpdateInstallation(ctx, read_write_layer.W000099, subInst); err != nil { return err } } @@ -392,7 +456,7 @@ func (c *Controller) setInstallationPhaseAndUpdate(ctx context.Context, inst *ls if inst.Status.JobIDFinished == inst.Status.JobID && inst.DeletionTimestamp.IsZero() { // The installation is about to finish. Put the names of dependent installations in the status. // The dependents will then be triggered in the beginning of the next reconcile event. - dependents, err := installations.NewInstallationTrigger(c.Client(), inst).DetermineDependents(ctx) + dependents, err := installations.NewInstallationTrigger(c.LsUncachedClient(), inst).DetermineDependents(ctx) if err != nil { logger.Error(err, "unable to determine successor installations") if lsError == nil { @@ -404,12 +468,12 @@ func (c *Controller) setInstallationPhaseAndUpdate(ctx context.Context, inst *ls inst.Status.DependentsToTrigger = dependents } - err := c.Writer().UpdateInstallationStatus(ctx, writeID, inst) + err := c.WriterToLsUncachedClient().UpdateInstallationStatus(ctx, writeID, inst) if err != nil { if inst.Status.InstallationPhase == lsv1alpha1.InstallationPhases.Deleting { // recheck if already deleted instRecheck := &lsv1alpha1.Installation{} - errRecheck := read_write_layer.GetInstallation(ctx, c.Client(), kutil.ObjectKey(inst.Name, inst.Namespace), + errRecheck := read_write_layer.GetInstallation(ctx, c.LsUncachedClient(), kutil.ObjectKey(inst.Name, inst.Namespace), instRecheck, read_write_layer.R000009) if errRecheck != nil && apierrors.IsNotFound(errRecheck) { return nil @@ -438,7 +502,7 @@ func (c *Controller) addReconcileAnnotation(ctx context.Context, inst *lsv1alpha lsv1alpha1helper.SetOperation(&inst.ObjectMeta, lsv1alpha1.ReconcileOperation) - if err := c.Writer().UpdateInstallation(ctx, read_write_layer.W000078, inst); err != nil { + if err := c.WriterToLsUncachedClient().UpdateInstallation(ctx, read_write_layer.W000078, inst); err != nil { logger.Error(err, "failed to trigger automatic reconcile operation of installation") return err } diff --git a/pkg/landscaper/controllers/installations/controller_test.go b/pkg/landscaper/controllers/installations/controller_test.go index 9b9ad31e2..9a3d92008 100644 --- a/pkg/landscaper/controllers/installations/controller_test.go +++ b/pkg/landscaper/controllers/installations/controller_test.go @@ -34,15 +34,16 @@ var _ = Describe("Installation Controller", func() { ) BeforeEach(func() { - op = lsoperation.NewOperation(testenv.Client, api.LandscaperScheme, record.NewFakeRecorder(1024)) - - ctrl = installationsctl.NewTestActuator(*op, testenv.Client, logging.Discard(), clock.RealClock{}, &config.LandscaperConfiguration{ - Registry: config.RegistryConfiguration{ - Local: &config.LocalRegistryConfiguration{ - RootPath: "./testdata", + op = lsoperation.NewOperation(api.LandscaperScheme, record.NewFakeRecorder(1024), testenv.Client) + + ctrl = installationsctl.NewTestActuator(testenv.Client, testenv.Client, testenv.Client, + *op, logging.Discard(), clock.RealClock{}, &config.LandscaperConfiguration{ + Registry: config.RegistryConfiguration{ + Local: &config.LocalRegistryConfiguration{ + RootPath: "./testdata", + }, }, - }, - }, "test-inst5-"+testutils.GetNextCounter()) + }, "test-inst5-"+testutils.GetNextCounter()) }) AfterEach(func() { diff --git a/pkg/landscaper/controllers/installations/reconcile.go b/pkg/landscaper/controllers/installations/reconcile.go index 119b75600..0aa1d2c39 100644 --- a/pkg/landscaper/controllers/installations/reconcile.go +++ b/pkg/landscaper/controllers/installations/reconcile.go @@ -55,7 +55,7 @@ func (c *Controller) handleReconcilePhase(ctx context.Context, inst *lsv1alpha1. inst.Status.ObservedGeneration = inst.GetGeneration() // do not use setInstallationPhaseAndUpdate because jobIDFinished should not be set here - if err := c.Writer().UpdateInstallationStatus(ctx, read_write_layer.W000115, inst); err != nil { + if err := c.WriterToLsUncachedClient().UpdateInstallationStatus(ctx, read_write_layer.W000115, inst); err != nil { return lserrors.NewWrappedError(err, op, "InitialPhaseSetting", err.Error()) } } @@ -231,7 +231,7 @@ func (c *Controller) handlePhaseInit(ctx context.Context, inst *lsv1alpha1.Insta currentOperation := "handlePhaseInit" // cleanup - newCleaner := NewDataObjectAndTargetCleaner(inst, c.Client()) + newCleaner := NewDataObjectAndTargetCleaner(inst, c.LsUncachedClient()) if err := newCleaner.CleanupContext(ctx); err != nil { return lserrors.NewWrappedError(err, currentOperation, "CleanupContext", err.Error()), nil } @@ -351,7 +351,7 @@ func (c *Controller) hash(imps *imports.Imports) (string, error) { func (c *Controller) handlePhaseCleanupOrphaned(ctx context.Context, inst *lsv1alpha1.Installation) (lserrors.LsError, lserrors.LsError) { currentOperation := "handlePhaseCleanupOrphaned" - subInsts, err := installations.ListSubinstallations(ctx, c.Client(), inst, inst.Status.SubInstCache, read_write_layer.R000018) + subInsts, err := installations.ListSubinstallations(ctx, c.LsUncachedClient(), inst, inst.Status.SubInstCache, read_write_layer.R000018) if err != nil { return nil, lserrors.NewWrappedError(err, currentOperation, "ListSubinstallations", err.Error()) } @@ -383,7 +383,7 @@ func (c *Controller) handlePhaseCleanupOrphaned(ctx context.Context, inst *lsv1a if next.Status.JobID != inst.Status.JobID { next.Status.JobID = inst.Status.JobID inst.Status.TransitionTimes = lsutil.NewTransitionTimes() - if err = c.Writer().UpdateInstallationStatus(ctx, read_write_layer.W000076, next); err != nil { + if err = c.WriterToLsUncachedClient().UpdateInstallationStatus(ctx, read_write_layer.W000076, next); err != nil { return nil, lserrors.NewWrappedError(err, currentOperation, "UpdateInstallationStatus", err.Error()) } } @@ -396,7 +396,7 @@ func (c *Controller) handlePhaseCleanupOrphaned(ctx context.Context, inst *lsv1a func (c *Controller) handlePhaseObjectsCreated(ctx context.Context, inst *lsv1alpha1.Installation) lserrors.LsError { currentOperation := "handlePhaseObjectsCreated" - subInsts, err := installations.ListSubinstallations(ctx, c.Client(), inst, inst.Status.SubInstCache, read_write_layer.R000089) + subInsts, err := installations.ListSubinstallations(ctx, c.LsUncachedClient(), inst, inst.Status.SubInstCache, read_write_layer.R000089) if err != nil { return lserrors.NewWrappedError(err, currentOperation, "ListSubinstallations", err.Error()) } @@ -406,7 +406,7 @@ func (c *Controller) handlePhaseObjectsCreated(ctx context.Context, inst *lsv1al if next.Status.JobID != inst.Status.JobID { next.Status.JobID = inst.Status.JobID next.Status.TransitionTimes = lsutil.NewTransitionTimes() - if err = c.Writer().UpdateInstallationStatus(ctx, read_write_layer.W000083, next); err != nil { + if err = c.WriterToLsUncachedClient().UpdateInstallationStatus(ctx, read_write_layer.W000083, next); err != nil { return lserrors.NewWrappedError(err, currentOperation, "UpdateInstallationStatus", err.Error()) } } @@ -415,14 +415,14 @@ func (c *Controller) handlePhaseObjectsCreated(ctx context.Context, inst *lsv1al if inst.Status.ExecutionReference != nil { key := client.ObjectKey{Namespace: inst.Status.ExecutionReference.Namespace, Name: inst.Status.ExecutionReference.Name} exec := &lsv1alpha1.Execution{} - if err := read_write_layer.GetExecution(ctx, c.Client(), key, exec, read_write_layer.R000020); err != nil { + if err := read_write_layer.GetExecution(ctx, c.LsUncachedClient(), key, exec, read_write_layer.R000020); err != nil { return lserrors.NewWrappedError(err, currentOperation, "GetExecution", err.Error()) } if exec.Status.JobID != inst.Status.JobID { exec.Status.JobID = inst.Status.JobID exec.Status.TransitionTimes = lsutil.NewTransitionTimes() - if err := c.Writer().UpdateExecutionStatus(ctx, read_write_layer.W000084, exec); err != nil { + if err := c.WriterToLsUncachedClient().UpdateExecutionStatus(ctx, read_write_layer.W000084, exec); err != nil { return lserrors.NewWrappedError(err, currentOperation, "UpdateExecutionStatus", err.Error()) } } @@ -436,7 +436,7 @@ func (c *Controller) handlePhaseProgressing(ctx context.Context, inst *lsv1alpha allSucceeded = true - subInsts, err := installations.ListSubinstallations(ctx, c.Client(), inst, inst.Status.SubInstCache, read_write_layer.R000087) + subInsts, err := installations.ListSubinstallations(ctx, c.LsUncachedClient(), inst, inst.Status.SubInstCache, read_write_layer.R000087) if err != nil { return false, lserrors.NewWrappedError(err, currentOperation, "ListSubinstallations", err.Error()) } @@ -455,7 +455,7 @@ func (c *Controller) handlePhaseProgressing(ctx context.Context, inst *lsv1alpha if inst.Status.ExecutionReference != nil { key := client.ObjectKey{Namespace: inst.Status.ExecutionReference.Namespace, Name: inst.Status.ExecutionReference.Name} exec := &lsv1alpha1.Execution{} - if err := read_write_layer.GetExecution(ctx, c.Client(), key, exec, read_write_layer.R000024); err != nil { + if err := read_write_layer.GetExecution(ctx, c.LsUncachedClient(), key, exec, read_write_layer.R000024); err != nil { return false, lserrors.NewWrappedError(err, currentOperation, "GetExecution", err.Error()) } @@ -558,7 +558,7 @@ func (c *Controller) removeReconcileAnnotation(ctx context.Context, inst *lsv1al logger.Debug("remove reconcile annotation") delete(inst.Annotations, lsv1alpha1.OperationAnnotation) delete(inst.Annotations, lsv1alpha1.ReconcileReasonAnnotation) - if err := c.Writer().UpdateInstallation(ctx, read_write_layer.W000009, inst); client.IgnoreNotFound(err) != nil { + if err := c.WriterToLsUncachedClient().UpdateInstallation(ctx, read_write_layer.W000009, inst); client.IgnoreNotFound(err) != nil { return lserrors.NewWrappedError(err, "RemoveReconcileAnnotation", "UpdateInstallation", err.Error()) } } diff --git a/pkg/landscaper/controllers/installations/reconcile_delete.go b/pkg/landscaper/controllers/installations/reconcile_delete.go index e84419c99..43c539c6d 100644 --- a/pkg/landscaper/controllers/installations/reconcile_delete.go +++ b/pkg/landscaper/controllers/installations/reconcile_delete.go @@ -36,7 +36,7 @@ func (c *Controller) handleDeletionPhaseInit(ctx context.Context, inst *lsv1alph return fatalError, normalError } - exec, err := executions.GetExecutionForInstallation(ctx, c.Client(), inst) + exec, err := executions.GetExecutionForInstallation(ctx, c.LsUncachedClient(), inst) if err != nil { return lserrors.NewWrappedError(err, op, "GetExecutionForInstallation", err.Error()), nil } @@ -45,7 +45,7 @@ func (c *Controller) handleDeletionPhaseInit(ctx context.Context, inst *lsv1alph if lsv1alpha1helper.HasDeleteWithoutUninstallAnnotation(inst.ObjectMeta) && !lsv1alpha1helper.HasDeleteWithoutUninstallAnnotation(exec.ObjectMeta) { metav1.SetMetaDataAnnotation(&exec.ObjectMeta, lsv1alpha1.DeleteWithoutUninstallAnnotation, "true") - if err := c.Writer().UpdateExecution(ctx, read_write_layer.W000102, exec); err != nil { + if err := c.WriterToLsUncachedClient().UpdateExecution(ctx, read_write_layer.W000102, exec); err != nil { if apierrors.IsConflict(err) { return nil, lserrors.NewWrappedError(err, op, "UpdateExecutionConflict", err.Error()) } @@ -54,7 +54,7 @@ func (c *Controller) handleDeletionPhaseInit(ctx context.Context, inst *lsv1alph } if exec.DeletionTimestamp.IsZero() { - if err = c.Writer().DeleteExecution(ctx, read_write_layer.W000012, exec); err != nil { + if err = c.WriterToLsUncachedClient().DeleteExecution(ctx, read_write_layer.W000012, exec); err != nil { if apierrors.IsConflict(err) { return nil, lserrors.NewWrappedError(err, op, "DeleteExecutionConflict", err.Error()) } @@ -63,7 +63,7 @@ func (c *Controller) handleDeletionPhaseInit(ctx context.Context, inst *lsv1alph } } - subInsts, err := installations.ListSubinstallations(ctx, c.Client(), inst, inst.Status.SubInstCache, read_write_layer.R000085) + subInsts, err := installations.ListSubinstallations(ctx, c.LsUncachedClient(), inst, inst.Status.SubInstCache, read_write_layer.R000085) if err != nil { return lserrors.NewWrappedError(err, op, "ListSubinstallations", err.Error()), nil } @@ -72,7 +72,7 @@ func (c *Controller) handleDeletionPhaseInit(ctx context.Context, inst *lsv1alph if lsv1alpha1helper.HasDeleteWithoutUninstallAnnotation(inst.ObjectMeta) && !lsv1alpha1helper.HasDeleteWithoutUninstallAnnotation(subInst.ObjectMeta) { metav1.SetMetaDataAnnotation(&subInst.ObjectMeta, lsv1alpha1.DeleteWithoutUninstallAnnotation, "true") - if err := c.Writer().UpdateInstallation(ctx, read_write_layer.W000103, subInst); err != nil { + if err := c.WriterToLsUncachedClient().UpdateInstallation(ctx, read_write_layer.W000103, subInst); err != nil { if apierrors.IsConflict(err) { return nil, lserrors.NewWrappedError(err, op, "UpdateInstallationConflict", err.Error()) } @@ -81,7 +81,7 @@ func (c *Controller) handleDeletionPhaseInit(ctx context.Context, inst *lsv1alph } if subInst.DeletionTimestamp.IsZero() { - if err = c.Writer().DeleteInstallation(ctx, read_write_layer.W000091, subInst); err != nil { + if err = c.WriterToLsUncachedClient().DeleteInstallation(ctx, read_write_layer.W000091, subInst); err != nil { if apierrors.IsConflict(err) { return nil, lserrors.NewWrappedError(err, op, "DeleteInstallationConflict", err.Error()) } @@ -95,7 +95,7 @@ func (c *Controller) handleDeletionPhaseInit(ctx context.Context, inst *lsv1alph func (c *Controller) handleDeletionPhaseTriggerDeleting(ctx context.Context, inst *lsv1alpha1.Installation) lserrors.LsError { op := "handleDeletionPhaseTriggerDeleting" - exec, err := executions.GetExecutionForInstallation(ctx, c.Client(), inst) + exec, err := executions.GetExecutionForInstallation(ctx, c.LsUncachedClient(), inst) if err != nil { return lserrors.NewWrappedError(err, op, "GetExecutionForInstallation", err.Error()) } @@ -103,12 +103,12 @@ func (c *Controller) handleDeletionPhaseTriggerDeleting(ctx context.Context, ins if exec != nil && exec.Status.JobID != inst.Status.JobID { exec.Status.JobID = inst.Status.JobID exec.Status.TransitionTimes = lsutil.NewTransitionTimes() - if err = c.Writer().UpdateExecutionStatus(ctx, read_write_layer.W000093, exec); err != nil { + if err = c.WriterToLsUncachedClient().UpdateExecutionStatus(ctx, read_write_layer.W000093, exec); err != nil { return lserrors.NewWrappedError(err, op, "UpdateExecutionStatus", err.Error()) } } - subInsts, err := installations.ListSubinstallations(ctx, c.Client(), inst, inst.Status.SubInstCache, read_write_layer.R000088) + subInsts, err := installations.ListSubinstallations(ctx, c.LsUncachedClient(), inst, inst.Status.SubInstCache, read_write_layer.R000088) if err != nil { return lserrors.NewWrappedError(err, op, "ListSubinstallations", err.Error()) } @@ -117,7 +117,7 @@ func (c *Controller) handleDeletionPhaseTriggerDeleting(ctx context.Context, ins if subInst.Status.JobID != inst.Status.JobID { subInst.Status.JobID = inst.Status.JobID subInst.Status.TransitionTimes = lsutil.NewTransitionTimes() - if err = c.Writer().UpdateInstallationStatus(ctx, read_write_layer.W000094, subInst); err != nil { + if err = c.WriterToLsUncachedClient().UpdateInstallationStatus(ctx, read_write_layer.W000094, subInst); err != nil { return lserrors.NewWrappedError(err, op, "UpdateInstallationStatus", err.Error()) } } @@ -130,19 +130,19 @@ func (c *Controller) handleDeletionPhaseDeleting(ctx context.Context, inst *lsv1 op := "handleDeletionPhaseDeleting" logger, ctx := logging.FromContextOrNew(ctx, nil) - exec, err := executions.GetExecutionForInstallation(ctx, c.Client(), inst) + exec, err := executions.GetExecutionForInstallation(ctx, c.LsUncachedClient(), inst) if err != nil { return false, false, lserrors.NewWrappedError(err, op, "GetExecutionForInstallation", err.Error()) } - subInsts, err := installations.ListSubinstallations(ctx, c.Client(), inst, inst.Status.SubInstCache, read_write_layer.R000091) + subInsts, err := installations.ListSubinstallations(ctx, c.LsUncachedClient(), inst, inst.Status.SubInstCache, read_write_layer.R000091) if err != nil { return false, false, lserrors.NewWrappedError(err, op, "ListSubinstallations", err.Error()) } if exec == nil && len(subInsts) == 0 { controllerutil.RemoveFinalizer(inst, lsv1alpha1.LandscaperFinalizer) - if err = c.Writer().UpdateInstallation(ctx, read_write_layer.W000095, inst); err != nil { + if err = c.WriterToLsUncachedClient().UpdateInstallation(ctx, read_write_layer.W000095, inst); err != nil { return false, false, lserrors.NewWrappedError(err, op, "UpdateInstallation", err.Error()) } @@ -150,14 +150,14 @@ func (c *Controller) handleDeletionPhaseDeleting(ctx context.Context, inst *lsv1 // touch siblings to speed up processing // a potential improvement is to only touch siblings exporting data for the current installation but this would // result in more complex coding and should only be done if the current approach results in performance problems - _, siblings, err := installations.GetParentAndSiblings(ctx, c.Client(), inst) + _, siblings, err := installations.GetParentAndSiblings(ctx, c.LsUncachedClient(), inst) if err != nil { return false, false, lserrors.NewWrappedError(err, op, "GetParentAndSiblings", err.Error()) } for _, nextSibling := range siblings { if !nextSibling.DeletionTimestamp.IsZero() { lsv1alpha1helper.Touch(&nextSibling.ObjectMeta) - if err = c.Writer().UpdateInstallation(ctx, read_write_layer.W000147, nextSibling); err != nil { + if err = c.WriterToLsUncachedClient().UpdateInstallation(ctx, read_write_layer.W000147, nextSibling); err != nil { if apierrors.IsConflict(err) { logger.Info(op + " - conflict touching sibling inst") } else if apierrors.IsNotFound(err) { @@ -202,7 +202,7 @@ func (c *Controller) deleteAllowed(ctx context.Context, inst *lsv1alpha1.Install return nil, nil } - _, siblings, err := installations.GetParentAndSiblings(ctx, c.Client(), inst) + _, siblings, err := installations.GetParentAndSiblings(ctx, c.LsUncachedClient(), inst) if err != nil { return nil, lserrors.NewWrappedError(err, op, "CalculateInstallationContext", err.Error(), lsv1alpha1.ErrorInternalProblem) diff --git a/pkg/landscaper/controllers/installations/reconcile_delete_test.go b/pkg/landscaper/controllers/installations/reconcile_delete_test.go index c06fae1cd..8f8f16913 100644 --- a/pkg/landscaper/controllers/installations/reconcile_delete_test.go +++ b/pkg/landscaper/controllers/installations/reconcile_delete_test.go @@ -45,8 +45,9 @@ var _ = Describe("Delete", func() { ) BeforeEach(func() { - op = lsoperation.NewOperation(testenv.Client, api.LandscaperScheme, record.NewFakeRecorder(1024)) - ctrl = installationsctl.NewTestActuator(*op, testenv.Client, logging.Discard(), clock.RealClock{}, + op = lsoperation.NewOperation(api.LandscaperScheme, record.NewFakeRecorder(1024), testenv.Client) + ctrl = installationsctl.NewTestActuator(testenv.Client, testenv.Client, testenv.Client, + *op, logging.Discard(), clock.RealClock{}, &config.LandscaperConfiguration{}, "test-inst1-"+testutils.GetNextCounter()) }) @@ -141,7 +142,8 @@ var _ = Describe("Delete", func() { Expect(err).ToNot(HaveOccurred()) Expect(testutils.CreateExampleDefaultContext(ctx, testenv.Client, state.Namespace)).To(Succeed()) - Expect(installationsctl.AddControllerToManager(logging.Wrap(simplelogger.NewIOLogger(GinkgoWriter)), mgr, mgr, + Expect(installationsctl.AddControllerToManager(mgr.GetClient(), mgr.GetClient(), mgr.GetClient(), mgr.GetClient(), + logging.Wrap(simplelogger.NewIOLogger(GinkgoWriter)), mgr, &config.LandscaperConfiguration{}, "inst-"+testutils.GetNextCounter())).To(Succeed()) go func() { Expect(mgr.Start(ctx)).To(Succeed()) diff --git a/pkg/landscaper/controllers/installations/registry.go b/pkg/landscaper/controllers/installations/registry.go index 1e93f97a6..b8bc8d284 100644 --- a/pkg/landscaper/controllers/installations/registry.go +++ b/pkg/landscaper/controllers/installations/registry.go @@ -44,7 +44,7 @@ func (c *Controller) resolveSecrets(ctx context.Context, secretRefs []lsv1alpha1 for i, secretRef := range secretRefs { secret := corev1.Secret{} // todo: check for cache - if err := c.Client().Get(ctx, secretRef.NamespacedName(), &secret); err != nil { + if err := c.LsUncachedClient().Get(ctx, secretRef.NamespacedName(), &secret); err != nil { return nil, err } secrets[i] = secret diff --git a/pkg/landscaper/controllers/installations/retry_helper_test.go b/pkg/landscaper/controllers/installations/retry_helper_test.go index 2c753d420..4eb376584 100644 --- a/pkg/landscaper/controllers/installations/retry_helper_test.go +++ b/pkg/landscaper/controllers/installations/retry_helper_test.go @@ -37,11 +37,11 @@ var _ = Describe("Retry handler", func() { ) BeforeEach(func() { - op = lsoperation.NewOperation(testenv.Client, api.LandscaperScheme, record.NewFakeRecorder(1024)) + op = lsoperation.NewOperation(api.LandscaperScheme, record.NewFakeRecorder(1024), testenv.Client) clok = &testing.FakePassiveClock{} - ctrl = installationsctl.NewTestActuator(*op, testenv.Client, logging.Discard(), clok, - &config.LandscaperConfiguration{}, "test-inst2-"+testutils.GetNextCounter()) + ctrl = installationsctl.NewTestActuator(testenv.Client, testenv.Client, testenv.Client, *op, + logging.Discard(), clok, &config.LandscaperConfiguration{}, "test-inst2-"+testutils.GetNextCounter()) }) AfterEach(func() { diff --git a/pkg/landscaper/controllers/targetsync/targetsync_controller.go b/pkg/landscaper/controllers/targetsync/targetsync_controller.go index f946f0adc..e0caae15a 100644 --- a/pkg/landscaper/controllers/targetsync/targetsync_controller.go +++ b/pkg/landscaper/controllers/targetsync/targetsync_controller.go @@ -46,31 +46,33 @@ import ( ) // AddControllerToManagerForTargetSyncs adds the controller to the manager -func AddControllerToManagerForTargetSyncs(logger logging.Logger, mgr manager.Manager) error { +func AddControllerToManagerForTargetSyncs(lsUncachedClient, lsCachedClient client.Client, logger logging.Logger, lsMgr manager.Manager) error { log := logger.Reconciles("targetSync", "TargetSync") - ctrl := NewTargetSyncController(log, mgr.GetClient(), clusters.NewDefaultSourceClientProvider()) + ctrl := NewTargetSyncController(lsUncachedClient, lsCachedClient, log, clusters.NewDefaultSourceClientProvider()) predicates := builder.WithPredicates(predicate.Or(predicate.LabelChangedPredicate{}, predicate.GenerationChangedPredicate{}, predicate.AnnotationChangedPredicate{})) - return builder.ControllerManagedBy(mgr). - For(&lsv1alpha1.TargetSync{}, predicates). + return builder.ControllerManagedBy(lsMgr). + For(&lsv1alpha1.TargetSync{}, predicates, builder.OnlyMetadata). WithLogConstructor(func(r *reconcile.Request) logr.Logger { return log.Logr() }). Complete(ctrl) } // TargetSyncController is the TargetSync controller type TargetSyncController struct { + lsUncachedClient client.Client + lsCachedClient client.Client log logging.Logger - targetClient client.Client sourceClientProvider clusters.SourceClientProvider } // NewTargetSyncController returns a new TargetSync controller -func NewTargetSyncController(logger logging.Logger, targetClient client.Client, p clusters.SourceClientProvider) reconcile.Reconciler { +func NewTargetSyncController(lsUncachedClient, lsCachedClient client.Client, logger logging.Logger, p clusters.SourceClientProvider) reconcile.Reconciler { return &TargetSyncController{ + lsUncachedClient: lsUncachedClient, + lsCachedClient: lsCachedClient, log: logger, - targetClient: targetClient, sourceClientProvider: p, } } @@ -80,7 +82,7 @@ func (c *TargetSyncController) Reconcile(ctx context.Context, req reconcile.Requ logger, ctx := c.log.StartReconcileAndAddToContext(ctx, req) targetSync := &lsv1alpha1.TargetSync{} - if err := c.targetClient.Get(ctx, req.NamespacedName, targetSync); err != nil { + if err := c.lsUncachedClient.Get(ctx, req.NamespacedName, targetSync); err != nil { if apierrors.IsNotFound(err) { logger.Info(err.Error()) return reconcile.Result{}, nil @@ -92,7 +94,7 @@ func (c *TargetSyncController) Reconcile(ctx context.Context, req reconcile.Requ // set finalizer if targetSync.DeletionTimestamp.IsZero() && !kutils.HasFinalizer(targetSync, lsv1alpha1.LandscaperFinalizer) { controllerutil.AddFinalizer(targetSync, lsv1alpha1.LandscaperFinalizer) - if err := c.targetClient.Update(ctx, targetSync); err != nil { + if err := c.lsUncachedClient.Update(ctx, targetSync); err != nil { logger.Error(err, "adding finalizer to targetsync object failed") return reconcile.Result{Requeue: true}, nil } @@ -136,7 +138,7 @@ func (c *TargetSyncController) removeReconcileAnnotation(ctx context.Context, ta if helper.HasOperation(targetSync.ObjectMeta, lsv1alpha1.ReconcileOperation) { logger.Debug("remove reconcile annotation from target sync") delete(targetSync.Annotations, lsv1alpha1.OperationAnnotation) - if err := c.targetClient.Update(ctx, targetSync); err != nil { + if err := c.lsUncachedClient.Update(ctx, targetSync); err != nil { return lserrors.NewWrappedError(err, "RemoveReconcileAnnotation", "UpdateTargetSync", err.Error()) } } @@ -157,7 +159,7 @@ func (c *TargetSyncController) handleReconcile(ctx context.Context, targetSync * err = fmt.Errorf("more than one TargetSync object in the same namespace is not allowed") errors = append(errors, err) } else { - sourceClient, restConfig, err := c.sourceClientProvider.GetSourceClient(ctx, targetSync, c.targetClient, nil) + sourceClient, restConfig, err := c.sourceClientProvider.GetSourceClient(ctx, targetSync, c.lsUncachedClient, nil) if err != nil { utils.LogHelper{}.LogErrorButNotFoundAsInfo(ctx, err, "fetching source client for targetsync object failed") errors = append(errors, err) @@ -182,7 +184,7 @@ func (c *TargetSyncController) handleReconcile(ctx context.Context, targetSync * targetSync.Status.ObservedGeneration = targetSync.GetGeneration() targetSync.Status.LastUpdateTime = &now - if err = c.targetClient.Status().Update(ctx, targetSync); err != nil { + if err = c.lsUncachedClient.Status().Update(ctx, targetSync); err != nil { logger.Error(err, "updating status at the end of reconcile of targetsync object failed") return err } @@ -207,7 +209,7 @@ func (c *TargetSyncController) handleDelete(ctx context.Context, targetSync *lsv targetSync.Status.ObservedGeneration = targetSync.GetGeneration() targetSync.Status.LastUpdateTime = &now - if internalErr := c.targetClient.Status().Update(ctx, targetSync); err != nil { + if internalErr := c.lsUncachedClient.Status().Update(ctx, targetSync); err != nil { logger.Error(err, "updating status with error for deleting targetsync object failed") return internalErr } @@ -217,7 +219,7 @@ func (c *TargetSyncController) handleDelete(ctx context.Context, targetSync *lsv logger.Info("deleting targetsync object: removing finalizer") controllerutil.RemoveFinalizer(targetSync, lsv1alpha1.LandscaperFinalizer) - if err := c.targetClient.Update(ctx, targetSync); err != nil { + if err := c.lsUncachedClient.Update(ctx, targetSync); err != nil { logger.Error(err, "removing finalizer for deleting targetsync object failed") return lserrors.NewWrappedError(err, "handleDelete", "RemoveFinalizer", err.Error()) } @@ -284,7 +286,7 @@ func (c *TargetSyncController) handleSecretsAndShoots(ctx context.Context, targe return errors } - shootClient, err := c.sourceClientProvider.GetSourceShootClient(ctx, targetSync, c.targetClient) + shootClient, err := c.sourceClientProvider.GetSourceShootClient(ctx, targetSync, c.lsUncachedClient) if err != nil { logger.Error(err, "failed to get shoot client for targetsync") errors = append(errors, err) @@ -333,7 +335,7 @@ func (c *TargetSyncController) handleSecretsAndShoots(ctx context.Context, targe // do not delete the secret to the source namespace if !c.isTargetSyncSecret(nextOldTarget.Spec.SecretRef.Name, targetSync) { secret := corev1.Secret{ObjectMeta: metav1.ObjectMeta{Namespace: targetSync.Namespace, Name: key}} - if err := c.targetClient.Delete(ctx, &secret); err != nil { + if err := c.lsUncachedClient.Delete(ctx, &secret); err != nil { msg := fmt.Sprintf("deleting old secret %s of targetsync object failed", client.ObjectKeyFromObject(&secret).String()) logger.Error(err, msg) errors = append(errors, err) @@ -341,7 +343,7 @@ func (c *TargetSyncController) handleSecretsAndShoots(ctx context.Context, targe } target := lsv1alpha1.Target{ObjectMeta: metav1.ObjectMeta{Namespace: targetSync.Namespace, Name: key}} - if err := c.targetClient.Delete(ctx, &target); err != nil { + if err := c.lsUncachedClient.Delete(ctx, &target); err != nil { msg := fmt.Sprintf("deleting old target %s of targetsync object failed", client.ObjectKeyFromObject(&target).String()) logger.Error(err, msg) errors = append(errors, err) @@ -407,7 +409,7 @@ func (c *TargetSyncController) isRenewalOfShortLivedKubeconfigDue(ctx context.Co ObjectMeta: controllerruntime.ObjectMeta{Name: targetName, Namespace: targetNamespace}, } - err = c.targetClient.Get(ctx, client.ObjectKeyFromObject(oldTarget), oldTarget) + err = c.lsUncachedClient.Get(ctx, client.ObjectKeyFromObject(oldTarget), oldTarget) if err != nil { if apierrors.IsNotFound(err) { logger.Info("targetsync for shoot is due for the first time") @@ -439,7 +441,7 @@ func (c *TargetSyncController) createOrUpdateTarget(ctx context.Context, targetS ObjectMeta: controllerruntime.ObjectMeta{Name: targetName, Namespace: targetSync.Namespace}, } - _, err := controllerruntime.CreateOrUpdate(ctx, c.targetClient, newTarget, func() error { + _, err := controllerruntime.CreateOrUpdate(ctx, c.lsUncachedClient, newTarget, func() error { newTarget.ObjectMeta.Labels = map[string]string{ labelKeyTargetSync: labelValueOk, } @@ -475,7 +477,7 @@ func (c *TargetSyncController) createOrUpdateSecret(ctx context.Context, targetS ObjectMeta: controllerruntime.ObjectMeta{Name: secret.Name, Namespace: targetSync.Namespace}, } - _, err := controllerruntime.CreateOrUpdate(ctx, c.targetClient, newSecret, func() error { + _, err := controllerruntime.CreateOrUpdate(ctx, c.lsUncachedClient, newSecret, func() error { newSecret.ObjectMeta.Labels = map[string]string{ labelKeyTargetSync: labelValueOk, } @@ -499,7 +501,7 @@ func (c *TargetSyncController) createOrUpdateSecretForShoot(ctx context.Context, return err } - _, err = controllerruntime.CreateOrUpdate(ctx, c.targetClient, newSecret, func() error { + _, err = controllerruntime.CreateOrUpdate(ctx, c.lsUncachedClient, newSecret, func() error { newSecret.ObjectMeta.Labels = map[string]string{ labelKeyTargetSync: labelValueOk, } @@ -517,7 +519,7 @@ func (c *TargetSyncController) removeTargetsAndSecrets(ctx context.Context, targ logger, ctx := logging.FromContextOrNew(ctx, nil) secrets := &corev1.SecretList{} - if err := read_write_layer.ListSecrets(ctx, c.targetClient, secrets, read_write_layer.R000065, + if err := read_write_layer.ListSecrets(ctx, c.lsUncachedClient, secrets, read_write_layer.R000065, client.InNamespace(targetSync.Namespace), client.MatchingLabels{labelKeyTargetSync: labelValueOk}); err != nil { logger.Error(err, "listing secrets for deleting targetsync object failed") @@ -528,7 +530,7 @@ func (c *TargetSyncController) removeTargetsAndSecrets(ctx context.Context, targ if !c.isTargetSyncSecret(secret.Name, targetSync) { secretLogger := logger.WithValues(lc.KeyResource, client.ObjectKeyFromObject(&secret).String()) secretLogger.Info("deleting secret whose targetsync object is being deleted") - if err := c.targetClient.Delete(ctx, &secret); err != nil { + if err := c.lsUncachedClient.Delete(ctx, &secret); err != nil { secretLogger.Error(err, "failed to delete secret whose targetsync object is being deleted") return err } @@ -536,7 +538,7 @@ func (c *TargetSyncController) removeTargetsAndSecrets(ctx context.Context, targ } targets := &lsv1alpha1.TargetList{} - if err := read_write_layer.ListTargets(ctx, c.targetClient, targets, read_write_layer.R000066, + if err := read_write_layer.ListTargets(ctx, c.lsUncachedClient, targets, read_write_layer.R000066, client.InNamespace(targetSync.Namespace), client.MatchingLabels{labelKeyTargetSync: labelValueOk}); err != nil { logger.Error(err, "listing targets for deleting targetsync object failed") @@ -546,7 +548,7 @@ func (c *TargetSyncController) removeTargetsAndSecrets(ctx context.Context, targ for _, target := range targets.Items { targetLogger := logger.WithValues(lc.KeyResource, client.ObjectKeyFromObject(&target).String()) targetLogger.Info("deleting target whose targetsync object is being deleted") - if err := c.targetClient.Delete(ctx, &target); err != nil { + if err := c.lsUncachedClient.Delete(ctx, &target); err != nil { targetLogger.Error(err, "failed to delete target whose targetsync object is being deleted") return err } @@ -559,7 +561,7 @@ func (c *TargetSyncController) fetchTargetSyncs(ctx context.Context, targetSync logger, ctx := logging.FromContextOrNew(ctx, nil) targetSyncs := &lsv1alpha1.TargetSyncList{} - if err := read_write_layer.ListTargetSyncs(ctx, c.targetClient, targetSyncs, read_write_layer.R000067, + if err := read_write_layer.ListTargetSyncs(ctx, c.lsUncachedClient, targetSyncs, read_write_layer.R000067, client.InNamespace(targetSync.Namespace)); err != nil { logger.Error(err, "targetsync failed: could not fetch targetsync list") return nil, err @@ -572,7 +574,7 @@ func (c *TargetSyncController) fetchOldTargets(ctx context.Context, targetSync * logger, ctx := logging.FromContextOrNew(ctx, nil) targets := &lsv1alpha1.TargetList{} - if err := read_write_layer.ListTargets(ctx, c.targetClient, targets, read_write_layer.R000068, + if err := read_write_layer.ListTargets(ctx, c.lsUncachedClient, targets, read_write_layer.R000068, client.InNamespace(targetSync.Namespace), client.MatchingLabels{labelKeyTargetSync: labelValueOk}); err != nil { logger.Error(err, "targetsync failed: old targets could not be fetched") return nil, err @@ -641,7 +643,7 @@ func (c *TargetSyncController) fetchSecretAndKubeconfigObject(ctx context.Contex Name: targetSync.Spec.SecretRef.Name, } - if err := c.targetClient.Get(ctx, secretKey, secret); err != nil { + if err := c.lsUncachedClient.Get(ctx, secretKey, secret); err != nil { return nil, nil, err } @@ -678,7 +680,7 @@ func (c *TargetSyncController) rotateTokenInSecret(ctx context.Context, targetSy secret.Data[targetSync.Spec.SecretRef.Key] = kubeconfigBytes - if err := c.targetClient.Update(ctx, secret); err != nil { + if err := c.lsUncachedClient.Update(ctx, secret); err != nil { return err } diff --git a/pkg/landscaper/controllers/targetsync/targetsync_controller_test.go b/pkg/landscaper/controllers/targetsync/targetsync_controller_test.go index 869716681..c4013d63d 100644 --- a/pkg/landscaper/controllers/targetsync/targetsync_controller_test.go +++ b/pkg/landscaper/controllers/targetsync/targetsync_controller_test.go @@ -34,7 +34,7 @@ var _ = Describe("TargetSync Controller", func() { ) BeforeEach(func() { - ctrl = NewTargetSyncController(logging.Discard(), testenv.Client, clusters.NewTrivialSourceClientProvider(testenv.Client, nil)) + ctrl = NewTargetSyncController(testenv.Client, testenv.Client, logging.Discard(), clusters.NewTrivialSourceClientProvider(testenv.Client, nil)) }) AfterEach(func() { diff --git a/pkg/landscaper/execution/execution.go b/pkg/landscaper/execution/execution.go index bbd20b23d..29d63cc23 100644 --- a/pkg/landscaper/execution/execution.go +++ b/pkg/landscaper/execution/execution.go @@ -155,7 +155,7 @@ func (o *Operation) TriggerDeployItemsForDelete(ctx context.Context) (*DeployIte // If all deploy items have been successfully deleted, remove the finalizer of the execution if classification.AllSucceeded() { controllerutil.RemoveFinalizer(o.exec, lsv1alpha1.LandscaperFinalizer) - err := o.Writer().UpdateExecution(ctx, read_write_layer.W000096, o.exec) + err := o.WriterToLsUncachedClient().UpdateExecution(ctx, read_write_layer.W000096, o.exec) if err != nil { return classification, lserrors.NewWrappedError(err, op, "RemoveFinalizer", err.Error()) } @@ -192,7 +192,7 @@ func (o *Operation) triggerDeployItem(ctx context.Context, di *lsv1alpha1.Deploy key := kutil.ObjectKeyFromObject(di) di = &lsv1alpha1.DeployItem{} - if err := read_write_layer.GetDeployItem(ctx, o.Client(), key, di, read_write_layer.R000034); err != nil { + if err := read_write_layer.GetDeployItem(ctx, o.LsUncachedClient(), key, di, read_write_layer.R000034); err != nil { return lserrors.NewWrappedError(err, op, "GetDeployItem", err.Error()) } @@ -200,7 +200,7 @@ func (o *Operation) triggerDeployItem(ctx context.Context, di *lsv1alpha1.Deploy di.Status.TransitionTimes = utils.NewTransitionTimes() now := metav1.Now() di.Status.JobIDGenerationTime = &now - if err := o.Writer().UpdateDeployItemStatus(ctx, writeId, di); err != nil { + if err := o.WriterToLsUncachedClient().UpdateDeployItemStatus(ctx, writeId, di); err != nil { return lserrors.NewWrappedError(err, op, "UpdateDeployItemStatus", err.Error()) } @@ -223,7 +223,7 @@ func (o *Operation) skipUninstall(ctx context.Context, di *lsv1alpha1.DeployItem } targetSyncs := &lsv1alpha1.TargetSyncList{} - if err := read_write_layer.ListTargetSyncs(ctx, o.Client(), targetSyncs, read_write_layer.R000069, + if err := read_write_layer.ListTargetSyncs(ctx, o.LsUncachedClient(), targetSyncs, read_write_layer.R000069, client.InNamespace(di.GetNamespace())); err != nil { msg := fmt.Sprintf("unable to retrieve targetsync object for namespace%s", di.GetNamespace()) return false, lserrors.NewWrappedError(err, op, msg, err.Error()) @@ -235,7 +235,7 @@ func (o *Operation) skipUninstall(ctx context.Context, di *lsv1alpha1.DeployItem tgs := targetSyncs.Items[0] sourceClientProvider := clusters.NewDefaultSourceClientProvider() - shootClient, err := sourceClientProvider.GetSourceShootClient(ctx, &tgs, o.Client()) + shootClient, err := sourceClientProvider.GetSourceShootClient(ctx, &tgs, o.LsUncachedClient()) if err != nil { return false, lserrors.NewError(op, "GetSourceShootClient", "failed to get shoot client for skipUninstall") } @@ -253,13 +253,13 @@ func (o *Operation) removeFinalizerFromDeployItem(ctx context.Context, di *lsv1a key := kutil.ObjectKeyFromObject(di) di = &lsv1alpha1.DeployItem{} - if err := read_write_layer.GetDeployItem(ctx, o.Client(), key, di, read_write_layer.R000031); err != nil { + if err := read_write_layer.GetDeployItem(ctx, o.LsUncachedClient(), key, di, read_write_layer.R000031); err != nil { return lserrors.NewWrappedError(err, op, "GetDeployItem", err.Error()) } updated := controllerutil.RemoveFinalizer(di, lsv1alpha1.LandscaperFinalizer) if updated { - if err := o.Writer().UpdateDeployItem(ctx, read_write_layer.W000033, di); err != nil { + if err := o.WriterToLsUncachedClient().UpdateDeployItem(ctx, read_write_layer.W000033, di); err != nil { return lserrors.NewWrappedError(err, op, "UpdateDeployItem", err.Error()) } } @@ -286,7 +286,7 @@ func (o *Operation) UpdateStatus(ctx context.Context, updatedConditions ...lsv1a logger, ctx := logging.FromContextOrNew(ctx, nil) o.exec.Status.Conditions = lsv1alpha1helper.MergeConditions(o.exec.Status.Conditions, updatedConditions...) - if err := o.Writer().UpdateExecutionStatus(ctx, read_write_layer.W000032, o.exec); err != nil { + if err := o.WriterToLsUncachedClient().UpdateExecutionStatus(ctx, read_write_layer.W000032, o.exec); err != nil { logger.Error(err, "unable to set installation status") return err } @@ -306,7 +306,7 @@ func (o *Operation) CreateOrUpdateExportReference(ctx context.Context, values in return err } - if _, err := o.Writer().CreateOrUpdateDataObject(ctx, read_write_layer.W000075, raw, func() error { + if _, err := o.WriterToLsUncachedClient().CreateOrUpdateDataObject(ctx, read_write_layer.W000075, raw, func() error { if err := controllerutil.SetOwnerReference(o.exec, raw, api.LandscaperScheme); err != nil { return err } diff --git a/pkg/landscaper/execution/gc.go b/pkg/landscaper/execution/gc.go index e862f5769..d953fc081 100644 --- a/pkg/landscaper/execution/gc.go +++ b/pkg/landscaper/execution/gc.go @@ -27,14 +27,14 @@ func (o *Operation) cleanupOrphanedDeployItemsForNewReconcile(ctx context.Contex itemName, ok := item.Labels[lsv1alpha1.ExecutionManagedNameLabel] if ok { o.exec.Status.ExecutionGenerations = removeExecutionGeneration(o.exec.Status.ExecutionGenerations, itemName) - if err := o.Writer().UpdateExecutionStatus(ctx, read_write_layer.W000146, o.exec); err != nil { + if err := o.WriterToLsUncachedClient().UpdateExecutionStatus(ctx, read_write_layer.W000146, o.exec); err != nil { msg := fmt.Sprintf("unable to patch execution status %s", o.exec.Name) return lserrors.NewWrappedError(err, "cleanupOrphanedDeployItemsForNewReconcile", msg, err.Error()) } } if item.DeletionTimestamp.IsZero() { - if err := o.Writer().DeleteDeployItem(ctx, read_write_layer.W000064, item); err != nil { + if err := o.WriterToLsUncachedClient().DeleteDeployItem(ctx, read_write_layer.W000064, item); err != nil { if !apierrors.IsNotFound(err) { return fmt.Errorf("unable to delete deploy item %s", item.Name) } diff --git a/pkg/landscaper/execution/helper.go b/pkg/landscaper/execution/helper.go index 1f343b2f4..f1f4e628a 100644 --- a/pkg/landscaper/execution/helper.go +++ b/pkg/landscaper/execution/helper.go @@ -62,7 +62,7 @@ func (o *Operation) ListManagedDeployItems(ctx context.Context, readID read_writ for i := range deployItemCache.OrphanedDIs { nextDi := &lsv1alpha1.DeployItem{} key := client.ObjectKey{Namespace: o.exec.Namespace, Name: deployItemCache.OrphanedDIs[i]} - if err := read_write_layer.GetDeployItem(ctx, o.Client(), key, nextDi, readID); err != nil { + if err := read_write_layer.GetDeployItem(ctx, o.LsUncachedClient(), key, nextDi, readID); err != nil { if apierrors.IsNotFound(err) { continue } @@ -74,7 +74,7 @@ func (o *Operation) ListManagedDeployItems(ctx context.Context, readID read_writ for i := range deployItemCache.ActiveDIs { nextDi := &lsv1alpha1.DeployItem{} key := client.ObjectKey{Namespace: o.exec.Namespace, Name: deployItemCache.ActiveDIs[i].ObjectName} - if err := read_write_layer.GetDeployItem(ctx, o.Client(), key, nextDi, readID); err != nil { + if err := read_write_layer.GetDeployItem(ctx, o.LsUncachedClient(), key, nextDi, readID); err != nil { if apierrors.IsNotFound(err) { continue } @@ -86,7 +86,7 @@ func (o *Operation) ListManagedDeployItems(ctx context.Context, readID read_writ return deployItems, nil } else { - deployItemList, err := read_write_layer.ListManagedDeployItems(ctx, o.Client(), client.ObjectKeyFromObject(o.exec), readID) + deployItemList, err := read_write_layer.ListManagedDeployItems(ctx, o.LsUncachedClient(), client.ObjectKeyFromObject(o.exec), readID) if err != nil { return nil, err } diff --git a/pkg/landscaper/execution/reconcile.go b/pkg/landscaper/execution/reconcile.go index 43c9910b0..94bec676a 100644 --- a/pkg/landscaper/execution/reconcile.go +++ b/pkg/landscaper/execution/reconcile.go @@ -47,7 +47,7 @@ func (o *Operation) updateDeployItem(ctx context.Context, item executionItem) (* item.DeployItem.Namespace = o.exec.Namespace } - if _, err := o.Writer().CreateOrUpdateDeployItem(ctx, read_write_layer.W000036, item.DeployItem, func() error { + if _, err := o.WriterToLsUncachedClient().CreateOrUpdateDeployItem(ctx, read_write_layer.W000036, item.DeployItem, func() error { ApplyDeployItemTemplate(item.DeployItem, item.Info) kutil.SetMetaDataLabel(&item.DeployItem.ObjectMeta, lsv1alpha1.ExecutionManagedByLabel, o.exec.Name) item.DeployItem.Spec.Context = o.exec.Spec.Context @@ -71,7 +71,7 @@ func (o *Operation) updateDeployItem(ctx context.Context, item executionItem) (* ref.Reference.ObservedGeneration = item.DeployItem.Generation o.exec.Status.ExecutionGenerations = setExecutionGeneration(o.exec.Status.ExecutionGenerations, item.Info.Name, o.exec.Generation) - if err := o.Writer().UpdateExecutionStatus(ctx, read_write_layer.W000034, o.exec); err != nil { + if err := o.WriterToLsUncachedClient().UpdateExecutionStatus(ctx, read_write_layer.W000034, o.exec); err != nil { msg := fmt.Sprintf("unable to patch execution status %s", o.exec.Name) return nil, lserrors.NewWrappedError(err, op, msg, err.Error()) } @@ -95,7 +95,7 @@ func (o *Operation) getShootClusterName(ctx context.Context, info lsv1alpha1.Dep target := &lsv1alpha1.Target{} targetKey := client.ObjectKey{Namespace: o.exec.Namespace, Name: info.Target.Name} - if err := o.Client().Get(ctx, targetKey, target); err != nil { + if err := o.LsUncachedClient().Get(ctx, targetKey, target); err != nil { msg := fmt.Sprintf("unable to fetch target %s/%s", o.exec.Namespace, info.Target.Name) return "", lserrors.NewWrappedError(err, op, msg, err.Error()) } @@ -104,7 +104,7 @@ func (o *Operation) getShootClusterName(ctx context.Context, info lsv1alpha1.Dep return "", nil } - targetResolver := secret.New(o.Client()) + targetResolver := secret.New(o.LsUncachedClient()) kubeconfigBytes, err := targetResolver.GetKubeconfigFromTarget(ctx, target) if err != nil { msg := fmt.Sprintf("unable to retrieve kubeconfig from target %s/%s", o.exec.Namespace, info.Target.Name) @@ -152,7 +152,7 @@ func (o *Operation) addExports(ctx context.Context, item *lsv1alpha1.DeployItem) return nil, nil } secret := &corev1.Secret{} - if err := o.Client().Get(ctx, item.Status.ExportReference.NamespacedName(), secret); err != nil { + if err := o.LsUncachedClient().Get(ctx, item.Status.ExportReference.NamespacedName(), secret); err != nil { return nil, err } var data map[string]interface{} diff --git a/pkg/landscaper/installations/builder.go b/pkg/landscaper/installations/builder.go index d9b9a6cfb..dbd87ede1 100644 --- a/pkg/landscaper/installations/builder.go +++ b/pkg/landscaper/installations/builder.go @@ -70,8 +70,8 @@ func (b *OperationBuilder) WithContext(ctx *Scope) *OperationBuilder { // operation builder wrapped options // Client sets the kubernetes client. -func (b *OperationBuilder) Client(c client.Client) *OperationBuilder { - b.Builder.Client(c) +func (b *OperationBuilder) WithLsUncachedClient(lsUncachedClient client.Client) *OperationBuilder { + b.Builder.WithLsUncachedClient(lsUncachedClient) return b } @@ -122,7 +122,7 @@ func (b *OperationBuilder) Build(ctx context.Context) (*Operation, error) { } if b.context == nil { - newCtx, err := GetInstallationContext(ctx, instOp.Client(), instOp.Inst.GetInstallation()) + newCtx, err := GetInstallationContext(ctx, instOp.LsUncachedClient(), instOp.Inst.GetInstallation()) if err != nil { return nil, err } diff --git a/pkg/landscaper/installations/context.go b/pkg/landscaper/installations/context.go index 607440bdc..d050505ea 100644 --- a/pkg/landscaper/installations/context.go +++ b/pkg/landscaper/installations/context.go @@ -79,7 +79,7 @@ func (s *Scope) GetSiblings(ctx context.Context, kubeClient client.Client) ([]*I // SetInstallationContext determines the current context and updates the operation context. func (o *Operation) SetInstallationContext(ctx context.Context) error { - newCtx, err := GetInstallationContext(ctx, o.Client(), o.Inst.GetInstallation()) + newCtx, err := GetInstallationContext(ctx, o.LsUncachedClient(), o.Inst.GetInstallation()) if err != nil { return err } diff --git a/pkg/landscaper/installations/context_test.go b/pkg/landscaper/installations/context_test.go index 8453896ec..b1f769e01 100644 --- a/pkg/landscaper/installations/context_test.go +++ b/pkg/landscaper/installations/context_test.go @@ -50,7 +50,7 @@ var _ = Describe("Context", func() { localregistryconfig := &config.LocalRegistryConfiguration{RootPath: "./testdata/registry"} registryAccess, err := registries.GetFactory().NewRegistryAccess(context.Background(), nil, nil, nil, localregistryconfig, nil, nil) Expect(err).ToNot(HaveOccurred()) - op = lsoperation.NewOperation(fakeClient, api.LandscaperScheme, record.NewFakeRecorder(1024)).SetComponentsRegistry(registryAccess) + op = lsoperation.NewOperation(api.LandscaperScheme, record.NewFakeRecorder(1024), fakeClient).SetComponentsRegistry(registryAccess) }) AfterEach(func() { @@ -68,7 +68,7 @@ var _ = Describe("Context", func() { lCtx := instOp.Context() Expect(lCtx.Parent).To(BeNil()) - Expect(lCtx.GetSiblings(ctx, op.Client())).To(HaveLen(0)) + Expect(lCtx.GetSiblings(ctx, op.LsUncachedClient())).To(HaveLen(0)) }) It("should show no parent and one sibling for the test2/a installation", func() { @@ -82,7 +82,7 @@ var _ = Describe("Context", func() { lCtx := instOp.Context() Expect(lCtx.Parent).To(BeNil()) - Expect(lCtx.GetSiblings(ctx, op.Client())).To(HaveLen(1)) + Expect(lCtx.GetSiblings(ctx, op.LsUncachedClient())).To(HaveLen(1)) }) It("should correctly determine the visible context of a installation with its parent and sibling installations", func() { @@ -96,7 +96,7 @@ var _ = Describe("Context", func() { lCtx := instOp.Context() Expect(lCtx.Parent).ToNot(BeNil()) - Expect(lCtx.GetSiblings(ctx, op.Client())).To(HaveLen(3)) + Expect(lCtx.GetSiblings(ctx, op.LsUncachedClient())).To(HaveLen(3)) Expect(lCtx.Parent.GetInstallation().Name).To(Equal("root")) }) @@ -113,7 +113,7 @@ var _ = Describe("Context", func() { instOp, err := installations.NewInstallationOperationFromOperation(ctx, op, inst, &defaultRepoContext) Expect(err).ToNot(HaveOccurred()) - siblings, err := instOp.Context().GetSiblings(ctx, op.Client()) + siblings, err := instOp.Context().GetSiblings(ctx, op.LsUncachedClient()) Expect(err).ToNot(HaveOccurred()) repoContextOfOtherRoot := siblings[0].GetInstallation().Spec.ComponentDescriptor.Reference.RepositoryContext Expect(repoContextOfOtherRoot).ToNot(BeNil()) diff --git a/pkg/landscaper/installations/executions/complete.go b/pkg/landscaper/installations/executions/complete.go index 99e6a25df..9839c7d23 100644 --- a/pkg/landscaper/installations/executions/complete.go +++ b/pkg/landscaper/installations/executions/complete.go @@ -21,7 +21,7 @@ import ( // GetExportedValues returns the exported values of the execution func (o *ExecutionOperation) GetExportedValues(ctx context.Context, inst *installations.InstallationImportsAndBlueprint) (*dataobjects.DataObject, error) { exec := &lsv1alpha1.Execution{} - if err := read_write_layer.GetExecution(ctx, o.Client(), kutil.ObjectKey(inst.GetInstallation().Name, inst.GetInstallation().Namespace), + if err := read_write_layer.GetExecution(ctx, o.LsUncachedClient(), kutil.ObjectKey(inst.GetInstallation().Name, inst.GetInstallation().Namespace), exec, read_write_layer.R000022); err != nil { if apierrors.IsNotFound(err) { return nil, nil @@ -31,7 +31,7 @@ func (o *ExecutionOperation) GetExportedValues(ctx context.Context, inst *instal doName := lsv1alpha1helper.GenerateDataObjectName(lsv1alpha1helper.DataObjectSourceFromExecution(exec), "") rawDO := &lsv1alpha1.DataObject{} - if err := o.Client().Get(ctx, kutil.ObjectKey(doName, o.Inst.GetInstallation().Namespace), rawDO); err != nil { + if err := o.LsUncachedClient().Get(ctx, kutil.ObjectKey(doName, o.Inst.GetInstallation().Namespace), rawDO); err != nil { return nil, err } diff --git a/pkg/landscaper/installations/executions/executions_test.go b/pkg/landscaper/installations/executions/executions_test.go index 813f1b85e..87cdd44c5 100644 --- a/pkg/landscaper/installations/executions/executions_test.go +++ b/pkg/landscaper/installations/executions/executions_test.go @@ -65,7 +65,7 @@ var _ = Describe("DeployItemExecutions", func() { registryAccess, err := registries.GetFactory().NewRegistryAccess(context.Background(), nil, nil, nil, localregistryconfig, nil, nil) Expect(err).ToNot(HaveOccurred()) - operation, err := lsoperation.NewBuilder().Client(fakeClient).Scheme(api.LandscaperScheme).WithEventRecorder(record.NewFakeRecorder(1024)).ComponentRegistry(registryAccess).Build(context.Background()) + operation, err := lsoperation.NewBuilder().WithLsUncachedClient(fakeClient).Scheme(api.LandscaperScheme).WithEventRecorder(record.NewFakeRecorder(1024)).ComponentRegistry(registryAccess).Build(context.Background()) Expect(err).ToNot(HaveOccurred()) op = &installations.Operation{ Operation: operation, diff --git a/pkg/landscaper/installations/executions/operation.go b/pkg/landscaper/installations/executions/operation.go index e6104f950..679fc9f3c 100644 --- a/pkg/landscaper/installations/executions/operation.go +++ b/pkg/landscaper/installations/executions/operation.go @@ -57,10 +57,10 @@ func (o *ExecutionOperation) RenderDeployItemTemplates(ctx context.Context, inst cond := lsv1alpha1helper.GetOrInitCondition(inst.GetInstallation().Status.Conditions, lsv1alpha1.ReconcileExecutionCondition) templateStateHandler := template.KubernetesStateHandler{ - KubeClient: o.Client(), + KubeClient: o.LsUncachedClient(), Inst: inst.GetInstallation(), } - targetResolver := genericresolver.New(o.Client()) + targetResolver := genericresolver.New(o.LsUncachedClient()) tmpl := template.New(gotemplate.New(templateStateHandler, targetResolver), spiff.New(templateStateHandler, targetResolver)) executions, err := tmpl.TemplateDeployExecutions( template.NewDeployExecutionOptions( @@ -166,7 +166,7 @@ func (o *ExecutionOperation) Ensure(ctx context.Context, inst *installations.Ins return err2 } - if _, err := o.Writer().CreateOrUpdateExecution(ctx, read_write_layer.W000022, exec, func() error { + if _, err := o.WriterToLsUncachedClient().CreateOrUpdateExecution(ctx, read_write_layer.W000022, exec, func() error { exec.Spec.Context = inst.GetInstallation().Spec.Context exec.Spec.DeployItems = versionedDeployItemTemplateList diff --git a/pkg/landscaper/installations/executions/operation_test.go b/pkg/landscaper/installations/executions/operation_test.go index 15de2d297..ab9d04195 100644 --- a/pkg/landscaper/installations/executions/operation_test.go +++ b/pkg/landscaper/installations/executions/operation_test.go @@ -98,7 +98,7 @@ var _ = Describe("Execution Operation", func() { }) installationOperation, err := installations.NewOperationBuilder(internalInst). - Client(kClient). + WithLsUncachedClient(kClient). ComponentVersion(componentVersion). ComponentRegistry(registryAccess). WithContext(lsCtx). diff --git a/pkg/landscaper/installations/exports/constructor.go b/pkg/landscaper/installations/exports/constructor.go index cd025e616..bc11a4493 100644 --- a/pkg/landscaper/installations/exports/constructor.go +++ b/pkg/landscaper/installations/exports/constructor.go @@ -78,10 +78,10 @@ func (c *Constructor) Construct(ctx context.Context) ([]*dataobjects.DataObject, internalExports["targets"] = targetsMap stateHdlr := template.KubernetesStateHandler{ - KubeClient: c.Client(), + KubeClient: c.LsUncachedClient(), Inst: c.Inst.GetInstallation(), } - targetResolver := genericresolver.New(c.Client()) + targetResolver := genericresolver.New(c.LsUncachedClient()) tmpl := template.New( gotemplate.New(stateHdlr, targetResolver), @@ -186,7 +186,7 @@ func (c *Constructor) Construct(ctx context.Context) ([]*dataobjects.DataObject, func (c *Constructor) aggregateDataObjectsInContext(ctx context.Context) (map[string]interface{}, error) { installationContext := lsv1alpha1helper.DataObjectSourceFromInstallation(c.Inst.GetInstallation()) dataObjectList := &lsv1alpha1.DataObjectList{} - if err := read_write_layer.ListDataObjects(ctx, c.Client(), dataObjectList, read_write_layer.R000070, + if err := read_write_layer.ListDataObjects(ctx, c.LsUncachedClient(), dataObjectList, read_write_layer.R000070, client.InNamespace(c.Inst.GetInstallation().Namespace), client.MatchingLabels{lsv1alpha1.DataObjectContextLabel: installationContext}); err != nil { return nil, err @@ -207,7 +207,7 @@ func (c *Constructor) aggregateDataObjectsInContext(ctx context.Context) (map[st func (c *Constructor) aggregateTargetsInContext(ctx context.Context) (map[string]interface{}, error) { installationContext := lsv1alpha1helper.DataObjectSourceFromInstallation(c.Inst.GetInstallation()) targetList := &lsv1alpha1.TargetList{} - if err := read_write_layer.ListTargets(ctx, c.Client(), targetList, read_write_layer.R000071, + if err := read_write_layer.ListTargets(ctx, c.LsUncachedClient(), targetList, read_write_layer.R000071, client.InNamespace(c.Inst.GetInstallation().Namespace), client.MatchingLabels{lsv1alpha1.DataObjectContextLabel: installationContext}); err != nil { return nil, err diff --git a/pkg/landscaper/installations/exports/constructor_test.go b/pkg/landscaper/installations/exports/constructor_test.go index 802065a51..28d58a3ac 100644 --- a/pkg/landscaper/installations/exports/constructor_test.go +++ b/pkg/landscaper/installations/exports/constructor_test.go @@ -53,7 +53,7 @@ var _ = Describe("Constructor", func() { registryAccess, err := registries.GetFactory().NewRegistryAccess(context.Background(), nil, nil, nil, localregistryconfig, nil, nil) Expect(err).ToNot(HaveOccurred()) - operation, err := lsoperation.NewBuilder().Client(fakeClient).Scheme(api.LandscaperScheme).WithEventRecorder(record.NewFakeRecorder(1024)).ComponentRegistry(registryAccess).Build(context.Background()) + operation, err := lsoperation.NewBuilder().WithLsUncachedClient(fakeClient).Scheme(api.LandscaperScheme).WithEventRecorder(record.NewFakeRecorder(1024)).ComponentRegistry(registryAccess).Build(context.Background()) Expect(err).ToNot(HaveOccurred()) op = &installations.Operation{ Operation: operation, diff --git a/pkg/landscaper/installations/imports/conditional_imports_test.go b/pkg/landscaper/installations/imports/conditional_imports_test.go index 4f141425b..f3c5e45a3 100644 --- a/pkg/landscaper/installations/imports/conditional_imports_test.go +++ b/pkg/landscaper/installations/imports/conditional_imports_test.go @@ -60,7 +60,7 @@ var _ = Describe("ConditionalImports", func() { registryAccess, err := registries.GetFactory().NewRegistryAccess(context.Background(), nil, nil, nil, localregistryconfig, nil, nil) Expect(err).ToNot(HaveOccurred()) - operation, err := lsoperation.NewBuilder().Client(fakeClient).Scheme(api.LandscaperScheme).WithEventRecorder(record.NewFakeRecorder(1024)).ComponentRegistry(registryAccess).Build(context.Background()) + operation, err := lsoperation.NewBuilder().WithLsUncachedClient(fakeClient).Scheme(api.LandscaperScheme).WithEventRecorder(record.NewFakeRecorder(1024)).ComponentRegistry(registryAccess).Build(context.Background()) Expect(err).ToNot(HaveOccurred()) op = &installations.Operation{ Operation: operation, diff --git a/pkg/landscaper/installations/imports/constructor.go b/pkg/landscaper/installations/imports/constructor.go index acff8ddf1..a50d11bca 100644 --- a/pkg/landscaper/installations/imports/constructor.go +++ b/pkg/landscaper/installations/imports/constructor.go @@ -298,10 +298,10 @@ func (c *Constructor) RenderImportExecutions() error { cond := lsv1alpha1helper.GetOrInitCondition(c.Operation.Inst.GetInstallation().Status.Conditions, lsv1alpha1.ValidateImportsCondition) templateStateHandler := template.KubernetesStateHandler{ - KubeClient: c.Operation.Client(), + KubeClient: c.Operation.LsUncachedClient(), Inst: c.Operation.Inst.GetInstallation(), } - targetResolver := genericresolver.New(c.Operation.Client()) + targetResolver := genericresolver.New(c.Operation.LsUncachedClient()) tmpl := template.New( gotemplate.New(templateStateHandler, targetResolver), spiff.New(templateStateHandler, targetResolver)) diff --git a/pkg/landscaper/installations/imports/constructor_test.go b/pkg/landscaper/installations/imports/constructor_test.go index 1eea8e693..356119d93 100644 --- a/pkg/landscaper/installations/imports/constructor_test.go +++ b/pkg/landscaper/installations/imports/constructor_test.go @@ -51,7 +51,7 @@ var _ = Describe("Constructor", func() { registryAccess, err := registries.GetFactory().NewRegistryAccess(context.Background(), nil, nil, nil, localregistryconfig, nil, nil) Expect(err).ToNot(HaveOccurred()) - operation, err := lsoperation.NewBuilder().Client(fakeClient).Scheme(api.LandscaperScheme).WithEventRecorder(record.NewFakeRecorder(1024)).ComponentRegistry(registryAccess).Build(context.Background()) + operation, err := lsoperation.NewBuilder().WithLsUncachedClient(fakeClient).Scheme(api.LandscaperScheme).WithEventRecorder(record.NewFakeRecorder(1024)).ComponentRegistry(registryAccess).Build(context.Background()) Expect(err).ToNot(HaveOccurred()) op = &installations.Operation{ Operation: operation, diff --git a/pkg/landscaper/installations/imports/importexec_test.go b/pkg/landscaper/installations/imports/importexec_test.go index 2e36b010e..7a92df119 100644 --- a/pkg/landscaper/installations/imports/importexec_test.go +++ b/pkg/landscaper/installations/imports/importexec_test.go @@ -65,7 +65,7 @@ var _ = Describe("ImportExecutions", func() { registryAccess, err := registries.GetFactory().NewRegistryAccess(context.Background(), nil, nil, nil, localregistryconfig, nil, nil) Expect(err).ToNot(HaveOccurred()) - operation, err := lsoperation.NewBuilder().Client(fakeClient).Scheme(api.LandscaperScheme).WithEventRecorder(record.NewFakeRecorder(1024)).ComponentRegistry(registryAccess).Build(context.Background()) + operation, err := lsoperation.NewBuilder().WithLsUncachedClient(fakeClient).Scheme(api.LandscaperScheme).WithEventRecorder(record.NewFakeRecorder(1024)).ComponentRegistry(registryAccess).Build(context.Background()) Expect(err).ToNot(HaveOccurred()) op = &installations.Operation{ Operation: operation, diff --git a/pkg/landscaper/installations/operation.go b/pkg/landscaper/installations/operation.go index b45b81851..4a1a2f241 100644 --- a/pkg/landscaper/installations/operation.go +++ b/pkg/landscaper/installations/operation.go @@ -124,7 +124,7 @@ func (o *Operation) JSONSchemaValidator(schema []byte) (*jsonschema.Validator, e func (o *Operation) ListSubinstallations(ctx context.Context, subInstCache *lsv1alpha1.SubInstCache, readID read_write_layer.ReadID) ([]*lsv1alpha1.Installation, error) { - return ListSubinstallations(ctx, o.Client(), o.Inst.GetInstallation(), subInstCache, readID) + return ListSubinstallations(ctx, o.LsUncachedClient(), o.Inst.GetInstallation(), subInstCache, readID) } type FilterInstallationFunc func(inst *lsv1alpha1.Installation) bool @@ -210,7 +210,7 @@ func (o *Operation) UpdateInstallationStatus(ctx context.Context, inst *lsv1alph logger, ctx := logging.FromContextOrNew(ctx, []interface{}{lc.KeyReconciledResource, client.ObjectKeyFromObject(inst).String()}) inst.Status.Conditions = lsv1alpha1helper.MergeConditions(inst.Status.Conditions, updatedConditions...) - if err := o.Writer().UpdateInstallationStatus(ctx, writeID, inst); err != nil { + if err := o.WriterToLsUncachedClient().UpdateInstallationStatus(ctx, writeID, inst); err != nil { logger.Error(err, "unable to set installation status") return err } @@ -223,7 +223,7 @@ func (o *Operation) GetImportedDataObjects(ctx context.Context) (map[string]*dat dataObjects := map[string]*dataobjects.DataObject{} for _, def := range o.Inst.GetInstallation().Spec.Imports.Data { - do, _, err := GetDataImport(ctx, o.Client(), o.Context().Name, &o.Inst.InstallationAndImports, def) + do, _, err := GetDataImport(ctx, o.LsUncachedClient(), o.Context().Name, &o.Inst.InstallationAndImports, def) if err != nil { return nil, err } @@ -240,7 +240,7 @@ func (o *Operation) GetImportedDataObjects(ctx context.Context) (map[string]*dat Namespace: o.Inst.GetInstallation().Namespace, } inst := &lsv1alpha1.Installation{} - if err := read_write_layer.GetInstallation(ctx, o.Client(), sourceRef.NamespacedName(), inst, read_write_layer.R000008); err != nil { + if err := read_write_layer.GetInstallation(ctx, o.LsUncachedClient(), sourceRef.NamespacedName(), inst, read_write_layer.R000008); err != nil { return nil, fmt.Errorf("unable to get source installation '%s' for import '%s': %w", sourceRef.NamespacedName().String(), def.Name, err) } @@ -278,7 +278,7 @@ func (o *Operation) GetImportedTargets(ctx context.Context) (map[string]*dataobj // It's a target list, skip it continue } - target, err := GetTargetImport(ctx, o.Client(), o.Context().Name, o.Inst.GetInstallation(), def) + target, err := GetTargetImport(ctx, o.LsUncachedClient(), o.Context().Name, o.Inst.GetInstallation(), def) if err != nil { return nil, err } @@ -295,7 +295,7 @@ func (o *Operation) GetImportedTargets(ctx context.Context) (map[string]*dataobj Namespace: o.Inst.GetInstallation().Namespace, } inst := &lsv1alpha1.Installation{} - if err := read_write_layer.GetInstallation(ctx, o.Client(), sourceRef.NamespacedName(), inst, + if err := read_write_layer.GetInstallation(ctx, o.LsUncachedClient(), sourceRef.NamespacedName(), inst, read_write_layer.R000004); err != nil { return nil, fmt.Errorf("unable to get source installation '%s' for import '%s': %w", sourceRef.NamespacedName().String(), def.Name, err) @@ -328,10 +328,10 @@ func (o *Operation) GetImportedTargetLists(ctx context.Context) (map[string]*dat ) if def.Targets != nil { // List of target names - tl, err = GetTargetListImportByNames(ctx, o.Client(), o.Context().Name, o.Inst.GetInstallation(), def) + tl, err = GetTargetListImportByNames(ctx, o.LsUncachedClient(), o.Context().Name, o.Inst.GetInstallation(), def) } else if len(def.TargetListReference) != 0 { // TargetListReference is converted to a label selector internally - tl, err = GetTargetListImportBySelector(ctx, o.Client(), o.Context().Name, o.Inst.GetInstallation(), map[string]string{lsv1alpha1.DataObjectKeyLabel: def.TargetListReference}, def, true) + tl, err = GetTargetListImportBySelector(ctx, o.LsUncachedClient(), o.Context().Name, o.Inst.GetInstallation(), map[string]string{lsv1alpha1.DataObjectKeyLabel: def.TargetListReference}, def, true) } else { // Invalid target err = fmt.Errorf("invalid target definition '%s': none of target, targets and targetListRef is defined", def.Name) @@ -355,7 +355,7 @@ func (o *Operation) GetImportedTargetLists(ctx context.Context) (map[string]*dat Namespace: o.Inst.GetInstallation().Namespace, } inst := &lsv1alpha1.Installation{} - if err := read_write_layer.GetInstallation(ctx, o.Client(), sourceRef.NamespacedName(), inst, read_write_layer.R000011); err != nil { + if err := read_write_layer.GetInstallation(ctx, o.LsUncachedClient(), sourceRef.NamespacedName(), inst, read_write_layer.R000011); err != nil { return nil, fmt.Errorf("unable to get source installation '%s' for import '%s': %w", sourceRef.NamespacedName().String(), def.Name, err) } @@ -419,7 +419,7 @@ func (o *Operation) SetExportConfigGeneration(ctx context.Context) error { // we have to set our config generation to the desired state o.Inst.GetInstallation().Status.ConfigGeneration = "" - return o.Writer().UpdateInstallationStatus(ctx, read_write_layer.W000016, o.Inst.GetInstallation()) + return o.WriterToLsUncachedClient().UpdateInstallationStatus(ctx, read_write_layer.W000016, o.Inst.GetInstallation()) } // CreateOrUpdateExports creates or updates the data objects that holds the exported values of the installation. @@ -448,7 +448,7 @@ func (o *Operation) CreateOrUpdateExports(ctx context.Context, dataExports []*da } // we do not need to set controller ownership as we anyway need a separate garbage collection. - if _, err := o.Writer().CreateOrUpdateCoreDataObject(ctx, read_write_layer.W000068, raw, func() error { + if _, err := o.WriterToLsUncachedClient().CreateOrUpdateCoreDataObject(ctx, read_write_layer.W000068, raw, func() error { if err, err2 := lsutil.SetExclusiveOwnerReference(o.Inst.GetInstallation(), raw); err != nil { return fmt.Errorf("dataobject '%s' for export '%s' conflicts with existing dataobject owned by another installation: %w", client.ObjectKeyFromObject(raw).String(), do.Metadata.Key, err) } else if err2 != nil { @@ -470,7 +470,7 @@ func (o *Operation) CreateOrUpdateExports(ctx context.Context, dataExports []*da target.ApplyNameAndNamespace(targetForUpdate) // we do not need to set controller ownership as we anyway need a separate garbage collection. - if _, err := o.Writer().CreateOrUpdateCoreTarget(ctx, read_write_layer.W000069, targetForUpdate, func() error { + if _, err := o.WriterToLsUncachedClient().CreateOrUpdateCoreTarget(ctx, read_write_layer.W000069, targetForUpdate, func() error { if err, err2 := lsutil.SetExclusiveOwnerReference(o.Inst.GetInstallation(), targetForUpdate); err != nil { return fmt.Errorf("target object '%s' for export '%s' conflicts with existing target owned by another installation: %w", client.ObjectKeyFromObject(targetForUpdate).String(), target.GetMetadata().Key, err) @@ -557,7 +557,7 @@ func (o *Operation) createOrUpdateDataImport(ctx context.Context, src string, im } // we do not need to set controller ownership as we anyway need a separate garbage collection. - if _, err := o.Writer().CreateOrUpdateCoreDataObject(ctx, read_write_layer.W000070, raw, func() error { + if _, err := o.WriterToLsUncachedClient().CreateOrUpdateCoreDataObject(ctx, read_write_layer.W000070, raw, func() error { if err := controllerutil.SetOwnerReference(o.Inst.GetInstallation(), raw, api.LandscaperScheme); err != nil { return err } @@ -594,7 +594,7 @@ func (o *Operation) createOrUpdateTargetImport(ctx context.Context, src string, targetExtension.ApplyNameAndNamespace(targetForUpdate) // we do not need to set controller ownership as we anyway need a separate garbage collection. - if _, err := o.Writer().CreateOrUpdateCoreTarget(ctx, read_write_layer.W000071, targetForUpdate, func() error { + if _, err := o.WriterToLsUncachedClient().CreateOrUpdateCoreTarget(ctx, read_write_layer.W000071, targetForUpdate, func() error { if err := controllerutil.SetOwnerReference(o.Inst.GetInstallation(), targetForUpdate, api.LandscaperScheme); err != nil { return err } @@ -645,7 +645,7 @@ func (o *Operation) createOrUpdateTargetListImport(ctx context.Context, src stri // we do not need to set controller ownership as we anyway need a separate garbage collection. for i, target := range targets { - if _, err := o.Writer().CreateOrUpdateCoreTarget(ctx, read_write_layer.W000072, target, func() error { + if _, err := o.WriterToLsUncachedClient().CreateOrUpdateCoreTarget(ctx, read_write_layer.W000072, target, func() error { if err := controllerutil.SetOwnerReference(o.Inst.GetInstallation(), target, api.LandscaperScheme); err != nil { return err } @@ -666,7 +666,7 @@ func (o *Operation) createOrUpdateTargetListImport(ctx context.Context, src stri func (o *Operation) GetExportForKey(ctx context.Context, key string) (*dataobjects.DataObject, error) { doName := lsv1alpha1helper.GenerateDataObjectName(o.context.Name, key) rawDO := &lsv1alpha1.DataObject{} - if err := o.Client().Get(ctx, kutil.ObjectKey(doName, o.Inst.GetInstallation().Namespace), rawDO); err != nil { + if err := o.LsUncachedClient().Get(ctx, kutil.ObjectKey(doName, o.Inst.GetInstallation().Namespace), rawDO); err != nil { return nil, err } return dataobjects.NewFromDataObject(rawDO) diff --git a/pkg/landscaper/installations/operation_test.go b/pkg/landscaper/installations/operation_test.go index b2c76d2a3..ad9552aca 100644 --- a/pkg/landscaper/installations/operation_test.go +++ b/pkg/landscaper/installations/operation_test.go @@ -35,7 +35,7 @@ var _ = Describe("Operation", func() { BeforeEach(func() { kubeClient = fake.NewClientBuilder().WithScheme(api.LandscaperScheme).WithStatusSubresource(&lsv1alpha1.Installation{}).Build() - commonOp := operation.NewOperation(kubeClient, api.LandscaperScheme, record.NewFakeRecorder(1024)) + commonOp := operation.NewOperation(api.LandscaperScheme, record.NewFakeRecorder(1024), kubeClient) instImportsAndBlueprint := installations.NewInstallationImportsAndBlueprint(&lsv1alpha1.Installation{}, &blueprints.Blueprint{Info: &lsv1alpha1.Blueprint{}}) op = &installations.Operation{ diff --git a/pkg/landscaper/installations/reconcilehelper/reconcilehelper.go b/pkg/landscaper/installations/reconcilehelper/reconcilehelper.go index 3fa17ac5f..5eda60d8a 100644 --- a/pkg/landscaper/installations/reconcilehelper/reconcilehelper.go +++ b/pkg/landscaper/installations/reconcilehelper/reconcilehelper.go @@ -148,7 +148,7 @@ func (rh *ReconcileHelper) fetchParent() error { if rh.Operation.Context().Parent != nil { var err error parent, err = installations.CreateInternalInstallationWithContext(rh.ctx, rh.Operation.Context().Parent.GetInstallation(), - rh.Operation.Client(), rh.Operation.ComponentsRegistry()) + rh.Operation.LsUncachedClient(), rh.Operation.ComponentsRegistry()) if err != nil { return err } @@ -163,7 +163,7 @@ func (rh *ReconcileHelper) getSiblings() (map[string]*installations.Installation return rh.siblingsNew, nil } - rawSiblings, err := rh.Context().GetSiblings(rh.ctx, rh.Client()) + rawSiblings, err := rh.Context().GetSiblings(rh.ctx, rh.LsUncachedClient()) if err != nil { return nil, err } diff --git a/pkg/landscaper/installations/reconcilehelper/validation_test.go b/pkg/landscaper/installations/reconcilehelper/validation_test.go index 4cdcad061..97c74cb8d 100644 --- a/pkg/landscaper/installations/reconcilehelper/validation_test.go +++ b/pkg/landscaper/installations/reconcilehelper/validation_test.go @@ -48,7 +48,7 @@ var _ = Describe("Validation", func() { registryAccess, err := registries.GetFactory().NewRegistryAccess(context.Background(), nil, nil, nil, localregistryconfig, nil, nil) Expect(err).ToNot(HaveOccurred()) - operation, err := lsoperation.NewBuilder().Client(fakeClient).Scheme(api.LandscaperScheme).WithEventRecorder(record.NewFakeRecorder(1024)).ComponentRegistry(registryAccess).Build(context.Background()) + operation, err := lsoperation.NewBuilder().WithLsUncachedClient(fakeClient).Scheme(api.LandscaperScheme).WithEventRecorder(record.NewFakeRecorder(1024)).ComponentRegistry(registryAccess).Build(context.Background()) Expect(err).ToNot(HaveOccurred()) op = &installations.Operation{ Operation: operation, diff --git a/pkg/landscaper/installations/subinstallations/subinstallations.go b/pkg/landscaper/installations/subinstallations/subinstallations.go index 6d8e52bfe..105e2a091 100644 --- a/pkg/landscaper/installations/subinstallations/subinstallations.go +++ b/pkg/landscaper/installations/subinstallations/subinstallations.go @@ -160,7 +160,7 @@ func (o *Operation) cleanupOrphanedSubInstallations(ctx context.Context, metav1.SetMetaDataAnnotation(&subInst.ObjectMeta, lsv1alpha1.DeleteIgnoreSuccessors, "true") - if err := o.Writer().UpdateInstallation(ctx, read_write_layer.W000015, subInst); err != nil { + if err := o.WriterToLsUncachedClient().UpdateInstallation(ctx, read_write_layer.W000015, subInst); err != nil { if apierrors.IsNotFound(err) { continue } @@ -168,7 +168,7 @@ func (o *Operation) cleanupOrphanedSubInstallations(ctx context.Context, return nil, o.NewError(err, "UpdateInstallationDeleteIgnoreSuccessors", err.Error()) } - if err := o.Writer().DeleteInstallation(ctx, read_write_layer.W000021, subInst); err != nil { + if err := o.WriterToLsUncachedClient().DeleteInstallation(ctx, read_write_layer.W000021, subInst); err != nil { if apierrors.IsNotFound(err) { continue } @@ -187,10 +187,10 @@ func (o *Operation) getInstallationTemplates() ([]*lsv1alpha1.InstallationTempla var instTmpls []*lsv1alpha1.InstallationTemplate if len(o.Inst.GetBlueprint().Info.SubinstallationExecutions) != 0 { templateStateHandler := template.KubernetesStateHandler{ - KubeClient: o.Client(), + KubeClient: o.LsUncachedClient(), Inst: o.Inst.GetInstallation(), } - targetResolver := genericresolver.New(o.Client()) + targetResolver := genericresolver.New(o.LsUncachedClient()) tmpl := template.New(gotemplate.New(templateStateHandler, targetResolver), spiff.New(templateStateHandler, targetResolver)) templatedTmpls, err := tmpl.TemplateSubinstallationExecutions(template.NewDeployExecutionOptions( template.NewBlueprintExecutionOptions( @@ -280,7 +280,7 @@ func (o *Operation) createOrUpdateNewInstallation(ctx context.Context, return nil, err } - _, err = o.Writer().CreateOrUpdateInstallation(ctx, read_write_layer.W000001, subInst, func() error { + _, err = o.WriterToLsUncachedClient().CreateOrUpdateInstallation(ctx, read_write_layer.W000001, subInst, func() error { subInst.Labels = map[string]string{ lsv1alpha1.EncompassedByLabel: inst.Name, } diff --git a/pkg/landscaper/installations/subinstallations/subinstallations_test.go b/pkg/landscaper/installations/subinstallations/subinstallations_test.go index a7fd0064b..4389c3fc2 100644 --- a/pkg/landscaper/installations/subinstallations/subinstallations_test.go +++ b/pkg/landscaper/installations/subinstallations/subinstallations_test.go @@ -130,7 +130,7 @@ var _ = Describe("SubInstallation", func() { Expect(err).ToNot(HaveOccurred()) op, err = lsoperation.NewBuilder(). - Client(fakeClient).Scheme(api.LandscaperScheme). + WithLsUncachedClient(fakeClient).Scheme(api.LandscaperScheme). WithEventRecorder(record.NewFakeRecorder(1024)). ComponentRegistry(registryAccess). Build(context.Background()) diff --git a/pkg/landscaper/operation/builder.go b/pkg/landscaper/operation/builder.go index 839ef97d7..4fb69c4b8 100644 --- a/pkg/landscaper/operation/builder.go +++ b/pkg/landscaper/operation/builder.go @@ -18,7 +18,7 @@ import ( // Builder implements the builder-pattern to craft the operation type Builder struct { - client client.Client + lsUncachedClient client.Client scheme *runtime.Scheme eventRecorder record.EventRecorder componentRegistry model.RegistryAccess @@ -30,8 +30,8 @@ func NewBuilder() *Builder { } // Client sets the kubernetes client. -func (b *Builder) Client(c client.Client) *Builder { - b.client = c +func (b *Builder) WithLsUncachedClient(lsUncachedClient client.Client) *Builder { + b.lsUncachedClient = lsUncachedClient return b } @@ -63,7 +63,7 @@ func (b *Builder) applyDefaults(ctx context.Context) { } func (b *Builder) validate() error { - if b.client == nil { + if b.lsUncachedClient == nil { return errors.New("a kubernetes client must be set") } if b.componentRegistry == nil { @@ -80,7 +80,7 @@ func (b *Builder) Build(ctx context.Context) (*Operation, error) { } return &Operation{ - client: b.client, + lsUncachedClient: b.lsUncachedClient, scheme: b.scheme, eventRecorder: b.eventRecorder, componentRegistry: b.componentRegistry, diff --git a/pkg/landscaper/operation/operation.go b/pkg/landscaper/operation/operation.go index 7c640fd9c..b65283758 100644 --- a/pkg/landscaper/operation/operation.go +++ b/pkg/landscaper/operation/operation.go @@ -22,7 +22,7 @@ type RegistriesAccessor interface { // Operation is the type that is used to share common operational data across the landscaper reconciler type Operation struct { - client client.Client + lsUncachedClient client.Client scheme *runtime.Scheme eventRecorder record.EventRecorder componentRegistry model.RegistryAccess @@ -30,18 +30,18 @@ type Operation struct { // NewOperation creates a new internal installation Operation object. // DEPRECATED: use the Builder instead. -func NewOperation(c client.Client, scheme *runtime.Scheme, recorder record.EventRecorder) *Operation { +func NewOperation(scheme *runtime.Scheme, recorder record.EventRecorder, lsUncachedClient client.Client) *Operation { return &Operation{ - client: c, - scheme: scheme, - eventRecorder: recorder, + lsUncachedClient: lsUncachedClient, + scheme: scheme, + eventRecorder: recorder, } } // Copy creates a new operation with the same client, scheme and component resolver func (o *Operation) Copy() *Operation { return &Operation{ - client: o.client, + lsUncachedClient: o.lsUncachedClient, scheme: o.scheme, eventRecorder: o.eventRecorder, componentRegistry: o.componentRegistry, @@ -49,12 +49,12 @@ func (o *Operation) Copy() *Operation { } // Client returns a controller runtime client.Registry -func (o *Operation) Client() client.Client { - return o.client +func (o *Operation) LsUncachedClient() client.Client { + return o.lsUncachedClient } -func (o *Operation) Writer() *read_write_layer.Writer { - return read_write_layer.NewWriter(o.client) +func (o *Operation) WriterToLsUncachedClient() *read_write_layer.Writer { + return read_write_layer.NewWriter(o.lsUncachedClient) } // Scheme returns a kubernetes scheme diff --git a/pkg/utils/constants.go b/pkg/utils/constants.go index 310d095dd..3236745aa 100644 --- a/pkg/utils/constants.go +++ b/pkg/utils/constants.go @@ -1,12 +1,15 @@ package utils import ( + "fmt" "os" + "reflect" "strconv" - "github.com/gardener/landscaper/controller-utils/pkg/logging" + "k8s.io/client-go/rest" lsv1alpha1 "github.com/gardener/landscaper/apis/core/v1alpha1" + "github.com/gardener/landscaper/controller-utils/pkg/logging" ) const ( @@ -64,6 +67,22 @@ func IsExecutionJobIDsIdentical(exec *lsv1alpha1.Execution) bool { return exec.Status.JobID == exec.Status.JobIDFinished } +func RestConfigWithModifiedClientRequestRestrictions(log logging.Logger, restConfig *rest.Config, burst, qps int) *rest.Config { + modifiedRestConfig := *restConfig + + if restConfig.RateLimiter != nil { + log.Info("ClientRequestRestrictions - RateLimiter: " + reflect.TypeOf(restConfig.RateLimiter).String()) + } + log.Info("ClientRequestRestrictions - OldBurst: " + strconv.Itoa(restConfig.Burst)) + log.Info("ClientRequestRestrictions - OldQPS: " + fmt.Sprintf("%v", restConfig.QPS)) + + modifiedRestConfig.RateLimiter = nil + modifiedRestConfig.Burst = burst + modifiedRestConfig.QPS = float32(qps) + + return &modifiedRestConfig +} + func GetHostClientRequestRestrictions(log logging.Logger, hostAndResourceClusterDifferent bool) (int, int) { burst, qps := GetResourceClientRequestRestrictions(log) diff --git a/pkg/utils/finished_object_cache.go b/pkg/utils/finished_object_cache.go new file mode 100644 index 000000000..3c93b637e --- /dev/null +++ b/pkg/utils/finished_object_cache.go @@ -0,0 +1,75 @@ +package utils + +import ( + "sync" + + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type FinishedObjectCache struct { + namespaceObjects map[string]nameResourceVersion + rwLock sync.RWMutex +} + +type nameResourceVersion = map[string]string + +func NewFinishedObjectCache() *FinishedObjectCache { + return &FinishedObjectCache{ + namespaceObjects: map[string]nameResourceVersion{}, + } +} + +func (c *FinishedObjectCache) Add(m *metav1.ObjectMeta) { + nameResourceVersion, ok := c.namespaceObjects[m.Namespace] + + if !ok { + nameResourceVersion = map[string]string{} + c.namespaceObjects[m.Namespace] = nameResourceVersion + } + + nameResourceVersion[m.Name] = m.ResourceVersion +} + +func (c *FinishedObjectCache) IsFinishedAndRemove(m *metav1.PartialObjectMetadata) bool { + c.rwLock.Lock() + defer c.rwLock.Unlock() + + nameResourceVersion, ok := c.namespaceObjects[m.Namespace] + + if !ok { + return false + } + + resourceVersion, ok := nameResourceVersion[m.Name] + if !ok { + return false + } + + delete(nameResourceVersion, m.Name) + + if len(c.namespaceObjects[m.Namespace]) == 0 { + delete(c.namespaceObjects, m.Namespace) + } + + if m.ResourceVersion != resourceVersion { + return false + } + + return true +} + +func (c *FinishedObjectCache) IsContained(req reconcile.Request) bool { + c.rwLock.RLock() + defer c.rwLock.RUnlock() + + nameResourceVersion, ok := c.namespaceObjects[req.Namespace] + + if !ok { + return false + } + + _, ok = nameResourceVersion[req.Name] + return ok +} diff --git a/pkg/utils/performance_measurement.go b/pkg/utils/performance_measurement.go new file mode 100644 index 000000000..8c57852e6 --- /dev/null +++ b/pkg/utils/performance_measurement.go @@ -0,0 +1,38 @@ +package utils + +import ( + "strconv" + "time" + + "github.com/gardener/landscaper/controller-utils/pkg/logging" +) + +const ( + keyDescription = "description" + keyDuration = "duration" + keyDurationMillis = "durationMillis" +) + +type PerformanceMeasurement struct { + log *logging.Logger + description string + startTime time.Time +} + +func StartPerformanceMeasurement(log *logging.Logger, description string) *PerformanceMeasurement { + log.Info("start performance measurement", keyDescription, description) + return &PerformanceMeasurement{ + log: log, + description: description, + startTime: time.Now(), + } +} + +func (p *PerformanceMeasurement) Stop() { + duration := time.Since(p.startTime) + durationMillis := strconv.FormatInt(duration.Milliseconds(), 10) + p.log.Info("stop performance measurement", + keyDescription, p.description, + keyDuration, duration.String(), + keyDurationMillis, durationMillis) +} diff --git a/pkg/utils/read_write_layer/consts.go b/pkg/utils/read_write_layer/consts.go index 3a3e2c42b..f97a231c8 100644 --- a/pkg/utils/read_write_layer/consts.go +++ b/pkg/utils/read_write_layer/consts.go @@ -259,7 +259,17 @@ const ( R000097 ReadID = "r000097" R000098 ReadID = "r000098" R000099 ReadID = "r000099" - R000100 ReadID = "r0000100" + R000100 ReadID = "r000100" + R000101 ReadID = "r000101" + R000102 ReadID = "r000102" + R000103 ReadID = "r000103" + R000104 ReadID = "r000104" + R000105 ReadID = "r000105" + R000106 ReadID = "r000106" + R000107 ReadID = "r000107" + R000108 ReadID = "r000108" + R000109 ReadID = "r000109" + R000110 ReadID = "r000110" ) const ( diff --git a/pkg/utils/read_write_layer/read.go b/pkg/utils/read_write_layer/read.go index 4418e9194..b368c08ed 100644 --- a/pkg/utils/read_write_layer/read.go +++ b/pkg/utils/read_write_layer/read.go @@ -44,6 +44,10 @@ func GetExecution(ctx context.Context, c client.Reader, key client.ObjectKey, ex return get(ctx, c, key, execution, readID, "execution") } +func ListExecutions(ctx context.Context, c client.Reader, executions *lsv1alpha1.ExecutionList, readID ReadID, opts ...client.ListOption) error { + return list(ctx, c, executions, readID, "executions", opts...) +} + // read methods for deploy items func GetDeployItem(ctx context.Context, c client.Reader, key client.ObjectKey, deployItem *lsv1alpha1.DeployItem, readID ReadID) error { return get(ctx, c, key, deployItem, readID, "deployItem") diff --git a/pkg/utils/uncached_client.go b/pkg/utils/uncached_client.go index 6cfb4f9cb..066a78910 100644 --- a/pkg/utils/uncached_client.go +++ b/pkg/utils/uncached_client.go @@ -6,13 +6,41 @@ import ( "strconv" "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/manager" "github.com/gardener/landscaper/controller-utils/pkg/logging" ) +func ClientsFromManagers(lsMgr, hostMgr manager.Manager) ( + lsUncachedClient, + lsCachedClient, + hostUncachedClient, + hostCachedClient client.Client, + err error, +) { + lsUncachedClient, err = NewUncachedClientFromManager(lsMgr) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("unable to build new uncached ls client: %w", err) + } + + lsCachedClient = lsMgr.GetClient() + + hostUncachedClient, err = NewUncachedClientFromManager(hostMgr) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("unable to build new uncached host client: %w", err) + } + + hostCachedClient = hostMgr.GetClient() + + return lsUncachedClient, lsCachedClient, hostUncachedClient, hostCachedClient, nil +} + +func NewUncachedClientFromManager(mgr manager.Manager) (client.Client, error) { + return client.New(mgr.GetConfig(), client.Options{Scheme: mgr.GetScheme()}) +} + func NewUncachedClient(burst, qps int) func(config *rest.Config, options client.Options) (client.Client, error) { return func(config *rest.Config, options client.Options) (client.Client, error) { diff --git a/test/integration/deployers/management/dm_tests.go b/test/integration/deployers/management/dm_tests.go index c1fab548e..f8cd4c3e7 100644 --- a/test/integration/deployers/management/dm_tests.go +++ b/test/integration/deployers/management/dm_tests.go @@ -130,11 +130,12 @@ func DeployerManagementTests(f *framework.Framework) { By("Adding agent with LandscaperNamespace: " + f.LsNamespace) logger := utils.NewLoggerFromTestLogger(f.TestLog()).WithName("dm-test-agent") - err = agent.AddToManager(ctx, logger, mgr, mgr, config.AgentConfiguration{ - Name: "testenv", - Namespace: state.Namespace, - LandscaperNamespace: f.LsNamespace, - }, "dm-test-helm"+testutil.GetNextCounter()) + err = agent.AddToManager(ctx, mgr.GetClient(), mgr.GetClient(), mgr.GetClient(), mgr.GetClient(), + logger, mgr, mgr, config.AgentConfiguration{ + Name: "testenv", + Namespace: state.Namespace, + LandscaperNamespace: f.LsNamespace, + }, "dm-test-helm"+testutil.GetNextCounter()) testutil.ExpectNoError(err) wg = sync.WaitGroup{} diff --git a/test/landscaper/e2e/inlinecd_test.go b/test/landscaper/e2e/inlinecd_test.go index c348b5f5c..b52509973 100644 --- a/test/landscaper/e2e/inlinecd_test.go +++ b/test/landscaper/e2e/inlinecd_test.go @@ -8,6 +8,8 @@ import ( "context" "path/filepath" + "github.com/gardener/landscaper/pkg/utils" + clientlib "sigs.k8s.io/controller-runtime/pkg/client" "github.com/gardener/landscaper/pkg/utils/read_write_layer" @@ -44,20 +46,23 @@ var _ = Describe("Inline Component Descriptor", func() { BeforeEach(func() { var err error - op := operation.NewOperation(testenv.Client, api.LandscaperScheme, record.NewFakeRecorder(1024)) + op := operation.NewOperation(api.LandscaperScheme, record.NewFakeRecorder(1024), testenv.Client) - instActuator = instctlr.NewTestActuator(*op, testenv.Client, logging.Discard(), clock.RealClock{}, + instActuator = instctlr.NewTestActuator(testenv.Client, testenv.Client, testenv.Client, *op, logging.Discard(), clock.RealClock{}, &config.LandscaperConfiguration{ Registry: config.RegistryConfiguration{ Local: &config.LocalRegistryConfiguration{RootPath: filepath.Join(projectRoot, "examples", "01-simple")}, }, }, "test-inst3-"+testutils.GetNextCounter()) - execActuator, err = execctlr.NewController(logging.Discard(), testenv.Client, testenv.Client, api.LandscaperScheme, + execActuator, err = execctlr.NewController(testenv.Client, testenv.Client, testenv.Client, testenv.Client, + logging.Discard(), api.LandscaperScheme, record.NewFakeRecorder(1024), 1000, false, "exec-test-"+testutils.GetNextCounter()) Expect(err).ToNot(HaveOccurred()) - mockActuator, err = mockctlr.NewController(logging.Discard(), testenv.Client, api.LandscaperScheme, + mockActuator, err = mockctlr.NewController(testenv.Client, testenv.Client, testenv.Client, testenv.Client, + utils.NewFinishedObjectCache(), + logging.Discard(), api.LandscaperScheme, record.NewFakeRecorder(1024), mockv1alpha1.Configuration{}, "test-inline"+testutils.GetNextCounter()) Expect(err).ToNot(HaveOccurred()) }) diff --git a/test/landscaper/e2e/simple_test.go b/test/landscaper/e2e/simple_test.go index 4681c2a8b..313c11e36 100644 --- a/test/landscaper/e2e/simple_test.go +++ b/test/landscaper/e2e/simple_test.go @@ -8,6 +8,8 @@ import ( "context" "path/filepath" + "github.com/gardener/landscaper/pkg/utils" + clientlib "sigs.k8s.io/controller-runtime/pkg/client" "github.com/gardener/landscaper/pkg/utils/read_write_layer" @@ -44,19 +46,22 @@ var _ = Describe("Simple", func() { BeforeEach(func() { var err error - op := operation.NewOperation(testenv.Client, api.LandscaperScheme, record.NewFakeRecorder(1024)) + op := operation.NewOperation(api.LandscaperScheme, record.NewFakeRecorder(1024), testenv.Client) - instActuator = instctlr.NewTestActuator(*op, testenv.Client, logging.Discard(), clock.RealClock{}, &config.LandscaperConfiguration{ - Registry: config.RegistryConfiguration{ - Local: &config.LocalRegistryConfiguration{RootPath: filepath.Join(projectRoot, "examples", "01-simple")}, - }, - }, "test-inst4-"+testutils.GetNextCounter()) + instActuator = instctlr.NewTestActuator(testenv.Client, testenv.Client, testenv.Client, *op, logging.Discard(), + clock.RealClock{}, &config.LandscaperConfiguration{ + Registry: config.RegistryConfiguration{ + Local: &config.LocalRegistryConfiguration{RootPath: filepath.Join(projectRoot, "examples", "01-simple")}, + }, + }, "test-inst4-"+testutils.GetNextCounter()) - execActuator, err = execctlr.NewController(logging.Discard(), testenv.Client, testenv.Client, api.LandscaperScheme, + execActuator, err = execctlr.NewController(testenv.Client, testenv.Client, testenv.Client, testenv.Client, logging.Discard(), api.LandscaperScheme, record.NewFakeRecorder(1024), 1000, false, "exec-test-"+testutils.GetNextCounter()) Expect(err).ToNot(HaveOccurred()) - mockActuator, err = mockctlr.NewController(logging.Discard(), testenv.Client, api.LandscaperScheme, + mockActuator, err = mockctlr.NewController(testenv.Client, testenv.Client, testenv.Client, testenv.Client, + utils.NewFinishedObjectCache(), + logging.Discard(), api.LandscaperScheme, record.NewFakeRecorder(1024), mockv1alpha1.Configuration{}, "test-simple"+testutils.GetNextCounter()) Expect(err).ToNot(HaveOccurred()) })