Skip to content

Commit 8a023e1

Browse files
committed
chore: add additional E2E tests for local user management
Signed-off-by: Jonathan West <jonwest@redhat.com>
1 parent 2a10f87 commit 8a023e1

File tree

3 files changed

+197
-16
lines changed

3 files changed

+197
-16
lines changed

tests/ginkgo/fixture/secret/fixture.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,16 @@ func HaveDataKeyValue(key string, value []byte) matcher.GomegaMatcher {
9898

9999
}
100100

101+
// NotHaveDataKey returns true if Secret's .data 'key' does not exist, false otherwise
102+
func NotHaveDataKey(key string) matcher.GomegaMatcher {
103+
return fetchSecret(func(secret *corev1.Secret) bool {
104+
_, exists := secret.Data[key]
105+
GinkgoWriter.Println("NotHaveDataKey - key:", key, "Exists:", exists)
106+
return !exists
107+
})
108+
109+
}
110+
101111
// This is intentionally NOT exported, for now. Create another function in this file/package that calls this function, and export that.
102112
func fetchSecret(f func(*corev1.Secret) bool) matcher.GomegaMatcher {
103113

tests/ginkgo/parallel/1-052_validate_local_user_management_test.go

Lines changed: 186 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,17 @@ import (
2323
. "github.com/onsi/gomega"
2424
corev1 "k8s.io/api/core/v1"
2525
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26+
"k8s.io/apimachinery/pkg/util/uuid"
27+
"k8s.io/utils/ptr"
2628
"sigs.k8s.io/controller-runtime/pkg/client"
2729

2830
argov1beta1api "github.com/argoproj-labs/argocd-operator/api/v1beta1"
2931
"github.com/argoproj-labs/argocd-operator/tests/ginkgo/fixture"
3032
argocdFixture "github.com/argoproj-labs/argocd-operator/tests/ginkgo/fixture/argocd"
33+
"github.com/argoproj-labs/argocd-operator/tests/ginkgo/fixture/configmap"
3134
configmapFixture "github.com/argoproj-labs/argocd-operator/tests/ginkgo/fixture/configmap"
3235
k8sFixture "github.com/argoproj-labs/argocd-operator/tests/ginkgo/fixture/k8s"
33-
"github.com/argoproj-labs/argocd-operator/tests/ginkgo/fixture/secret"
36+
secretFixture "github.com/argoproj-labs/argocd-operator/tests/ginkgo/fixture/secret"
3437
fixtureUtils "github.com/argoproj-labs/argocd-operator/tests/ginkgo/fixture/utils"
3538
)
3639

@@ -68,46 +71,214 @@ var _ = Describe("GitOps Operator Parallel E2E Tests", func() {
6871
}
6972
Expect(k8sClient.Create(ctx, argoCD)).To(Succeed())
7073

71-
By("verifying the Argo CD becomes available")
74+
By("verifying the Argo CD instance becomes available")
7275
Eventually(argoCD, "5m", "5s").Should(argocdFixture.BeAvailable())
7376

74-
By("verifying Secret is created for local user")
7577
aliceLocalUser := &corev1.Secret{
7678
ObjectMeta: metav1.ObjectMeta{
7779
Name: "alice-local-user",
7880
Namespace: ns.Name,
7981
},
8082
}
81-
Eventually(aliceLocalUser).Should(k8sFixture.ExistByName())
82-
83-
By("verifying Argo CD argocd-cm ConfigMap references user, and user is enabled")
8483
argocdCMConfigMap := &corev1.ConfigMap{
8584
ObjectMeta: metav1.ObjectMeta{
8685
Name: "argocd-cm",
8786
Namespace: argoCD.Namespace,
8887
},
8988
}
90-
Eventually(argocdCMConfigMap).Should(k8sFixture.ExistByName())
91-
Eventually(argocdCMConfigMap).Should(configmapFixture.HaveStringDataKeyValue("accounts.alice", "apiKey"))
92-
Eventually(argocdCMConfigMap).Should(configmapFixture.HaveStringDataKeyValue("accounts.alice.enabled", "true"))
93-
94-
By("verifying argocd-secret Secret contains token for user")
9589
argocdSecret := &corev1.Secret{
9690
ObjectMeta: metav1.ObjectMeta{
9791
Name: "argocd-secret",
9892
Namespace: argoCD.Namespace,
9993
},
10094
}
101-
Eventually(argocdSecret).Should(k8sFixture.ExistByName())
102-
Eventually(argocdSecret).Should(secret.HaveNonEmptyKeyValue("accounts.alice.tokens"), "Entry 'alice.account.tokens' should be found in argocd-secret")
95+
96+
// verifyConfigurationIsAsExpected verifies all related resources (ConfigMap, Secret, etc) exist and have expected value
97+
verifyConfigurationIsAsExpected := func(description string) {
98+
99+
By(description + " - verifying Secret exists for local user")
100+
Eventually(aliceLocalUser).Should(k8sFixture.ExistByName())
101+
Consistently(aliceLocalUser, "5s", "1s").Should(k8sFixture.ExistByName())
102+
103+
By(description + "- verifying Argo CD argocd-cm ConfigMap references user, and user is enabled")
104+
Eventually(argocdCMConfigMap).Should(k8sFixture.ExistByName())
105+
Eventually(argocdCMConfigMap).Should(configmapFixture.HaveStringDataKeyValue("accounts.alice", "apiKey"))
106+
Consistently(argocdCMConfigMap, "5s", "1s").Should(configmapFixture.HaveStringDataKeyValue("accounts.alice", "apiKey"))
107+
Eventually(argocdCMConfigMap).Should(configmapFixture.HaveStringDataKeyValue("accounts.alice.enabled", "true"))
108+
109+
By(description + "- verifying argocd-secret Secret contains token for user")
110+
Eventually(argocdSecret).Should(k8sFixture.ExistByName())
111+
112+
Consistently(argocdSecret, "5s", "1s").Should(k8sFixture.ExistByName())
113+
Eventually(argocdSecret).Should(secretFixture.HaveNonEmptyKeyValue("accounts.alice.tokens"), "Entry 'alice.account.tokens' should be found in argocd-secret")
114+
Consistently(argocdSecret, "5s", "1s").Should(secretFixture.HaveNonEmptyKeyValue("accounts.alice.tokens"), "Entry 'alice.account.tokens' should be found in argocd-secret")
115+
116+
}
117+
118+
verifyConfigurationIsAsExpected("initial creation")
119+
120+
// ----
103121

104122
By("delete local user Secret")
105123
Expect(k8sClient.Delete(ctx, aliceLocalUser)).To(Succeed())
106124

107125
By("verifying local user Secret is recreated")
108-
Eventually(aliceLocalUser).Should(k8sFixture.ExistByName())
109-
Consistently(aliceLocalUser).Should(k8sFixture.ExistByName())
126+
verifyConfigurationIsAsExpected("after local Secret deletion")
127+
128+
// -----
129+
130+
By("deleting argocd-cm ConfigMap, to verify it is recreated with expected values")
131+
132+
Expect(k8sClient.Delete(ctx, argocdCMConfigMap)).To(Succeed())
133+
134+
verifyConfigurationIsAsExpected("after argocd-cm deletion")
135+
136+
// -----
137+
By("removing alice user, and creating new user bob")
138+
argocdFixture.Update(argoCD, func(ac *argov1beta1api.ArgoCD) {
139+
ac.Spec.LocalUsers = []argov1beta1api.LocalUserSpec{
140+
{
141+
Name: "bob",
142+
TokenLifetime: "100h",
143+
},
144+
}
145+
})
146+
147+
By("verifying alice-local-user Secret is deleted")
148+
Eventually(aliceLocalUser).Should(k8sFixture.NotExistByName())
149+
150+
By("verifying bob-local-user Secret is created")
151+
152+
bobLocalUser := &corev1.Secret{
153+
ObjectMeta: metav1.ObjectMeta{
154+
Name: "bob-local-user",
155+
Namespace: ns.Name,
156+
},
157+
}
158+
Eventually(bobLocalUser).Should(k8sFixture.ExistByName())
159+
160+
By("verifying alice is removed from argocd-cm ConfigMap")
161+
Eventually(argocdCMConfigMap).Should(k8sFixture.ExistByName())
162+
Eventually(argocdCMConfigMap).Should(configmapFixture.NotHaveStringDataKey("accounts.alice"))
163+
Eventually(argocdCMConfigMap).Should(configmapFixture.NotHaveStringDataKey("accounts.alice.enabled"))
164+
Consistently(argocdCMConfigMap).Should(configmapFixture.NotHaveStringDataKey("accounts.alice"))
165+
Consistently(argocdCMConfigMap).Should(configmapFixture.NotHaveStringDataKey("accounts.alice.enabled"))
166+
167+
By("verifying Argo CD argocd-cm ConfigMap references bob, and bob is enabled")
168+
Eventually(argocdCMConfigMap).Should(configmapFixture.HaveStringDataKeyValue("accounts.bob", "apiKey"))
169+
Consistently(argocdCMConfigMap, "5s", "1s").Should(configmapFixture.HaveStringDataKeyValue("accounts.bob", "apiKey"))
170+
Eventually(argocdCMConfigMap).Should(configmapFixture.HaveStringDataKeyValue("accounts.bob.enabled", "true"))
171+
172+
By("verifying argocd-secret Secret contains token for bob")
173+
Eventually(argocdSecret).Should(k8sFixture.ExistByName())
174+
Consistently(argocdSecret, "5s", "1s").Should(k8sFixture.ExistByName())
175+
Eventually(argocdSecret).Should(k8sFixture.ExistByName())
176+
Consistently(argocdSecret, "5s", "1s").Should(k8sFixture.ExistByName())
177+
Eventually(argocdSecret).Should(secretFixture.HaveNonEmptyKeyValue("accounts.bob.tokens"))
178+
Consistently(argocdSecret, "5s", "1s").Should(secretFixture.HaveNonEmptyKeyValue("accounts.bob.tokens"))
179+
180+
By("verifying argocd-secret Secret does not contain token for alice")
181+
Eventually(argocdSecret).Should(secretFixture.NotHaveDataKey("accounts.alice.tokens"))
182+
Consistently(argocdSecret).Should(secretFixture.NotHaveDataKey("accounts.alice.tokens"))
183+
184+
// -----
185+
186+
By("removing localUsers field, which should cause the resources to be deleted")
187+
argocdFixture.Update(argoCD, func(ac *argov1beta1api.ArgoCD) {
188+
ac.Spec.LocalUsers = nil
189+
})
190+
191+
By("verifying local user Secret is removed")
192+
Eventually(aliceLocalUser).Should(k8sFixture.NotExistByName())
193+
Consistently(aliceLocalUser).Should(k8sFixture.NotExistByName())
194+
195+
By("verifying Argo CD argocd-cm ConfigMap continues to exist")
196+
Eventually(argocdCMConfigMap).Should(k8sFixture.ExistByName())
197+
Consistently(argocdCMConfigMap).Should(k8sFixture.ExistByName())
198+
199+
})
200+
201+
It("verifies that if left over resources exist after the local user is deleted from ArgoCD CR, the resources are deleted", func() {
202+
203+
By("creating namespace-scoped Argo CD instance in a new namespace, with no local users")
204+
ns, cleanupFunc := fixture.CreateRandomE2ETestNamespaceWithCleanupFunc()
205+
defer cleanupFunc()
206+
207+
argoCD := &argov1beta1api.ArgoCD{
208+
ObjectMeta: metav1.ObjectMeta{Name: "example-argocd", Namespace: ns.Name},
209+
Spec: argov1beta1api.ArgoCDSpec{},
210+
}
211+
Expect(k8sClient.Create(ctx, argoCD)).To(Succeed())
212+
213+
By("verifying the Argo CD instance becomes available")
214+
Eventually(argoCD, "5m", "5s").Should(argocdFixture.BeAvailable())
215+
216+
By("adding account fields to ConfigMap, and verifying they are removed by reconciler")
217+
218+
argocdCMConfigMap := &corev1.ConfigMap{
219+
ObjectMeta: metav1.ObjectMeta{
220+
Name: "argocd-cm",
221+
Namespace: argoCD.Namespace,
222+
},
223+
}
224+
225+
configmap.Update(argocdCMConfigMap, func(cm *corev1.ConfigMap) {
226+
if cm.Data == nil {
227+
cm.Data = map[string]string{}
228+
}
229+
cm.Data["accounts.alice"] = string("apiKey")
230+
cm.Data["accounts.alice.enabled"] = string("true")
231+
})
232+
233+
Eventually(argocdCMConfigMap).Should(configmapFixture.NotHaveStringDataKey("accounts.alice.enabled"))
234+
Eventually(argocdCMConfigMap).Should(configmapFixture.NotHaveStringDataKey("accounts.alice"))
235+
236+
Consistently(argocdCMConfigMap).Should(configmapFixture.NotHaveStringDataKey("accounts.alice.enabled"))
237+
Consistently(argocdCMConfigMap).Should(configmapFixture.NotHaveStringDataKey("accounts.alice"))
238+
239+
// -----
240+
241+
By("creating local user Secret (without an entry in ArgoCD CR) and verifying it is deleted")
242+
243+
// Create a manually crafted local user Secret to verify it gets deleted by the reconciler
244+
manuallyCreatedSecret := &corev1.Secret{
245+
ObjectMeta: metav1.ObjectMeta{
246+
Name: "alice-local-user",
247+
Namespace: ns.Name,
248+
Labels: map[string]string{
249+
"app.kubernetes.io/component": "local-users",
250+
"app.kubernetes.io/managed-by": "example-argocd",
251+
"app.kubernetes.io/name": "alice-local-user",
252+
"app.kubernetes.io/part-of": "argocd",
253+
"operator.argoproj.io/tracked-by": "argocd",
254+
},
255+
OwnerReferences: []metav1.OwnerReference{
256+
{
257+
APIVersion: "argoproj.io/v1beta1",
258+
Kind: "ArgoCD",
259+
BlockOwnerDeletion: ptr.To(true),
260+
Controller: ptr.To(true),
261+
Name: argoCD.Name,
262+
UID: argoCD.UID,
263+
},
264+
},
265+
},
266+
Type: corev1.SecretTypeOpaque,
267+
Data: map[string][]byte{
268+
"apiToken": []byte("fake-api-token-" + string(uuid.NewUUID())),
269+
"autoRenew": []byte("true"),
270+
"expAt": []byte("2761409557"),
271+
"tokenLifetime": []byte("100h"),
272+
"user": []byte("alice"),
273+
},
274+
}
275+
276+
By("creating the manually crafted local user Secret")
277+
Expect(k8sClient.Create(ctx, manuallyCreatedSecret)).To(Succeed())
110278

279+
By("verifying the manually created Secret is deleted by the reconciler")
280+
Eventually(manuallyCreatedSecret).Should(k8sFixture.NotExistByName())
281+
Consistently(manuallyCreatedSecret).Should(k8sFixture.NotExistByName())
111282
})
112283

113284
})

tests/ginkgo/parallel/1-053_validate_local_user_token_renewal_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ var _ = Describe("GitOps Operator Parallel E2E Tests", func() {
6767
}
6868
Expect(k8sClient.Create(ctx, argoCD)).To(Succeed())
6969

70-
By("verifying the Argo CD becomes available")
70+
By("verifying the Argo CD instance becomes available")
7171
Eventually(argoCD, "5m", "5s").Should(argocdFixture.BeAvailable())
7272

7373
By("verifying Secret is created for local user")

0 commit comments

Comments
 (0)