Skip to content

Commit abe9899

Browse files
committed
test: add integration tests for secretKeyRef support
Add integration tests that verify CODER_AGENT_TOKEN can be read from Kubernetes secrets via secretKeyRef for both Pods and ReplicaSets.
1 parent 114288c commit abe9899

File tree

1 file changed

+206
-0
lines changed

1 file changed

+206
-0
lines changed

integration_test.go

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,3 +512,209 @@ func TestIntegration_LabelSelector(t *testing.T) {
512512
require.NotContains(t, log, "test-pod-no-label", "should not receive logs for unlabeled pod")
513513
}
514514
}
515+
516+
func TestIntegration_PodWithSecretRef(t *testing.T) {
517+
t.Parallel()
518+
519+
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
520+
defer cancel()
521+
522+
client := getKubeClient(t)
523+
namespace := createTestNamespace(t, ctx, client)
524+
525+
// Create a secret containing the agent token
526+
secret := &corev1.Secret{
527+
ObjectMeta: metav1.ObjectMeta{
528+
Name: "agent-token-secret",
529+
Namespace: namespace,
530+
},
531+
Data: map[string][]byte{
532+
"token": []byte("secret-token-integration"),
533+
},
534+
}
535+
_, err := client.CoreV1().Secrets(namespace).Create(ctx, secret, metav1.CreateOptions{})
536+
require.NoError(t, err)
537+
538+
// Start fake Coder API server
539+
api := newFakeAgentAPI(t)
540+
defer api.server.Close()
541+
542+
agentURL, err := url.Parse(api.server.URL)
543+
require.NoError(t, err)
544+
545+
// Create the pod event logger
546+
reporter, err := newPodEventLogger(ctx, podEventLoggerOptions{
547+
client: client,
548+
coderURL: agentURL,
549+
namespaces: []string{namespace},
550+
logger: slogtest.Make(t, nil).Leveled(slog.LevelDebug),
551+
logDebounce: 5 * time.Second,
552+
})
553+
require.NoError(t, err)
554+
defer reporter.Close()
555+
556+
// Wait for informers to sync
557+
time.Sleep(1 * time.Second)
558+
559+
// Create a pod with CODER_AGENT_TOKEN from secretKeyRef
560+
pod := &corev1.Pod{
561+
ObjectMeta: metav1.ObjectMeta{
562+
Name: "test-pod-secret",
563+
Namespace: namespace,
564+
},
565+
Spec: corev1.PodSpec{
566+
Containers: []corev1.Container{
567+
{
568+
Name: "test-container",
569+
Image: "busybox:latest",
570+
Command: []string{"sleep", "3600"},
571+
Env: []corev1.EnvVar{
572+
{
573+
Name: "CODER_AGENT_TOKEN",
574+
ValueFrom: &corev1.EnvVarSource{
575+
SecretKeyRef: &corev1.SecretKeySelector{
576+
LocalObjectReference: corev1.LocalObjectReference{
577+
Name: "agent-token-secret",
578+
},
579+
Key: "token",
580+
},
581+
},
582+
},
583+
},
584+
},
585+
},
586+
NodeSelector: map[string]string{
587+
"non-existent-label": "non-existent-value",
588+
},
589+
},
590+
}
591+
592+
_, err = client.CoreV1().Pods(namespace).Create(ctx, pod, metav1.CreateOptions{})
593+
require.NoError(t, err)
594+
595+
// Wait for log source registration
596+
waitForLogSource(t, ctx, api, 30*time.Second)
597+
598+
// Wait for the "Created pod" log
599+
logs, found := waitForLogContaining(t, ctx, api, 30*time.Second, "Created pod")
600+
require.True(t, found, "expected 'Created pod' log, got: %v", logs)
601+
602+
// Delete the pod and verify deletion event
603+
err = client.CoreV1().Pods(namespace).Delete(ctx, pod.Name, metav1.DeleteOptions{})
604+
require.NoError(t, err)
605+
606+
// Wait for the "Deleted pod" log
607+
logs, found = waitForLogContaining(t, ctx, api, 30*time.Second, "Deleted pod")
608+
require.True(t, found, "expected 'Deleted pod' log, got: %v", logs)
609+
}
610+
611+
func TestIntegration_ReplicaSetWithSecretRef(t *testing.T) {
612+
t.Parallel()
613+
614+
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
615+
defer cancel()
616+
617+
client := getKubeClient(t)
618+
namespace := createTestNamespace(t, ctx, client)
619+
620+
// Create a secret containing the agent token
621+
secret := &corev1.Secret{
622+
ObjectMeta: metav1.ObjectMeta{
623+
Name: "agent-token-secret",
624+
Namespace: namespace,
625+
},
626+
Data: map[string][]byte{
627+
"token": []byte("secret-token-rs-integration"),
628+
},
629+
}
630+
_, err := client.CoreV1().Secrets(namespace).Create(ctx, secret, metav1.CreateOptions{})
631+
require.NoError(t, err)
632+
633+
// Start fake Coder API server
634+
api := newFakeAgentAPI(t)
635+
defer api.server.Close()
636+
637+
agentURL, err := url.Parse(api.server.URL)
638+
require.NoError(t, err)
639+
640+
// Create the pod event logger
641+
reporter, err := newPodEventLogger(ctx, podEventLoggerOptions{
642+
client: client,
643+
coderURL: agentURL,
644+
namespaces: []string{namespace},
645+
logger: slogtest.Make(t, nil).Leveled(slog.LevelDebug),
646+
logDebounce: 5 * time.Second,
647+
})
648+
require.NoError(t, err)
649+
defer reporter.Close()
650+
651+
// Wait for informers to sync
652+
time.Sleep(1 * time.Second)
653+
654+
// Create a ReplicaSet with CODER_AGENT_TOKEN from secretKeyRef
655+
replicas := int32(1)
656+
rs := &appsv1.ReplicaSet{
657+
ObjectMeta: metav1.ObjectMeta{
658+
Name: "test-rs-secret",
659+
Namespace: namespace,
660+
},
661+
Spec: appsv1.ReplicaSetSpec{
662+
Replicas: &replicas,
663+
Selector: &metav1.LabelSelector{
664+
MatchLabels: map[string]string{
665+
"app": "test-rs-secret",
666+
},
667+
},
668+
Template: corev1.PodTemplateSpec{
669+
ObjectMeta: metav1.ObjectMeta{
670+
Labels: map[string]string{
671+
"app": "test-rs-secret",
672+
},
673+
},
674+
Spec: corev1.PodSpec{
675+
Containers: []corev1.Container{
676+
{
677+
Name: "test-container",
678+
Image: "busybox:latest",
679+
Command: []string{"sleep", "3600"},
680+
Env: []corev1.EnvVar{
681+
{
682+
Name: "CODER_AGENT_TOKEN",
683+
ValueFrom: &corev1.EnvVarSource{
684+
SecretKeyRef: &corev1.SecretKeySelector{
685+
LocalObjectReference: corev1.LocalObjectReference{
686+
Name: "agent-token-secret",
687+
},
688+
Key: "token",
689+
},
690+
},
691+
},
692+
},
693+
},
694+
},
695+
NodeSelector: map[string]string{
696+
"non-existent-label": "non-existent-value",
697+
},
698+
},
699+
},
700+
},
701+
}
702+
703+
_, err = client.AppsV1().ReplicaSets(namespace).Create(ctx, rs, metav1.CreateOptions{})
704+
require.NoError(t, err)
705+
706+
// Wait for log source registration
707+
waitForLogSource(t, ctx, api, 30*time.Second)
708+
709+
// Wait for the "Queued pod from ReplicaSet" log
710+
logs, found := waitForLogContaining(t, ctx, api, 30*time.Second, "Queued pod from ReplicaSet")
711+
require.True(t, found, "expected 'Queued pod from ReplicaSet' log, got: %v", logs)
712+
713+
// Delete the ReplicaSet
714+
err = client.AppsV1().ReplicaSets(namespace).Delete(ctx, rs.Name, metav1.DeleteOptions{})
715+
require.NoError(t, err)
716+
717+
// Wait for the "Deleted ReplicaSet" log
718+
logs, found = waitForLogContaining(t, ctx, api, 30*time.Second, "Deleted ReplicaSet")
719+
require.True(t, found, "expected 'Deleted ReplicaSet' log, got: %v", logs)
720+
}

0 commit comments

Comments
 (0)