diff --git a/Makefile b/Makefile index 82028c4..38a0826 100644 --- a/Makefile +++ b/Makefile @@ -129,7 +129,7 @@ manifests: $(CONTROLLER_GEN) $(KUSTOMIZE) $(ENVSUBST) fmt generate ## Generate W $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases MANIFEST_IMG=$(CONTROLLER_IMG) MANIFEST_TAG=$(TAG) $(MAKE) set-manifest-image $(KUSTOMIZE) build config/default | $(ENVSUBST) > manifest/manifest.yaml - $(MAKE) shard-deployment + $(if $(LOCAL_MANIFESTS),,$(MAKE) shard-deployment) .PHONY: generate generate: $(CONTROLLER_GEN) ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. diff --git a/cmd/main.go b/cmd/main.go index c7dca06..57b8ec5 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -52,17 +52,20 @@ import ( ) var ( - setupLog = ctrl.Log.WithName("setup") - diagnosticsAddress string - insecureDiagnostics bool - agentInMgmtCluster bool - reportMode controller.ReportMode - tmpReportMode int - restConfigQPS float32 - restConfigBurst int - webhookPort int - syncPeriod time.Duration - healthAddr string + setupLog = ctrl.Log.WithName("setup") + diagnosticsAddress string + insecureDiagnostics bool + agentInMgmtCluster bool + driftDetectionConfig string + sveltosAgentConfig string + sveltosApplierConfig string + reportMode controller.ReportMode + tmpReportMode int + restConfigQPS float32 + restConfigBurst int + webhookPort int + syncPeriod time.Duration + healthAddr string ) const ( @@ -126,11 +129,14 @@ func main() { ctrl.GetConfigOrDie()) if err = (&controller.SveltosClusterReconciler{ - Config: mgr.GetConfig(), - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - AgentInMgmtCluster: agentInMgmtCluster, - ReportMode: reportMode, + Config: mgr.GetConfig(), + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + AgentInMgmtCluster: agentInMgmtCluster, + DriftDetectionConfig: driftDetectionConfig, + SveltosAgentConfig: sveltosAgentConfig, + SveltosApplierConfig: sveltosApplierConfig, + ReportMode: reportMode, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "SveltosCluster") os.Exit(1) @@ -163,6 +169,21 @@ func initFlags(fs *pflag.FlagSet) { false, "flag which is passed to sveltos deployments created for a cluster shard") + fs.StringVar(&driftDetectionConfig, + "drift-detection-config", + "", + "optional config passed to addon-controller deployments created for a cluster shard") + + fs.StringVar(&sveltosAgentConfig, + "sveltos-agent-config", + "", + "optional config passed to classifier deployments created for a cluster shard") + + fs.StringVar(&sveltosApplierConfig, + "sveltos-applier-config", + "", + "optional config passed to classifier deployments created for a cluster shard") + fs.IntVar(&tmpReportMode, "report-mode", defaulReportMode, @@ -220,11 +241,14 @@ func capiWatchers(ctx context.Context, mgr ctrl.Manager, logger logr.Logger) { } else { setupLog.V(logs.LogInfo).Info("CAPI present.") if err = (&controller.ClusterReconciler{ - Config: mgr.GetConfig(), - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - AgentInMgmtCluster: agentInMgmtCluster, - ReportMode: reportMode, + Config: mgr.GetConfig(), + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + AgentInMgmtCluster: agentInMgmtCluster, + DriftDetectionConfig: driftDetectionConfig, + SveltosAgentConfig: sveltosAgentConfig, + SveltosApplierConfig: sveltosApplierConfig, + ReportMode: reportMode, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "Cluster") os.Exit(1) diff --git a/internal/controller/cluster_controller.go b/internal/controller/cluster_controller.go index db0138b..3d8bf02 100644 --- a/internal/controller/cluster_controller.go +++ b/internal/controller/cluster_controller.go @@ -33,9 +33,12 @@ import ( type ClusterReconciler struct { *rest.Config client.Client - Scheme *runtime.Scheme - AgentInMgmtCluster bool - ReportMode ReportMode + Scheme *runtime.Scheme + AgentInMgmtCluster bool + DriftDetectionConfig string + SveltosAgentConfig string + SveltosApplierConfig string + ReportMode ReportMode } //+kubebuilder:rbac:groups=cluster.x-k8s.io,resources=clusters,verbs=get;list;watch @@ -48,7 +51,7 @@ func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct // Fecth the Cluster instance cluster := &clusterv1.Cluster{} return reconcile.Result{}, processCluster(ctx, r.Config, r.Client, r.AgentInMgmtCluster, - cluster, req, logger) + r.DriftDetectionConfig, r.SveltosAgentConfig, r.SveltosApplierConfig, cluster, req, logger) } // SetupWithManager sets up the controller with the Manager. diff --git a/internal/controller/sveltoscluster_controller.go b/internal/controller/sveltoscluster_controller.go index c2875d6..a3dea3c 100644 --- a/internal/controller/sveltoscluster_controller.go +++ b/internal/controller/sveltoscluster_controller.go @@ -33,9 +33,12 @@ import ( type SveltosClusterReconciler struct { *rest.Config client.Client - Scheme *runtime.Scheme - AgentInMgmtCluster bool - ReportMode ReportMode + Scheme *runtime.Scheme + AgentInMgmtCluster bool + DriftDetectionConfig string + SveltosAgentConfig string + SveltosApplierConfig string + ReportMode ReportMode } //+kubebuilder:rbac:groups=lib.projectsveltos.io,resources=sveltosclusters,verbs=get;list;watch @@ -48,7 +51,7 @@ func (r *SveltosClusterReconciler) Reconcile(ctx context.Context, req ctrl.Reque // Fecth the SveltosCluster instance sveltosCluster := &libsveltosv1beta1.SveltosCluster{} return reconcile.Result{}, processCluster(ctx, r.Config, r.Client, r.AgentInMgmtCluster, - sveltosCluster, req, logger) + r.DriftDetectionConfig, r.SveltosAgentConfig, r.SveltosApplierConfig, sveltosCluster, req, logger) } // SetupWithManager sets up the controller with the Manager. diff --git a/internal/controller/utils.go b/internal/controller/utils.go index 7af23a5..5539165 100644 --- a/internal/controller/utils.go +++ b/internal/controller/utils.go @@ -99,7 +99,8 @@ func InitScheme() (*runtime.Scheme, error) { } func processCluster(ctx context.Context, config *rest.Config, c client.Client, - agentInMgmtCluster bool, cluster client.Object, req ctrl.Request, logger logr.Logger) error { + agentInMgmtCluster bool, driftDetectionConfig, sveltosAgentConfig, sveltosApplierConfig string, + cluster client.Object, req ctrl.Request, logger logr.Logger) error { if err := c.Get(ctx, req.NamespacedName, cluster); err != nil { if apierrors.IsNotFound(err) { @@ -136,7 +137,7 @@ func processCluster(ctx context.Context, config *rest.Config, c client.Client, currentShard = annotations[libsveltosv1beta1.ShardAnnotation] } - return trackCluster(ctx, config, c, agentInMgmtCluster, clusterRef, currentShard, logger) + return trackCluster(ctx, config, c, agentInMgmtCluster, driftDetectionConfig, sveltosAgentConfig, sveltosApplierConfig, clusterRef, currentShard, logger) } // trackCluster starts tracking a cluster: @@ -150,7 +151,7 @@ func processCluster(ctx context.Context, config *rest.Config, c client.Client, // cluster moves to currentShardKey, no more clusters are part of old shard, // removes projectsveltos deployments for old shard. func trackCluster(ctx context.Context, config *rest.Config, c client.Client, agentInMgmtCluster bool, - cluster *corev1.ObjectReference, currentShardKey string, logger logr.Logger) error { + driftDetectionConfig, sveltosAgentConfig, sveltosApplierConfig string, cluster *corev1.ObjectReference, currentShardKey string, logger logr.Logger) error { mux.Lock() defer mux.Unlock() @@ -188,7 +189,7 @@ func trackCluster(ctx context.Context, config *rest.Config, c client.Client, age // currentShardKey if shardMap[currentShardKey] == nil || shardMap[currentShardKey].Len() == 0 { logger.V(logs.LogInfo).Info(fmt.Sprintf("first cluster matching shard %q", currentShardKey)) - if err := deployControllers(ctx, c, currentShardKey, agentInMgmtCluster, logger); err != nil { + if err := deployControllers(ctx, c, currentShardKey, agentInMgmtCluster, driftDetectionConfig, sveltosAgentConfig, sveltosApplierConfig, logger); err != nil { return err } } @@ -272,7 +273,7 @@ func addTypeInformationToObject(scheme *runtime.Scheme, obj client.Object) { } func deployControllers(ctx context.Context, c client.Client, shardKey string, //nolint: funlen // deploying sveltos controllers - agentInMgmtCluster bool, logger logr.Logger) error { + agentInMgmtCluster bool, driftDetectionConfig, sveltosAgentConfig, sveltosApplierConfig string, logger logr.Logger) error { if shardKey == "" { // Clusters with no shard annotation are managed by the default projectsveltos deployments @@ -291,6 +292,10 @@ func deployControllers(ctx context.Context, c client.Client, shardKey string, // return err } } + addonControllerTemplate, err = addDriftDetectionConfig(addonControllerTemplate, driftDetectionConfig) + if err != nil { + return err + } err = deployDeployment(ctx, c, addonControllerTemplate, getSveltosNamespace(), shardKey) if err != nil { logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to create addon-controller deployment %v", err)) @@ -305,6 +310,10 @@ func deployControllers(ctx context.Context, c client.Client, shardKey string, // return err } } + classifierTemplate, err = addClassifierConfigs(classifierTemplate, sveltosAgentConfig, sveltosApplierConfig) + if err != nil { + return err + } err = deployDeployment(ctx, c, classifierTemplate, getSveltosNamespace(), shardKey) if err != nil { logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to create classifier deployment %v", err)) @@ -349,6 +358,28 @@ func deployControllers(ctx context.Context, c client.Client, shardKey string, // return nil } +func addDriftDetectionConfig(tmpl []byte, driftDetectionConfig string) ([]byte, error) { + if driftDetectionConfig == "" { + return tmpl, nil + } + return appendArgsToContainer(tmpl, "controller", + map[string]string{"--drift-detection-config": driftDetectionConfig}) +} + +func addClassifierConfigs(tmpl []byte, sveltosAgentConfig, sveltosApplierConfig string) ([]byte, error) { + if sveltosAgentConfig == "" && sveltosApplierConfig == "" { + return tmpl, nil + } + classifierArgsToAdd := make(map[string]string) + if sveltosAgentConfig != "" { + classifierArgsToAdd["--sveltos-agent-config"] = sveltosAgentConfig + } + if sveltosApplierConfig != "" { + classifierArgsToAdd["--sveltos-applier-config"] = sveltosApplierConfig + } + return appendArgsToContainer(tmpl, "manager", classifierArgsToAdd) +} + func undeployControllers(ctx context.Context, config *rest.Config, shardKey string, logger logr.Logger) error { if shardKey == "" { // Clusters with no shard annotation are managed by the default projectsveltos deployments @@ -397,7 +428,7 @@ func undeployControllers(ctx context.Context, config *rest.Config, shardKey stri } func deployDeployment(ctx context.Context, c client.Client, - deploymentTemplate []byte, sveltosNamespace, shardKey string) error { + deploymentTemplate []byte, sveltosNamespace string, shardKey string) error { data, err := instantiateTemplate(deploymentTemplate, shardKey) if err != nil { @@ -423,7 +454,7 @@ func deployDeployment(ctx context.Context, c client.Client, } func undeployDeployment(ctx context.Context, config *rest.Config, - deploymentTemplate []byte, sveltosNamespace, shardKey string) error { + deploymentTemplate []byte, sveltosNamespace string, shardKey string) error { data, err := instantiateTemplate(deploymentTemplate, shardKey) if err != nil { @@ -530,3 +561,39 @@ func setOptions(deplTemplate []byte) ([]byte, error) { // Get the encoded JSON data from the buffer. return buffer.Bytes(), nil } + +func appendArgsToContainer(deplTemplate []byte, containerName string, argsToAdd map[string]string) ([]byte, error) { + u, err := k8s_utils.GetUnstructured(deplTemplate) + if err != nil { + return nil, err + } + + depl := appsv1.Deployment{} + err = runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &depl) + if err != nil { + return nil, err + } + + for flag, value := range argsToAdd { + if value == "" { + continue + } + arg := fmt.Sprintf("%s=%s", flag, value) + + for i := range depl.Spec.Template.Spec.Containers { + if depl.Spec.Template.Spec.Containers[i].Name == containerName { + depl.Spec.Template.Spec.Containers[i].Args = append( + depl.Spec.Template.Spec.Containers[i].Args, arg) + } + } + } + + buffer := bytes.NewBuffer([]byte{}) + encoder := json.NewEncoder(buffer) + err = encoder.Encode(depl) + if err != nil { + return nil, err + } + + return buffer.Bytes(), nil +} diff --git a/internal/controller/utils_test.go b/internal/controller/utils_test.go index 0ad0382..3581762 100644 --- a/internal/controller/utils_test.go +++ b/internal/controller/utils_test.go @@ -76,7 +76,7 @@ var _ = Describe("Utils", func() { // First cluster being registered as part of shardKey Expect(controller.TrackCluster(context.TODO(), testEnv.Config, testEnv.Client, false, - clusterRef, shardKey, logger)).To(BeNil()) + "", "", "", clusterRef, shardKey, logger)).To(BeNil()) currentShard, ok := (*controller.ClusterMap)[*clusterRef] Expect(ok).To(BeTrue()) @@ -93,12 +93,12 @@ var _ = Describe("Utils", func() { // First cluster being registered as part of shardKey Expect(controller.TrackCluster(context.TODO(), testEnv.Config, testEnv.Client, - false, clusterRef, oldShardKey, logger)).To(BeNil()) + false, "", "", "", clusterRef, oldShardKey, logger)).To(BeNil()) verifyClusterIsRegisteredForShard(clusterRef, oldShardKey) // First cluster being registered as part of shardKey Expect(controller.TrackCluster(context.TODO(), testEnv.Config, testEnv.Client, - false, clusterRef, newShardKey, logger)).To(BeNil()) + false, "", "", "", clusterRef, newShardKey, logger)).To(BeNil()) verifyClusterIsRegisteredForShard(clusterRef, newShardKey) // Verify cluster is not registered anymore as matching oldShardKey @@ -119,13 +119,13 @@ var _ = Describe("Utils", func() { // First cluster being registered as part of shardKey Expect(controller.TrackCluster(context.TODO(), testEnv.Config, testEnv.Client, - false, clusterRef, shardKey, logger)).To(BeNil()) + false, "", "", "", clusterRef, shardKey, logger)).To(BeNil()) verifyClusterIsRegisteredForShard(clusterRef, shardKey) // Second cluster being registered as part of shardKey newClusterRef := getClusterRef() Expect(controller.TrackCluster(context.TODO(), testEnv.Config, testEnv.Client, - false, newClusterRef, shardKey, logger)).To(BeNil()) + false, "", "", "", newClusterRef, shardKey, logger)).To(BeNil()) verifyClusterIsRegisteredForShard(newClusterRef, shardKey) }) @@ -136,7 +136,7 @@ var _ = Describe("Utils", func() { // First cluster being registered as part of shardKey Expect(controller.TrackCluster(context.TODO(), testEnv.Config, testEnv.Client, - false, clusterRef, shardKey, logger)).To(BeNil()) + false, "", "", "", clusterRef, shardKey, logger)).To(BeNil()) verifyClusterIsRegisteredForShard(clusterRef, shardKey) Expect(controller.StopTrackingCluster(context.TODO(), testEnv.Config, clusterRef, logger)).To(Succeed()) @@ -158,7 +158,7 @@ var _ = Describe("Utils", func() { // First cluster being registered as part of shardKey Expect(controller.TrackCluster(context.TODO(), testEnv.Config, testEnv.Client, - false, clusterRef, shardKey, logger)).To(BeNil()) + false, "", "", "", clusterRef, shardKey, logger)).To(BeNil()) verifyClusterIsRegisteredForShard(clusterRef, shardKey) Expect(controller.StopTrackingCluster(context.TODO(), testEnv.Config, clusterRef, logger)).To(Succeed()) @@ -216,7 +216,7 @@ var _ = Describe("Utils", func() { Expect(waitForObject(context.TODO(), testEnv.Client, cluster)).To(Succeed()) err := controller.ProcessCluster(context.TODO(), testEnv.Config, testEnv.Client, - false, cluster, req, logger) + false, "", "", "", cluster, req, logger) Expect(err).To(BeNil()) clusterRef := &corev1.ObjectReference{ @@ -241,7 +241,7 @@ var _ = Describe("Utils", func() { }, timeout, pollingInterval).Should(BeTrue()) err = controller.ProcessCluster(context.TODO(), testEnv.Config, testEnv.Client, - false, cluster, req, logger) + false, "", "", "", cluster, req, logger) Expect(err).To(BeNil()) verifyClusterIsRegisteredForShard(clusterRef, "") @@ -286,7 +286,7 @@ var _ = Describe("Utils", func() { // Cluster does not exist err := controller.ProcessCluster(context.TODO(), testEnv.Config, testEnv.Client, - false, cluster, req, logger) + false, "", "", "", cluster, req, logger) Expect(err).To(BeNil()) // Verify cluster is not registered anymore as matching oldShardKey @@ -340,7 +340,7 @@ var _ = Describe("Utils", func() { c := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjects...).Build() Expect(controller.DeployControllers(context.TODO(), c, randomString(), - false, logger)).To(Succeed()) + false, "", "", "", logger)).To(Succeed()) deploymentList := &appsv1.DeploymentList{} listOptions := []client.ListOption{ @@ -364,7 +364,7 @@ var _ = Describe("Utils", func() { currentDeploments := len(deploymentList.Items) Expect(controller.DeployControllers(context.TODO(), testEnv.Client, randomString(), - true, logger)).To(Succeed()) + true, "", "", "", logger)).To(Succeed()) const expectedNewDeployment = 5 // addon-controller, event-manager, healthcheck-manager, // classifier, sveltoscluster-manager @@ -388,7 +388,7 @@ var _ = Describe("Utils", func() { shardKey := randomString() Expect(controller.DeployControllers(context.TODO(), testEnv.Client, shardKey, - false, logger)).To(Succeed()) + false, "", "", "", logger)).To(Succeed()) const expectedDeployment = 5 // addon-controller, event-manager, healthcheck-manager, // classifier, sveltoscluster-manager @@ -410,6 +410,204 @@ var _ = Describe("Utils", func() { return len(deploymentList.Items) == currentDeployments }, timeout, pollingInterval).Should(BeTrue()) }) + + It("deployControllers accepts driftDetectionConfig and sveltosAgentConfig parameters", func() { + driftCfg := "drift-config-value" + agentCfg := "agent-config-value" + applierCfg := "applier-config-value" + shardKey := randomString() + + // Verify deployControllers accepts and processes the config parameters without error + Expect(controller.DeployControllers(context.TODO(), testEnv.Client, shardKey, + false, driftCfg, agentCfg, applierCfg, logger)).To(Succeed()) + + // Verify addon-controller deployment was created with correct shard name + addonDeployment := &appsv1.Deployment{} + err := testEnv.Get(context.TODO(), + types.NamespacedName{ + Namespace: sveltosNamespace, + Name: "addon-controller-" + shardKey, + }, + addonDeployment) + Expect(err).To(BeNil()) + Expect(addonDeployment).ToNot(BeNil()) + Expect(addonDeployment.Spec.Template.Spec.Containers).ToNot(BeEmpty()) + + // Verify classifier deployment was created with correct shard name + classifierDeployment := &appsv1.Deployment{} + err = testEnv.Get(context.TODO(), + types.NamespacedName{ + Namespace: sveltosNamespace, + Name: "classifier-manager-" + shardKey, + }, + classifierDeployment) + Expect(err).To(BeNil()) + Expect(classifierDeployment).ToNot(BeNil()) + Expect(classifierDeployment.Spec.Template.Spec.Containers).ToNot(BeEmpty()) + + // Verify addon deployment has correct config args + addonContainers := addonDeployment.Spec.Template.Spec.Containers + addonArgs := make(map[string]bool) + for _, container := range addonContainers { + for _, arg := range container.Args { + addonArgs[arg] = true + } + } + Expect(addonArgs).To(HaveKey("--drift-detection-config="+driftCfg), + "addon-controller must have --drift-detection-config arg with correct value") + + // Verify classifier deployment has correct config args + classifierContainers := classifierDeployment.Spec.Template.Spec.Containers + classifierArgs := make(map[string]bool) + for _, container := range classifierContainers { + for _, arg := range container.Args { + classifierArgs[arg] = true + } + } + Expect(classifierArgs).To(HaveKey("--sveltos-agent-config="+agentCfg), + "classifier must have --sveltos-agent-config arg with correct value") + Expect(classifierArgs).To(HaveKey("--sveltos-applier-config="+applierCfg), + "classifier must have --sveltos-applier-config arg with correct value") + }) + + It("deployControllers passes correct shard-key to controllers", func() { + listOptions := []client.ListOption{ + client.InNamespace(sveltosNamespace), + } + + deploymentList := &appsv1.DeploymentList{} + Expect(testEnv.List(context.TODO(), deploymentList, listOptions...)).To(Succeed()) + currentDeployments := len(deploymentList.Items) + + shardKey := randomString() + + // Deploy controllers with specific shard key + Expect(controller.DeployControllers(context.TODO(), testEnv.Client, shardKey, + false, "", "", "", logger)).To(Succeed()) + + const expectedDeployment = 5 // addon-controller, event-manager, healthcheck-manager, + // classifier, sveltoscluster-manager + Eventually(func() bool { + err := testEnv.List(context.TODO(), deploymentList, listOptions...) + if err != nil { + return false + } + return len(deploymentList.Items) == expectedDeployment+currentDeployments + }, timeout, pollingInterval).Should(BeTrue()) + + // Verify addon-controller deployment has correct shard key + addonDeployment := &appsv1.Deployment{} + err := testEnv.Get(context.TODO(), + types.NamespacedName{ + Namespace: sveltosNamespace, + Name: "addon-controller-" + shardKey, + }, + addonDeployment) + Expect(err).To(BeNil()) + Expect(addonDeployment).ToNot(BeNil()) + + addonContainers := addonDeployment.Spec.Template.Spec.Containers + addonArgs := make(map[string]bool) + for _, container := range addonContainers { + for _, arg := range container.Args { + addonArgs[arg] = true + } + } + Expect(addonArgs).To(HaveKey("--shard-key="+shardKey), + "addon-controller should have --shard-key arg with correct shard") + + // Verify classifier deployment has correct shard key + classifierDeployment := &appsv1.Deployment{} + err = testEnv.Get(context.TODO(), + types.NamespacedName{ + Namespace: sveltosNamespace, + Name: "classifier-manager-" + shardKey, + }, + classifierDeployment) + Expect(err).To(BeNil()) + Expect(classifierDeployment).ToNot(BeNil()) + + classifierContainers := classifierDeployment.Spec.Template.Spec.Containers + classifierArgs := make(map[string]bool) + for _, container := range classifierContainers { + for _, arg := range container.Args { + classifierArgs[arg] = true + } + } + Expect(classifierArgs).To(HaveKey("--shard-key="+shardKey), + "classifier should have --shard-key arg with correct shard") + }) + + It("deployControllers omits optional args when config values are not provided", func() { + listOptions := []client.ListOption{ + client.InNamespace(sveltosNamespace), + } + + deploymentList := &appsv1.DeploymentList{} + Expect(testEnv.List(context.TODO(), deploymentList, listOptions...)).To(Succeed()) + currentDeployments := len(deploymentList.Items) + + shardKey := randomString() + + // Deploy with empty config values (args should be omitted) + Expect(controller.DeployControllers(context.TODO(), testEnv.Client, shardKey, + false, "", "", "", logger)).To(Succeed()) + + const expectedDeployment = 5 + Eventually(func() bool { + err := testEnv.List(context.TODO(), deploymentList, listOptions...) + if err != nil { + return false + } + return len(deploymentList.Items) == expectedDeployment+currentDeployments + }, timeout, pollingInterval).Should(BeTrue()) + + // Verify addon-controller deployment does not have --drift-detection-config arg + addonDeployment := &appsv1.Deployment{} + err := testEnv.Get(context.TODO(), + types.NamespacedName{ + Namespace: sveltosNamespace, + Name: "addon-controller-" + shardKey, + }, + addonDeployment) + Expect(err).To(BeNil()) + + addonArgs := make(map[string]bool) + for _, container := range addonDeployment.Spec.Template.Spec.Containers { + for _, arg := range container.Args { + addonArgs[arg] = true + } + } + // Check that drift-detection-config arg is NOT present + for arg := range addonArgs { + Expect(arg).ToNot(ContainSubstring("--drift-detection-config"), + "addon-controller should not have --drift-detection-config arg when not provided") + } + + // Verify classifier deployment does not have sveltos config args + classifierDeployment := &appsv1.Deployment{} + err = testEnv.Get(context.TODO(), + types.NamespacedName{ + Namespace: sveltosNamespace, + Name: "classifier-manager-" + shardKey, + }, + classifierDeployment) + Expect(err).To(BeNil()) + + classifierArgs := make(map[string]bool) + for _, container := range classifierDeployment.Spec.Template.Spec.Containers { + for _, arg := range container.Args { + classifierArgs[arg] = true + } + } + // Check that sveltos config args are NOT present + for arg := range classifierArgs { + Expect(arg).ToNot(ContainSubstring("--sveltos-agent-config"), + "classifier should not have --sveltos-agent-config arg when not provided") + Expect(arg).ToNot(ContainSubstring("--sveltos-applier-config"), + "classifier should not have --sveltos-applier-config arg when not provided") + } + }) }) func getClusterRef() *corev1.ObjectReference {