Skip to content

Commit 02400d0

Browse files
authored
feat(redis): Inject creds via volume (#1112)
* feat(redis): Inject creds via volume Signed-off-by: Oliver Gondža <ogondza@gmail.com> * unrewert the imports Signed-off-by: Oliver Gondža <ogondza@gmail.com> * Bump the argocd version correctly Signed-off-by: Oliver Gondža <ogondza@gmail.com> * comment typo Signed-off-by: Oliver Gondža <ogondza@gmail.com> --------- Signed-off-by: Oliver Gondža <ogondza@gmail.com>
1 parent 830b1dd commit 02400d0

6 files changed

Lines changed: 182 additions & 10 deletions

test/openshift/e2e/ginkgo/parallel/1-066_validate_redis_secure_comm_no_autotls_no_ha_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"time"
2323

2424
argov1beta1api "github.com/argoproj-labs/argocd-operator/api/v1beta1"
25+
"github.com/argoproj-labs/argocd-operator/controllers/argoutil"
2526
. "github.com/onsi/ginkgo/v2"
2627
. "github.com/onsi/gomega"
2728
"github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture"
@@ -175,5 +176,72 @@ var _ = Describe("GitOps Operator Parallel E2E Tests", func() {
175176

176177
})
177178

179+
It("verify redis credential distribution", func() {
180+
181+
By("creating simple Argo CD instance")
182+
ns, cleanupFunc = fixture.CreateRandomE2ETestNamespaceWithCleanupFunc()
183+
184+
argoCD := &argov1beta1api.ArgoCD{
185+
ObjectMeta: metav1.ObjectMeta{Name: "argocd", Namespace: ns.Name},
186+
Spec: argov1beta1api.ArgoCDSpec{},
187+
}
188+
Expect(k8sClient.Create(ctx, argoCD)).To(Succeed())
189+
190+
By("waiting for ArgoCD CR to be reconciled and the instance to be ready")
191+
Eventually(argoCD, "5m", "5s").Should(argocdFixture.BeAvailable())
192+
193+
By("verify redis creds are correctly passed to pods")
194+
const expectedMsg = "Loading Redis credentials from mounted directory: /app/config/redis-auth/"
195+
expectedComponents := []string{
196+
"statefulset/" + argoCD.Name + "-" + "application-controller",
197+
"deployment/" + argoCD.Name + "-" + "repo-server",
198+
"deployment/" + argoCD.Name + "-" + "server",
199+
}
200+
for _, component := range expectedComponents {
201+
logOutput, err := osFixture.ExecCommandWithOutputParam(false, true,
202+
"kubectl", "logs", component, "-n", ns.Name,
203+
)
204+
Expect(err).ToNot(HaveOccurred(), "Output: "+logOutput)
205+
Expect(logOutput).To(ContainSubstring(expectedMsg))
206+
// This is how redis disconnect manifests
207+
Expect(logOutput).ToNot(ContainSubstring("manifest cache error"))
208+
Expect(logOutput).ToNot(ContainSubstring("WRONGPASS"))
209+
210+
mountedFiles, err := osFixture.ExecCommandWithOutputParam(false, true,
211+
"kubectl", "exec", component, "-n", ns.Name, "--", "ls", "-1", argoutil.RedisAuthMountPath,
212+
)
213+
Expect(err).ToNot(HaveOccurred(), "Output: "+logOutput)
214+
Expect(mountedFiles).ToNot(ContainSubstring("users.acl"))
215+
}
216+
217+
By("verifying redis password is correct")
218+
redisInitialSecret := &corev1.Secret{}
219+
redisPwdSecretKey := client.ObjectKey{
220+
Name: argoutil.GetSecretNameWithSuffix(argoCD, "redis-initial-password"),
221+
Namespace: ns.Name,
222+
}
223+
Expect(k8sClient.Get(ctx, redisPwdSecretKey, redisInitialSecret)).Should(Succeed())
224+
expectedRedisPwd := string(redisInitialSecret.Data["auth"])
225+
Expect(expectedRedisPwd).ShouldNot(Equal(""))
226+
227+
redisPingOut, err := osFixture.ExecCommandWithOutputParam(false, false,
228+
"kubectl", "exec", "-n", ns.Name, "-c", "redis", "deployment/argocd-redis", "--",
229+
"redis-cli", "-a", expectedRedisPwd, "--no-auth-warning", "ping",
230+
)
231+
232+
Expect(err).ToNot(HaveOccurred(), "Output: "+redisPingOut)
233+
Expect(redisPingOut).NotTo(ContainSubstring("NOAUTH Authentication required"))
234+
Expect(redisPingOut).To(ContainSubstring("PONG"))
235+
236+
By("verifying redis rejects unauthenticated requests")
237+
redisPingOut, err = osFixture.ExecCommandWithOutputParam(false, false,
238+
"kubectl", "exec", "-n", ns.Name, "-c", "redis", "deployment/argocd-redis", "--",
239+
"redis-cli", "ping", // no auth provided
240+
)
241+
242+
Expect(err).ToNot(HaveOccurred(), "Output: "+redisPingOut)
243+
Expect(redisPingOut).To(ContainSubstring("NOAUTH Authentication required"))
244+
Expect(redisPingOut).NotTo(ContainSubstring("PONG"))
245+
})
178246
})
179247
})

