Skip to content

Commit db89e22

Browse files
committed
chore: add additional E2E tests for local user management
Signed-off-by: Jonathan West <[email protected]>
1 parent 2a10f87 commit db89e22

File tree

3 files changed

+194
-16
lines changed

3 files changed

+194
-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: 183 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@ 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"
3133
configmapFixture "github.com/argoproj-labs/argocd-operator/tests/ginkgo/fixture/configmap"
3234
k8sFixture "github.com/argoproj-labs/argocd-operator/tests/ginkgo/fixture/k8s"
33-
"github.com/argoproj-labs/argocd-operator/tests/ginkgo/fixture/secret"
35+
secretFixture "github.com/argoproj-labs/argocd-operator/tests/ginkgo/fixture/secret"
3436
fixtureUtils "github.com/argoproj-labs/argocd-operator/tests/ginkgo/fixture/utils"
3537
)
3638

@@ -68,46 +70,212 @@ var _ = Describe("GitOps Operator Parallel E2E Tests", func() {
6870
}
6971
Expect(k8sClient.Create(ctx, argoCD)).To(Succeed())
7072

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

74-
By("verifying Secret is created for local user")
7576
aliceLocalUser := &corev1.Secret{
7677
ObjectMeta: metav1.ObjectMeta{
7778
Name: "alice-local-user",
7879
Namespace: ns.Name,
7980
},
8081
}
81-
Eventually(aliceLocalUser).Should(k8sFixture.ExistByName())
82-
83-
By("verifying Argo CD argocd-cm ConfigMap references user, and user is enabled")
8482
argocdCMConfigMap := &corev1.ConfigMap{
8583
ObjectMeta: metav1.ObjectMeta{
8684
Name: "argocd-cm",
8785
Namespace: argoCD.Namespace,
8886
},
8987
}
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")
9588
argocdSecret := &corev1.Secret{
9689
ObjectMeta: metav1.ObjectMeta{
9790
Name: "argocd-secret",
9891
Namespace: argoCD.Namespace,
9992
},
10093
}
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")
94+
95+
// verifyConfigurationIsAsExpected verifies all related resources (ConfigMap, Secret, etc) exist and have expected value
96+
verifyConfigurationIsAsExpected := func(description string) {
97+
98+
By(description + " - verifying Secret exists for local user")
99+
Eventually(aliceLocalUser).Should(k8sFixture.ExistByName())
100+
Consistently(aliceLocalUser, "5s", "1s").Should(k8sFixture.ExistByName())
101+
102+
By(description + "- verifying Argo CD argocd-cm ConfigMap references user, and user is enabled")
103+
Eventually(argocdCMConfigMap).Should(k8sFixture.ExistByName())
104+
Eventually(argocdCMConfigMap).Should(configmapFixture.HaveStringDataKeyValue("accounts.alice", "apiKey"))
105+
Consistently(argocdCMConfigMap, "5s", "1s").Should(configmapFixture.HaveStringDataKeyValue("accounts.alice", "apiKey"))
106+
Eventually(argocdCMConfigMap).Should(configmapFixture.HaveStringDataKeyValue("accounts.alice.enabled", "true"))
107+
108+
By(description + "- verifying argocd-secret Secret contains token for user")
109+
Eventually(argocdSecret).Should(k8sFixture.ExistByName())
110+
111+
Consistently(argocdSecret, "5s", "1s").Should(k8sFixture.ExistByName())
112+
Eventually(argocdSecret).Should(secretFixture.HaveNonEmptyKeyValue("accounts.alice.tokens"), "Entry 'alice.account.tokens' should be found in argocd-secret")
113+
Consistently(argocdSecret, "5s", "1s").Should(secretFixture.HaveNonEmptyKeyValue("accounts.alice.tokens"), "Entry 'alice.account.tokens' should be found in argocd-secret")
114+
115+
}
116+
117+
verifyConfigurationIsAsExpected("initial creation")
118+
119+
// ----
103120

104121
By("delete local user Secret")
105122
Expect(k8sClient.Delete(ctx, aliceLocalUser)).To(Succeed())
106123

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

276+
By("verifying the manually created Secret is deleted by the reconciler")
277+
Eventually(manuallyCreatedSecret).Should(k8sFixture.NotExistByName())
278+
Consistently(manuallyCreatedSecret).Should(k8sFixture.NotExistByName())
111279
})
112280

113281
})

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)