github.com/argoproj-labs/argocd-operator@v0.10.0/controllers/argocd/secret_test.go (about)

     1  package argocd
     2  
     3  import (
     4  	"context"
     5  	"crypto/sha256"
     6  	"fmt"
     7  	argopass "github.com/argoproj/argo-cd/v2/util/password"
     8  	"reflect"
     9  	"sort"
    10  	"testing"
    11  
    12  	configv1 "github.com/openshift/api/config/v1"
    13  	routev1 "github.com/openshift/api/route/v1"
    14  	"github.com/stretchr/testify/assert"
    15  
    16  	corev1 "k8s.io/api/core/v1"
    17  
    18  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    19  	"k8s.io/apimachinery/pkg/runtime"
    20  	"k8s.io/apimachinery/pkg/types"
    21  	"sigs.k8s.io/controller-runtime/pkg/client"
    22  	logf "sigs.k8s.io/controller-runtime/pkg/log"
    23  
    24  	argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1"
    25  	"github.com/argoproj-labs/argocd-operator/common"
    26  	"github.com/argoproj-labs/argocd-operator/controllers/argoutil"
    27  )
    28  
    29  func Test_newCASecret(t *testing.T) {
    30  	cr := &argoproj.ArgoCD{
    31  		ObjectMeta: metav1.ObjectMeta{
    32  			Name:      "test-argocd",
    33  			Namespace: "argocd",
    34  		},
    35  	}
    36  
    37  	s, err := newCASecret(cr)
    38  	if err != nil {
    39  		t.Fatal(err)
    40  	}
    41  	want := []string{
    42  		corev1.ServiceAccountRootCAKey,
    43  		corev1.TLSCertKey,
    44  		corev1.TLSPrivateKeyKey,
    45  	}
    46  	if k := byteMapKeys(s.Data); !reflect.DeepEqual(want, k) {
    47  		t.Fatalf("got %#v, want %#v", k, want)
    48  	}
    49  }
    50  
    51  func byteMapKeys(m map[string][]byte) []string {
    52  	r := []string{}
    53  	for k := range m {
    54  		r = append(r, k)
    55  	}
    56  	sort.Strings(r)
    57  	return r
    58  }
    59  
    60  func Test_ReconcileArgoCD_ReconcileRepoTLSSecret(t *testing.T) {
    61  	argocd := &argoproj.ArgoCD{
    62  		ObjectMeta: metav1.ObjectMeta{
    63  			Name:      "argocd",
    64  			Namespace: "argocd-operator",
    65  			UID:       "abcd",
    66  		},
    67  	}
    68  	crt := []byte("foo")
    69  	key := []byte("bar")
    70  	t.Run("Reconcile TLS secret", func(t *testing.T) {
    71  		service := &corev1.Service{
    72  			ObjectMeta: metav1.ObjectMeta{
    73  				Name:      "argocd-repo-server",
    74  				Namespace: "argocd-operator",
    75  				OwnerReferences: []metav1.OwnerReference{
    76  					{
    77  						APIVersion: "argoproj.io/v1alpha1",
    78  						Kind:       "ArgoCD",
    79  						Name:       "argocd",
    80  						UID:        argocd.GetUID(),
    81  					},
    82  				},
    83  				UID: "service-123",
    84  			},
    85  		}
    86  		secret := &corev1.Secret{
    87  			ObjectMeta: metav1.ObjectMeta{
    88  				Name:      "argocd-repo-server-tls",
    89  				Namespace: "argocd-operator",
    90  				OwnerReferences: []metav1.OwnerReference{
    91  					{
    92  						APIVersion: "v1",
    93  						Kind:       "Service",
    94  						Name:       "argocd-repo-server",
    95  						UID:        service.GetUID(),
    96  					},
    97  				},
    98  			},
    99  			Type: corev1.SecretTypeTLS,
   100  			Data: map[string][]byte{
   101  				corev1.TLSCertKey:       crt,
   102  				corev1.TLSPrivateKeyKey: key,
   103  			},
   104  		}
   105  		var sumOver []byte
   106  		sumOver = append(sumOver, crt...)
   107  		sumOver = append(sumOver, key...)
   108  		shasum := fmt.Sprintf("%x", sha256.Sum256(sumOver))
   109  		serverDepl := newDeploymentWithSuffix("server", "server", argocd)
   110  		repoDepl := newDeploymentWithSuffix("repo-server", "repo-server", argocd)
   111  		ctrlSts := newStatefulSetWithSuffix("application-controller", "application-controller", argocd)
   112  
   113  		resObjs := []client.Object{argocd,
   114  			secret,
   115  			service,
   116  			serverDepl,
   117  			repoDepl,
   118  			ctrlSts}
   119  		subresObjs := []client.Object{argocd,
   120  			serverDepl,
   121  			repoDepl,
   122  			ctrlSts}
   123  		runtimeObjs := []runtime.Object{}
   124  		sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install)
   125  		cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs)
   126  		r := makeTestReconciler(cl, sch)
   127  
   128  		err := r.reconcileRepoServerTLSSecret(argocd)
   129  		if err != nil {
   130  			t.Errorf("Error should be nil, but is %v", err)
   131  		}
   132  		if shasum != argocd.Status.RepoTLSChecksum {
   133  			t.Errorf("Error in SHA256 sum of secret, want=%s got=%s", shasum, argocd.Status.RepoTLSChecksum)
   134  		}
   135  
   136  		// Workloads should have been requested to re-rollout on a change
   137  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-server", Namespace: "argocd-operator"}, serverDepl)
   138  		deplRollout, ok := serverDepl.Spec.Template.ObjectMeta.Labels["repo.tls.cert.changed"]
   139  		if !ok {
   140  			t.Errorf("Expected rollout of argocd-server, but it didn't happen: %v", serverDepl.Spec.Template.ObjectMeta.Labels)
   141  		}
   142  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-repo-server", Namespace: "argocd-operator"}, repoDepl)
   143  		repoRollout, ok := repoDepl.Spec.Template.ObjectMeta.Labels["repo.tls.cert.changed"]
   144  		if !ok {
   145  			t.Errorf("Expected rollout of argocd-repo-server, but it didn't happen: %v", repoDepl.Spec.Template.ObjectMeta.Labels)
   146  		}
   147  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-application-controller", Namespace: "argocd-operator"}, ctrlSts)
   148  		ctrlRollout, ok := ctrlSts.Spec.Template.ObjectMeta.Labels["repo.tls.cert.changed"]
   149  		if !ok {
   150  			t.Errorf("Expected rollout of argocd-application-server, but it didn't happen: %v", ctrlSts.Spec.Template.ObjectMeta.Labels)
   151  		}
   152  
   153  		// Second run - no change
   154  		err = r.reconcileRepoServerTLSSecret(argocd)
   155  		if err != nil {
   156  			t.Errorf("Error should be nil, but is %v", err)
   157  		}
   158  		if shasum != argocd.Status.RepoTLSChecksum {
   159  			t.Errorf("Error in SHA256 sum of secret, want=%s got=%s", shasum, argocd.Status.RepoTLSChecksum)
   160  		}
   161  
   162  		// This time, label should not have changed
   163  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-server", Namespace: "argocd-operator"}, serverDepl)
   164  		deplRolloutNew, ok := serverDepl.Spec.Template.ObjectMeta.Labels["repo.tls.cert.changed"]
   165  		if !ok || deplRollout != deplRolloutNew {
   166  			t.Errorf("Did not expect rollout of argocd-server, but it did happen: %v", serverDepl.Spec.Template.ObjectMeta.Labels)
   167  		}
   168  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-repo-server", Namespace: "argocd-operator"}, repoDepl)
   169  		repoRolloutNew, ok := repoDepl.Spec.Template.ObjectMeta.Labels["repo.tls.cert.changed"]
   170  		if !ok || repoRollout != repoRolloutNew {
   171  			t.Errorf("Did not expect rollout of argocd-repo-server, but it did happen: %v", repoDepl.Spec.Template.ObjectMeta.Labels)
   172  		}
   173  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-application-controller", Namespace: "argocd-operator"}, ctrlSts)
   174  		ctrlRolloutNew, ok := ctrlSts.Spec.Template.ObjectMeta.Labels["repo.tls.cert.changed"]
   175  		if !ok || ctrlRollout != ctrlRolloutNew {
   176  			t.Errorf("Did not expect rollout of argocd-application-server, but it did happen: %v", ctrlSts.Spec.Template.ObjectMeta.Labels)
   177  		}
   178  
   179  		// Update certificate in the secret must trigger new rollout
   180  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-repo-server-tls", Namespace: "argocd-operator"}, secret)
   181  		secret.Data["tls.crt"] = []byte("bar")
   182  		r.Client.Update(context.TODO(), secret)
   183  
   184  		sumOver = []byte{}
   185  		sumOver = append(sumOver, []byte("bar")...)
   186  		sumOver = append(sumOver, key...)
   187  		shasum = fmt.Sprintf("%x", sha256.Sum256(sumOver))
   188  
   189  		// Second run - no change
   190  		err = r.reconcileRepoServerTLSSecret(argocd)
   191  		if err != nil {
   192  			t.Errorf("Error should be nil, but is %v", err)
   193  		}
   194  		if shasum != argocd.Status.RepoTLSChecksum {
   195  			t.Errorf("Error in SHA256 sum of secret, want=%s got=%s", shasum, argocd.Status.RepoTLSChecksum)
   196  		}
   197  
   198  		// This time, label should have changed
   199  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-server", Namespace: "argocd-operator"}, serverDepl)
   200  		deplRolloutNew, ok = serverDepl.Spec.Template.ObjectMeta.Labels["repo.tls.cert.changed"]
   201  		if !ok || deplRollout == deplRolloutNew {
   202  			t.Errorf("Expected rollout of argocd-server, but it didn't happen: %v", serverDepl.Spec.Template.ObjectMeta.Labels)
   203  		}
   204  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-repo-server", Namespace: "argocd-operator"}, repoDepl)
   205  		repoRolloutNew, ok = repoDepl.Spec.Template.ObjectMeta.Labels["repo.tls.cert.changed"]
   206  		if !ok || repoRollout == repoRolloutNew {
   207  			t.Errorf("Expected rollout of argocd-repo-server, but it didn't happen: %v", repoDepl.Spec.Template.ObjectMeta.Labels)
   208  		}
   209  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-application-controller", Namespace: "argocd-operator"}, ctrlSts)
   210  		ctrlRolloutNew, ok = ctrlSts.Spec.Template.ObjectMeta.Labels["repo.tls.cert.changed"]
   211  		if !ok || ctrlRollout == ctrlRolloutNew {
   212  			t.Errorf("Expected rollout of argocd-application-controller, but it didn't happen: %v", ctrlSts.Spec.Template.ObjectMeta.Labels)
   213  		}
   214  
   215  	})
   216  
   217  }
   218  
   219  func Test_ReconcileArgoCD_ReconcileExistingArgoSecret(t *testing.T) {
   220  	argocd := &argoproj.ArgoCD{
   221  		ObjectMeta: metav1.ObjectMeta{
   222  			Name:      "argocd",
   223  			Namespace: "argocd-operator",
   224  		},
   225  	}
   226  
   227  	clusterSecret := argoutil.NewSecretWithSuffix(argocd, "cluster")
   228  	clusterSecret.Data = map[string][]byte{common.ArgoCDKeyAdminPassword: []byte("something")}
   229  	tlsSecret := argoutil.NewSecretWithSuffix(argocd, "tls")
   230  
   231  	resObjs := []client.Object{argocd}
   232  	subresObjs := []client.Object{argocd}
   233  	runtimeObjs := []runtime.Object{}
   234  	sch := makeTestReconcilerScheme(argoproj.AddToScheme)
   235  	cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs)
   236  	r := makeTestReconciler(cl, sch)
   237  
   238  	r.Client.Create(context.TODO(), clusterSecret)
   239  	r.Client.Create(context.TODO(), tlsSecret)
   240  
   241  	err := r.reconcileArgoSecret(argocd)
   242  
   243  	assert.NoError(t, err)
   244  
   245  	testSecret := &corev1.Secret{}
   246  	secretErr := r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-secret", Namespace: "argocd-operator"}, testSecret)
   247  	assert.NoError(t, secretErr)
   248  
   249  	// if you remove the secret.Data it should come back, including the secretKey
   250  	testSecret.Data = nil
   251  	r.Client.Update(context.TODO(), testSecret)
   252  
   253  	_ = r.reconcileExistingArgoSecret(argocd, testSecret, clusterSecret, tlsSecret)
   254  	_ = r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-secret", Namespace: "argocd-operator"}, testSecret)
   255  
   256  	if testSecret.Data == nil {
   257  		t.Errorf("Expected data for data.server but got nothing")
   258  	}
   259  
   260  	if testSecret.Data[common.ArgoCDKeyServerSecretKey] == nil {
   261  		t.Errorf("Expected data for data.server.secretKey but got nothing")
   262  	}
   263  }
   264  
   265  func Test_ReconcileArgoCD_ReconcileShouldNotChangeWhenUpdatedAdminPass(t *testing.T) {
   266  	argocd := &argoproj.ArgoCD{
   267  		ObjectMeta: metav1.ObjectMeta{
   268  			Name:      "argocd",
   269  			Namespace: "argocd-operator",
   270  		},
   271  	}
   272  
   273  	clusterSecret := argoutil.NewSecretWithSuffix(argocd, "cluster")
   274  	clusterSecret.Data = map[string][]byte{common.ArgoCDKeyAdminPassword: []byte("something")}
   275  	tlsSecret := argoutil.NewSecretWithSuffix(argocd, "tls")
   276  
   277  	resObjs := []client.Object{argocd}
   278  	subresObjs := []client.Object{argocd}
   279  	runtimeObjs := []runtime.Object{}
   280  	sch := makeTestReconcilerScheme(argoproj.AddToScheme)
   281  	cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs)
   282  	r := makeTestReconciler(cl, sch)
   283  
   284  	r.Client.Create(context.TODO(), clusterSecret)
   285  	r.Client.Create(context.TODO(), tlsSecret)
   286  
   287  	err := r.reconcileArgoSecret(argocd)
   288  
   289  	assert.NoError(t, err)
   290  
   291  	testSecret := &corev1.Secret{}
   292  	secretErr := r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-secret", Namespace: "argocd-operator"}, testSecret)
   293  	assert.NoError(t, secretErr)
   294  
   295  	// simulating update of argo-cd Admin password from cli or argocd dashboard
   296  	hashedPassword, _ := argopass.HashPassword("updated_password")
   297  	testSecret.Data[common.ArgoCDKeyAdminPassword] = []byte(hashedPassword)
   298  	mTime := nowBytes()
   299  	testSecret.Data[common.ArgoCDKeyAdminPasswordMTime] = mTime
   300  	r.Client.Update(context.TODO(), testSecret)
   301  
   302  	_ = r.reconcileExistingArgoSecret(argocd, testSecret, clusterSecret, tlsSecret)
   303  	_ = r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-secret", Namespace: "argocd-operator"}, testSecret)
   304  
   305  	// checking if reconciliation updates the ArgoCDKeyAdminPassword and ArgoCDKeyAdminPasswordMTime
   306  	if string(testSecret.Data[common.ArgoCDKeyAdminPassword]) != hashedPassword {
   307  		t.Errorf("Expected hashedPassword to reamin unchanged but got updated")
   308  	}
   309  	if string(testSecret.Data[common.ArgoCDKeyAdminPasswordMTime]) != string(mTime) {
   310  		t.Errorf("Expected ArgoCDKeyAdminPasswordMTime to reamin unchanged but got updated")
   311  	}
   312  
   313  	// if you remove the secret.Data it should come back, including the secretKey
   314  	testSecret.Data = nil
   315  	r.Client.Update(context.TODO(), testSecret)
   316  
   317  	_ = r.reconcileExistingArgoSecret(argocd, testSecret, clusterSecret, tlsSecret)
   318  	_ = r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-secret", Namespace: "argocd-operator"}, testSecret)
   319  
   320  	if testSecret.Data == nil {
   321  		t.Errorf("Expected data for data.server but got nothing")
   322  	}
   323  
   324  	if testSecret.Data[common.ArgoCDKeyServerSecretKey] == nil {
   325  		t.Errorf("Expected data for data.server.secretKey but got nothing")
   326  	}
   327  }
   328  
   329  func Test_ReconcileArgoCD_ReconcileRedisTLSSecret(t *testing.T) {
   330  	argocd := &argoproj.ArgoCD{
   331  		ObjectMeta: metav1.ObjectMeta{
   332  			Name:      "argocd",
   333  			Namespace: "argocd-operator",
   334  			UID:       "abcd",
   335  		},
   336  	}
   337  	crt := []byte("foo")
   338  	key := []byte("bar")
   339  	t.Run("Reconcile TLS secret", func(t *testing.T) {
   340  		service := &corev1.Service{
   341  			ObjectMeta: metav1.ObjectMeta{
   342  				Name:      "argocd-redis",
   343  				Namespace: "argocd-operator",
   344  				OwnerReferences: []metav1.OwnerReference{
   345  					{
   346  						APIVersion: "argoproj.io/v1alpha1",
   347  						Kind:       "ArgoCD",
   348  						Name:       "argocd",
   349  						UID:        argocd.GetUID(),
   350  					},
   351  				},
   352  				UID: "service-123",
   353  			},
   354  		}
   355  		secret := &corev1.Secret{
   356  			ObjectMeta: metav1.ObjectMeta{
   357  				Name:      "argocd-operator-redis-tls",
   358  				Namespace: "argocd-operator",
   359  				OwnerReferences: []metav1.OwnerReference{
   360  					{
   361  						APIVersion: "v1",
   362  						Kind:       "Service",
   363  						Name:       "argocd-redis",
   364  						UID:        service.GetUID(),
   365  					},
   366  				},
   367  			},
   368  			Type: corev1.SecretTypeTLS,
   369  			Data: map[string][]byte{
   370  				corev1.TLSCertKey:       crt,
   371  				corev1.TLSPrivateKeyKey: key,
   372  			},
   373  		}
   374  		var sumOver []byte
   375  		sumOver = append(sumOver, crt...)
   376  		sumOver = append(sumOver, key...)
   377  		shasum := fmt.Sprintf("%x", sha256.Sum256(sumOver))
   378  		serverDepl := newDeploymentWithSuffix("server", "server", argocd)
   379  		repoDepl := newDeploymentWithSuffix("repo-server", "repo-server", argocd)
   380  		redisDepl := newDeploymentWithSuffix("redis", "redis", argocd)
   381  		ctrlSts := newStatefulSetWithSuffix("application-controller", "application-controller", argocd)
   382  
   383  		resObjs := []client.Object{argocd,
   384  			secret,
   385  			service,
   386  			serverDepl,
   387  			repoDepl,
   388  			ctrlSts,
   389  			redisDepl}
   390  		subresObjs := []client.Object{argocd,
   391  			serverDepl,
   392  			repoDepl,
   393  			ctrlSts,
   394  			redisDepl}
   395  		runtimeObjs := []runtime.Object{}
   396  		sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install)
   397  		cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs)
   398  		r := makeTestReconciler(cl, sch)
   399  
   400  		err := r.reconcileRedisTLSSecret(argocd, true)
   401  		if err != nil {
   402  			t.Errorf("Error should be nil, but is %v", err)
   403  		}
   404  		if shasum != argocd.Status.RedisTLSChecksum {
   405  			t.Errorf("Error in SHA256 sum of secret, want=%s got=%s", shasum, argocd.Status.RedisTLSChecksum)
   406  		}
   407  
   408  		certChangedLabel := "redis.tls.cert.changed"
   409  
   410  		// Workloads should have been requested to re-rollout on a change
   411  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-server", Namespace: "argocd-operator"}, serverDepl)
   412  		deplRollout, ok := serverDepl.Spec.Template.ObjectMeta.Labels[certChangedLabel]
   413  		if !ok {
   414  			t.Errorf("Expected rollout of argocd-server, but it didn't happen: %v", serverDepl.Spec.Template.ObjectMeta.Labels)
   415  		}
   416  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-repo-server", Namespace: "argocd-operator"}, repoDepl)
   417  		repoRollout, ok := repoDepl.Spec.Template.ObjectMeta.Labels[certChangedLabel]
   418  		if !ok {
   419  			t.Errorf("Expected rollout of argocd-repo-server, but it didn't happen: %v", repoDepl.Spec.Template.ObjectMeta.Labels)
   420  		}
   421  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-redis", Namespace: "argocd-operator"}, redisDepl)
   422  		redisRollout, ok := redisDepl.Spec.Template.ObjectMeta.Labels[certChangedLabel]
   423  		if !ok {
   424  			t.Errorf("Expected rollout of argocd-redis, but it didn't happen: %v", redisDepl.Spec.Template.ObjectMeta.Labels)
   425  		}
   426  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-application-controller", Namespace: "argocd-operator"}, ctrlSts)
   427  		ctrlRollout, ok := ctrlSts.Spec.Template.ObjectMeta.Labels[certChangedLabel]
   428  		if !ok {
   429  			t.Errorf("Expected rollout of argocd-application-server, but it didn't happen: %v", ctrlSts.Spec.Template.ObjectMeta.Labels)
   430  		}
   431  
   432  		// Second run - no change
   433  		err = r.reconcileRedisTLSSecret(argocd, true)
   434  		if err != nil {
   435  			t.Errorf("Error should be nil, but is %v", err)
   436  		}
   437  		if shasum != argocd.Status.RedisTLSChecksum {
   438  			t.Errorf("Error in SHA256 sum of secret, want=%s got=%s", shasum, argocd.Status.RepoTLSChecksum)
   439  		}
   440  
   441  		// This time, label should not have changed
   442  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-server", Namespace: "argocd-operator"}, serverDepl)
   443  		deplRolloutNew, ok := serverDepl.Spec.Template.ObjectMeta.Labels[certChangedLabel]
   444  		if !ok || deplRollout != deplRolloutNew {
   445  			t.Errorf("Did not expect rollout of argocd-server, but it did happen: %v", serverDepl.Spec.Template.ObjectMeta.Labels)
   446  		}
   447  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-repo-server", Namespace: "argocd-operator"}, repoDepl)
   448  		repoRolloutNew, ok := repoDepl.Spec.Template.ObjectMeta.Labels[certChangedLabel]
   449  		if !ok || repoRollout != repoRolloutNew {
   450  			t.Errorf("Did not expect rollout of argocd-repo-server, but it did happen: %v", repoDepl.Spec.Template.ObjectMeta.Labels)
   451  		}
   452  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-redis", Namespace: "argocd-operator"}, redisDepl)
   453  		redisRolloutNew, ok := redisDepl.Spec.Template.ObjectMeta.Labels[certChangedLabel]
   454  		if !ok || redisRollout != redisRolloutNew {
   455  			t.Errorf("Did not expect rollout of argocd-redis, but it did happen: %v", redisDepl.Spec.Template.ObjectMeta.Labels)
   456  		}
   457  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-application-controller", Namespace: "argocd-operator"}, ctrlSts)
   458  		ctrlRolloutNew, ok := ctrlSts.Spec.Template.ObjectMeta.Labels[certChangedLabel]
   459  		if !ok || ctrlRollout != ctrlRolloutNew {
   460  			t.Errorf("Did not expect rollout of argocd-application-server, but it did happen: %v", ctrlSts.Spec.Template.ObjectMeta.Labels)
   461  		}
   462  
   463  		// Update certificate in the secret must trigger new rollout
   464  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-repo-server-tls", Namespace: "argocd-operator"}, secret)
   465  		secret.Data["tls.crt"] = []byte("bar")
   466  		r.Client.Update(context.TODO(), secret)
   467  
   468  		sumOver = []byte{}
   469  		sumOver = append(sumOver, []byte("bar")...)
   470  		sumOver = append(sumOver, key...)
   471  		shasum = fmt.Sprintf("%x", sha256.Sum256(sumOver))
   472  
   473  		// Second run - no change
   474  		err = r.reconcileRedisTLSSecret(argocd, true)
   475  		if err != nil {
   476  			t.Errorf("Error should be nil, but is %v", err)
   477  		}
   478  		if shasum != argocd.Status.RedisTLSChecksum {
   479  			t.Errorf("Error in SHA256 sum of secret, want=%s got=%s", shasum, argocd.Status.RedisTLSChecksum)
   480  		}
   481  
   482  		// This time, label should have changed
   483  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-server", Namespace: "argocd-operator"}, serverDepl)
   484  		deplRolloutNew, ok = serverDepl.Spec.Template.ObjectMeta.Labels[certChangedLabel]
   485  		if !ok || deplRollout == deplRolloutNew {
   486  			t.Errorf("Expected rollout of argocd-server, but it didn't happen: %v", serverDepl.Spec.Template.ObjectMeta.Labels)
   487  		}
   488  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-repo-server", Namespace: "argocd-operator"}, repoDepl)
   489  		repoRolloutNew, ok = repoDepl.Spec.Template.ObjectMeta.Labels[certChangedLabel]
   490  		if !ok || repoRollout == repoRolloutNew {
   491  			t.Errorf("Expected rollout of argocd-repo-server, but it didn't happen: %v", repoDepl.Spec.Template.ObjectMeta.Labels)
   492  		}
   493  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-redis", Namespace: "argocd-operator"}, redisDepl)
   494  		redisRolloutNew, ok = repoDepl.Spec.Template.ObjectMeta.Labels[certChangedLabel]
   495  		if !ok || redisRollout == redisRolloutNew {
   496  			t.Errorf("Expected rollout of argocd-redis, but it didn't happen: %v", redisDepl.Spec.Template.ObjectMeta.Labels)
   497  		}
   498  		r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-application-controller", Namespace: "argocd-operator"}, ctrlSts)
   499  		ctrlRolloutNew, ok = ctrlSts.Spec.Template.ObjectMeta.Labels[certChangedLabel]
   500  		if !ok || ctrlRollout == ctrlRolloutNew {
   501  			t.Errorf("Expected rollout of argocd-application-controller, but it didn't happen: %v", ctrlSts.Spec.Template.ObjectMeta.Labels)
   502  		}
   503  	})
   504  }
   505  
   506  func Test_ReconcileArgoCD_ClusterPermissionsSecret(t *testing.T) {
   507  	logf.SetLogger(ZapLogger(true))
   508  	a := makeTestArgoCD()
   509  
   510  	resObjs := []client.Object{a}
   511  	subresObjs := []client.Object{a}
   512  	runtimeObjs := []runtime.Object{}
   513  	sch := makeTestReconcilerScheme(argoproj.AddToScheme)
   514  	cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs)
   515  	r := makeTestReconciler(cl, sch)
   516  
   517  	assert.NoError(t, createNamespace(r, a.Namespace, ""))
   518  
   519  	testSecret := argoutil.NewSecretWithSuffix(a, "default-cluster-config")
   520  	//assert.ErrorContains(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: testSecret.Name, Namespace: testSecret.Namespace}, testSecret), "not found")
   521  	//TODO: https://github.com/stretchr/testify/pull/1022 introduced ErrorContains, but is not yet available in a tagged release. Revert to ErrorContains once this becomes available
   522  	assert.Error(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: testSecret.Name, Namespace: testSecret.Namespace}, testSecret))
   523  	assert.Contains(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: testSecret.Name, Namespace: testSecret.Namespace}, testSecret).Error(), "not found")
   524  
   525  	assert.NoError(t, r.reconcileClusterPermissionsSecret(a))
   526  	assert.NoError(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: testSecret.Name, Namespace: testSecret.Namespace}, testSecret))
   527  	assert.Equal(t, string(testSecret.Data["namespaces"]), a.Namespace)
   528  
   529  	want := "argocd,someRandomNamespace"
   530  	testSecret.Data["namespaces"] = []byte("someRandomNamespace")
   531  	r.Client.Update(context.TODO(), testSecret)
   532  
   533  	// reconcile to check namespace with the label gets added
   534  	assert.NoError(t, r.reconcileClusterPermissionsSecret(a))
   535  	assert.NoError(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: testSecret.Name, Namespace: testSecret.Namespace}, testSecret))
   536  	assert.Equal(t, string(testSecret.Data["namespaces"]), want)
   537  
   538  	assert.NoError(t, createNamespace(r, "xyz", a.Namespace))
   539  	want = "argocd,someRandomNamespace,xyz"
   540  	// reconcile to check namespace with the label gets added
   541  	assert.NoError(t, r.reconcileClusterPermissionsSecret(a))
   542  	assert.NoError(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: testSecret.Name, Namespace: testSecret.Namespace}, testSecret))
   543  	assert.Equal(t, string(testSecret.Data["namespaces"]), want)
   544  
   545  	t.Setenv("ARGOCD_CLUSTER_CONFIG_NAMESPACES", a.Namespace)
   546  
   547  	assert.NoError(t, r.reconcileClusterPermissionsSecret(a))
   548  	//assert.ErrorContains(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: testSecret.Name, Namespace: testSecret.Namespace}, testSecret), "not found")
   549  	//TODO: https://github.com/stretchr/testify/pull/1022 introduced ErrorContains, but is not yet available in a tagged release. Revert to ErrorContains once this becomes available
   550  	assert.NoError(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: testSecret.Name, Namespace: testSecret.Namespace}, testSecret))
   551  	assert.Nil(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: testSecret.Name, Namespace: testSecret.Namespace}, testSecret))
   552  }