test/openshift/e2e/ginkgo/parallel/1-067_validate_redis_secure_comm_no_autotls_ha_test.go

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"os"
2222

2323
argov1beta1api "github.com/argoproj-labs/argocd-operator/api/v1beta1"
24+
"github.com/argoproj-labs/argocd-operator/controllers/argoutil"
2425
. "github.com/onsi/ginkgo/v2"
2526
. "github.com/onsi/gomega"
2627
"github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture"
@@ -175,19 +176,24 @@ var _ = Describe("GitOps Operator Parallel E2E Tests", func() {
175176
}
176177

177178
By("extracting the contents of /data/conf/sentinel.conf and checking it contains expected values")
178-
sentinelConf, err := osFixture.ExecCommandWithOutputParam(false, true, "kubectl", "exec", "-i", "pod/argocd-redis-ha-server-0", "-n", ns.Name, "-c", "redis", "--", "cat", "/data/conf/sentinel.conf")
179+
sentinelConf, err := osFixture.ExecCommandWithOutputParam(
180+
false, true,
181+
"kubectl", "exec", "-i", "pod/argocd-redis-ha-server-0", "-n", ns.Name, "-c", "redis",
182+
"--", "cat", "/data/conf/sentinel.conf",
183+
)
179184
Expect(err).ToNot(HaveOccurred())
180185
expectedSentinelConfig := []string{
181186
"port 0",
182187
"tls-port 26379",
183-
"tls-cert-file \"/app/config/redis/tls/tls.crt\"",
184-
"tls-ca-cert-file \"/app/config/redis/tls/tls.crt\"",
185-
"tls-key-file \"/app/config/redis/tls/tls.key\"",
188+
// Dynamic changes to the config file can result in doublequotes added unpredictably
189+
`tls-cert-file "?/app/config/redis/tls/tls.crt"?`,
190+
`tls-ca-cert-file "?/app/config/redis/tls/tls.crt"?`,
191+
`tls-key-file "?/app/config/redis/tls/tls.key"?`,
186192
"tls-replication yes",
187193
"tls-auth-clients no",
188194
}
189195
for _, line := range expectedSentinelConfig {
190-
Expect(sentinelConf).To(ContainSubstring(line))
196+
Expect(sentinelConf).To(MatchRegexp(line))
191197
}
192198

193199
repoServerDepl := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "argocd-repo-server", Namespace: ns.Name}}
@@ -210,8 +216,80 @@ var _ = Describe("GitOps Operator Parallel E2E Tests", func() {
210216

211217
Expect(applicationControllerSS).To(statefulsetFixture.HaveContainerCommandSubstring("argocd-application-controller --operation-processors 10 --redis argocd-redis-ha-haproxy."+ns.Name+".svc.cluster.local:6379 --redis-use-tls --redis-ca-certificate /app/config/controller/tls/redis/tls.crt --repo-server argocd-repo-server."+ns.Name+".svc.cluster.local:8081 --status-processors 20 --kubectl-parallelism-limit 10 --loglevel info --logformat text", 0),
212218
"TLS .spec.template.spec.containers.command for argocd-application-controller statefulsets is wrong")
213-
214219
})
215220

221+
It("verify redis HA credential distribution", func() {
222+
By("verifying we are running on a cluster with at least 3 nodes. This is required for Redis HA")
223+
nodeFixture.ExpectHasAtLeastXNodes(3)
224+
225+
By("creating simple Argo CD instance")
226+
ns, cleanupFunc = fixture.CreateRandomE2ETestNamespaceWithCleanupFunc()
227+
228+
argoCD := &argov1beta1api.ArgoCD{
229+
ObjectMeta: metav1.ObjectMeta{Name: "argocd", Namespace: ns.Name},
230+
Spec: argov1beta1api.ArgoCDSpec{
231+
HA: argov1beta1api.ArgoCDHASpec{
232+
Enabled: true,
233+
},
234+
},
235+
}
236+
Expect(k8sClient.Create(ctx, argoCD)).To(Succeed())
237+
238+
By("waiting for ArgoCD CR to be reconciled and the instance to be ready")
239+
Eventually(argoCD, "10m", "10s").Should(argocdFixture.BeAvailable())
240+
241+
By("verify redis creds are correctly passed to pods")
242+
const expectedMsg = "Loading Redis credentials from mounted directory: /app/config/redis-auth/"
243+
expectedComponents := []string{
244+
"statefulset/" + argoCD.Name + "-" + "application-controller",
245+
"deployment/" + argoCD.Name + "-" + "repo-server",
246+
"deployment/" + argoCD.Name + "-" + "server",
247+
}
248+
for _, component := range expectedComponents {
249+
logOutput, err := osFixture.ExecCommandWithOutputParam(false, true,
250+
"kubectl", "logs", component, "-n", ns.Name,
251+
)
252+
Expect(err).ToNot(HaveOccurred(), "Output: "+logOutput)
253+
Expect(logOutput).To(ContainSubstring(expectedMsg))
254+
// This is how redis disconnect manifests
255+
Expect(logOutput).ToNot(ContainSubstring("manifest cache error"))
256+
Expect(logOutput).ToNot(ContainSubstring("WRONGPASS"))
257+
258+
mountedFiles, err := osFixture.ExecCommandWithOutputParam(false, true,
259+
"kubectl", "exec", component, "-n", ns.Name, "--", "ls", "-1", argoutil.RedisAuthMountPath,
260+
)
261+
Expect(err).ToNot(HaveOccurred(), "Output: "+logOutput)
262+
Expect(mountedFiles).ToNot(ContainSubstring("users.acl"))
263+
}
264+
265+
By("verifying redis password is correct")
266+
redisInitialSecret := &corev1.Secret{}
267+
redisPwdSecretKey := client.ObjectKey{
268+
Name: argoutil.GetSecretNameWithSuffix(argoCD, "redis-initial-password"),
269+
Namespace: ns.Name,
270+
}
271+
Expect(k8sClient.Get(ctx, redisPwdSecretKey, redisInitialSecret)).Should(Succeed())
272+
expectedRedisPwd := string(redisInitialSecret.Data["auth"])
273+
Expect(expectedRedisPwd).ShouldNot(Equal(""))
274+
275+
redisPingOut, err := osFixture.ExecCommandWithOutputParam(false, false,
276+
"kubectl", "exec", "-n", ns.Name, "-c", "redis", "pod/argocd-redis-ha-server-0", "--",
277+
"redis-cli", "-a", expectedRedisPwd, "--no-auth-warning", "ping",
278+
)
279+
280+
Expect(err).ToNot(HaveOccurred(), "Output: "+redisPingOut)
281+
Expect(redisPingOut).NotTo(ContainSubstring("NOAUTH Authentication required"))
282+
Expect(redisPingOut).To(ContainSubstring("PONG"))
283+
284+
By("verifying redis rejects unauthenticated requests")
285+
redisPingOut, err = osFixture.ExecCommandWithOutputParam(false, false,
286+
"kubectl", "exec", "-n", ns.Name, "-c", "redis", "pod/argocd-redis-ha-server-0", "--",
287+
"redis-cli", "ping", // no auth provided
288+
)
289+
290+
Expect(err).ToNot(HaveOccurred(), "Output: "+redisPingOut)
291+
Expect(redisPingOut).To(ContainSubstring("NOAUTH Authentication required"))
292+
Expect(redisPingOut).NotTo(ContainSubstring("PONG"))
293+
})
216294
})
217295
})

test/openshift/e2e/ginkgo/parallel/1-096-validate_home_env_argocd_controller_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ var _ = Describe("GitOps Operator Parallel E2E Tests", func() {
5050

5151
By("verifying REDIS_PASSWORD env var is no longer set (replaced by redis-initial-pass volume mount)")
5252
container := ss.Spec.Template.Spec.Containers[0]
53-
for _, env := range container.Env {
54-
Expect(env.Name).NotTo(Equal("REDIS_PASSWORD"))
55-
}
53+
Expect(container.Env).NotTo(ContainElement(
54+
HaveField("Name", "REDIS_PASSWORD"),
55+
), "REDIS_PASSWORD should not be set")
5656

5757
By("verifying redis-initial-pass volume mount is present")
5858
hasRedisAuthMount := false

test/openshift/e2e/ginkgo/sequential/1-051_validate_argocd_agent_principal_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,10 @@ var _ = Describe("GitOps Operator Sequential E2E Tests", func() {
390390
Expect(container.Env).To(ContainElement(corev1.EnvVar{Name: key, Value: value}), "Environment variable %s should be set to %s", key, value)
391391
}
392392

393+
Expect(container.Env).NotTo(ContainElement(
394+
HaveField("Name", "REDIS_PASSWORD"),
395+
), "REDIS_PASSWORD should not be set")
396+
393397
By("Disable principal")
394398

395399
Expect(k8sClient.Get(ctx, client.ObjectKey{Name: argoCDName, Namespace: ns.Name}, argoCD)).To(Succeed())

test/openshift/e2e/ginkgo/sequential/1-052_validate_argocd_agent_agent_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,10 @@ var _ = Describe("GitOps Operator Sequential E2E Tests", func() {
346346
Expect(container.Env).To(ContainElement(corev1.EnvVar{Name: key, Value: value}), "Environment variable %s should be set to %s", key, value)
347347
}
348348

349+
Expect(container.Env).NotTo(ContainElement(
350+
HaveField("Name", "REDIS_PASSWORD"),
351+
), "REDIS_PASSWORD should not be set")
352+
349353
By("Verify custom environment variable is present")
350354

351355
Expect(container.Env).To(ContainElement(corev1.EnvVar{Name: "TEST_ENV", Value: "test_value"}), "Custom environment variable TEST_ENV should be set")

test/openshift/e2e/ginkgo/sequential/1-053_validate_argocd_agent_principal_connected_test.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
appFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/application"
3636
deploymentFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/deployment"
3737
k8sFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/k8s"
38+
osFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/os"
3839
fixtureUtils "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/utils"
3940
appsv1 "k8s.io/api/apps/v1"
4041
corev1 "k8s.io/api/core/v1"
@@ -366,6 +367,23 @@ var _ = Describe("GitOps Operator Sequential E2E Tests", func() {
366367
cancellableContext, cancelFunc := context.WithCancel(context.Background())
367368
defer cancelFunc()
368369

370+
injectedRedisPwd, err := osFixture.ExecCommandWithOutputParam(
371+
false, false,
372+
"kubectl", "exec", "deployment/argocd-hub-agent-principal", "-n", namespaceAgentPrincipal,
373+
"--", "cat", "/app/config/redis-auth/auth",
374+
)
375+
Expect(err).NotTo(HaveOccurred())
376+
Expect(strings.TrimSpace(injectedRedisPwd)).ToNot(BeEmpty())
377+
378+
principalEnv, err := osFixture.ExecCommandWithOutputParam(
379+
false, false,
380+
"kubectl", "exec", "deployment/argocd-hub-agent-principal", "-n", namespaceAgentPrincipal,
381+
"--", "cat", "/proc/1/environ",
382+
)
383+
Expect(err).NotTo(HaveOccurred())
384+
Expect(principalEnv).To(ContainSubstring("REDIS_CREDS_DIR_PATH=/app/config/redis-auth/"))
385+
Expect(principalEnv).NotTo(ContainSubstring("REDIS_PASSWORD"))
386+
369387
resourceTreeURL := "https://" + argoEndpoint + "/api/v1/stream/applications/" + appOnPrincipal.Name + "/resource-tree?appNamespace=" + appOnPrincipal.Namespace
370388

371389
// Wait for successful connection to resource tree event source API, on principal Argo CD
@@ -472,6 +490,7 @@ var _ = Describe("GitOps Operator Sequential E2E Tests", func() {
472490
Eventually(func() bool {
473491
for {
474492
// drain channel looking for name of new pod
493+
GinkgoWriter.Println("Awaiting message")
475494
select {
476495
case msg := <-msgChan:
477496
GinkgoWriter.Println("Processing message:", msg)
@@ -502,7 +521,6 @@ var _ = Describe("GitOps Operator Sequential E2E Tests", func() {
502521
}
503522
}
504523
Expect(matchFound).To(BeTrue())
505-
506524
}
507525

508526
// This test verifies that:

0 commit comments

Comments
 (0)