From e351a7adcdb71d9275a6a6b858c77ad18bde58d5 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Wed, 15 Oct 2025 20:01:44 +0100 Subject: [PATCH 1/3] fix kubernetes waiting containers cache index This PR resolves an issue with the Kubernetes ephemeral containers cache used by Kubernetes agents, where the keys used in the index and get methods did not match. This mismatch caused the get method to fail with not found error, preventing the debug container from being created. Signed-off-by: Tiago Silva --- lib/cache/kube.go | 2 +- lib/cache/kube_test.go | 52 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/lib/cache/kube.go b/lib/cache/kube.go index eb2dca385137a..fbbb677de862b 100644 --- a/lib/cache/kube.go +++ b/lib/cache/kube.go @@ -235,7 +235,7 @@ func newKubernetesWaitingContainerCollection(upstream services.KubeWaitingContai proto.CloneOf[*kubewaitingcontainerv1.KubernetesWaitingContainer], map[kubeWaitingContainerIndex]func(*kubewaitingcontainerv1.KubernetesWaitingContainer) string{ kubeWaitingContainerNameIndex: func(u *kubewaitingcontainerv1.KubernetesWaitingContainer) string { - return u.GetMetadata().GetName() + return u.GetSpec().GetUsername() + "/" + u.GetSpec().GetCluster() + "/" + u.GetSpec().GetNamespace() + "/" + u.GetSpec().GetPodName() + "/" + u.GetMetadata().GetName() }, }), fetcher: func(ctx context.Context, loadSecrets bool) ([]*kubewaitingcontainerv1.KubernetesWaitingContainer, error) { diff --git a/lib/cache/kube_test.go b/lib/cache/kube_test.go index 437fc984c2c32..37a97de090dbe 100644 --- a/lib/cache/kube_test.go +++ b/lib/cache/kube_test.go @@ -24,7 +24,9 @@ import ( "github.com/gravitational/trace" "github.com/stretchr/testify/require" + kubewaitingcontainerpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/kubewaitingcontainer/v1" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/types/kubewaitingcontainer" ) // TestKubernetes tests that CRUD operations on kubernetes clusters resources are @@ -133,3 +135,53 @@ func TestKubernetesServers(t *testing.T) { }) } + +func TestKubernetesWaitingContainers(t *testing.T) { + t.Parallel() + + p := newTestPack(t, ForProxy) + t.Cleanup(p.Close) + + testResources153(t, p, testFuncs[*kubewaitingcontainerpb.KubernetesWaitingContainer]{ + newResource: func(name string) (*kubewaitingcontainerpb.KubernetesWaitingContainer, error) { + u := uuid.NewString() + waitingCont, err := kubewaitingcontainer.NewKubeWaitingContainer( + u, + &kubewaitingcontainerpb.KubernetesWaitingContainerSpec{ + Username: "user", + Cluster: "cluster", + Namespace: "namespace", + PodName: "pod", + ContainerName: u, + Patch: []byte("{}"), + PatchType: "application/json-patch+json", + }) + + return waitingCont, trace.Wrap(err) + }, + create: func(ctx context.Context, kwc *kubewaitingcontainerpb.KubernetesWaitingContainer) error { + _, err := p.kubeWaitingContainers.CreateKubernetesWaitingContainer(ctx, kwc) + return trace.Wrap(err) + }, + cacheGet: func(ctx context.Context, name string) (*kubewaitingcontainerpb.KubernetesWaitingContainer, error) { + return p.cache.GetKubernetesWaitingContainer(ctx, &kubewaitingcontainerpb.GetKubernetesWaitingContainerRequest{ + Username: "user", + Cluster: "cluster", + Namespace: "namespace", + PodName: "pod", + ContainerName: name, + }) + }, + list: func(ctx context.Context, i int, s string) ([]*kubewaitingcontainerpb.KubernetesWaitingContainer, string, error) { + return p.kubeWaitingContainers.ListKubernetesWaitingContainers(ctx, i, s) + }, + cacheList: func(ctx context.Context, i int, s string) ([]*kubewaitingcontainerpb.KubernetesWaitingContainer, string, error) { + return p.cache.ListKubernetesWaitingContainers(ctx, i, s) + }, + + deleteAll: func(ctx context.Context) error { + return p.kubeWaitingContainers.DeleteAllKubernetesWaitingContainers(ctx) + }, + }) + +} From 3987e2177fddc0dabe229fec765b1f445ea10826 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Wed, 15 Oct 2025 20:32:37 +0100 Subject: [PATCH 2/3] fix issue with headerTransform --- lib/cache/kube.go | 10 ---------- lib/cache/kube_test.go | 15 +++++++++++---- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/lib/cache/kube.go b/lib/cache/kube.go index fbbb677de862b..f33216c2c263f 100644 --- a/lib/cache/kube.go +++ b/lib/cache/kube.go @@ -23,7 +23,6 @@ import ( "github.com/gravitational/trace" "google.golang.org/protobuf/proto" - headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" kubewaitingcontainerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/kubewaitingcontainer/v1" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/utils/clientutils" @@ -242,15 +241,6 @@ func newKubernetesWaitingContainerCollection(upstream services.KubeWaitingContai out, err := stream.Collect(clientutils.Resources(ctx, upstream.ListKubernetesWaitingContainers)) return out, trace.Wrap(err) }, - headerTransform: func(hdr *types.ResourceHeader) *kubewaitingcontainerv1.KubernetesWaitingContainer { - return &kubewaitingcontainerv1.KubernetesWaitingContainer{ - Kind: hdr.Kind, - Version: hdr.Version, - Metadata: &headerv1.Metadata{ - Name: hdr.Metadata.Name, - }, - } - }, watch: w, }, nil } diff --git a/lib/cache/kube_test.go b/lib/cache/kube_test.go index 37a97de090dbe..8ce802eb2d2ef 100644 --- a/lib/cache/kube_test.go +++ b/lib/cache/kube_test.go @@ -144,15 +144,14 @@ func TestKubernetesWaitingContainers(t *testing.T) { testResources153(t, p, testFuncs[*kubewaitingcontainerpb.KubernetesWaitingContainer]{ newResource: func(name string) (*kubewaitingcontainerpb.KubernetesWaitingContainer, error) { - u := uuid.NewString() waitingCont, err := kubewaitingcontainer.NewKubeWaitingContainer( - u, + name, &kubewaitingcontainerpb.KubernetesWaitingContainerSpec{ Username: "user", Cluster: "cluster", Namespace: "namespace", PodName: "pod", - ContainerName: u, + ContainerName: name, Patch: []byte("{}"), PatchType: "application/json-patch+json", }) @@ -178,7 +177,15 @@ func TestKubernetesWaitingContainers(t *testing.T) { cacheList: func(ctx context.Context, i int, s string) ([]*kubewaitingcontainerpb.KubernetesWaitingContainer, string, error) { return p.cache.ListKubernetesWaitingContainers(ctx, i, s) }, - + delete: func(ctx context.Context, s string) error { + return p.kubeWaitingContainers.DeleteKubernetesWaitingContainer(ctx, &kubewaitingcontainerpb.DeleteKubernetesWaitingContainerRequest{ + Username: "user", + Cluster: "cluster", + Namespace: "namespace", + PodName: "pod", + ContainerName: s, + }) + }, deleteAll: func(ctx context.Context) error { return p.kubeWaitingContainers.DeleteAllKubernetesWaitingContainers(ctx) }, From a0509d8743e3e7eba64ad9e6db1e1620e041dc57 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Thu, 16 Oct 2025 08:29:17 +0100 Subject: [PATCH 3/3] unify cache keys --- lib/cache/kube.go | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/cache/kube.go b/lib/cache/kube.go index f33216c2c263f..6effda9819655 100644 --- a/lib/cache/kube.go +++ b/lib/cache/kube.go @@ -234,7 +234,8 @@ func newKubernetesWaitingContainerCollection(upstream services.KubeWaitingContai proto.CloneOf[*kubewaitingcontainerv1.KubernetesWaitingContainer], map[kubeWaitingContainerIndex]func(*kubewaitingcontainerv1.KubernetesWaitingContainer) string{ kubeWaitingContainerNameIndex: func(u *kubewaitingcontainerv1.KubernetesWaitingContainer) string { - return u.GetSpec().GetUsername() + "/" + u.GetSpec().GetCluster() + "/" + u.GetSpec().GetNamespace() + "/" + u.GetSpec().GetPodName() + "/" + u.GetMetadata().GetName() + spec := u.GetSpec() + return kubernetesWaitingContainerCacheKey(spec) }, }), fetcher: func(ctx context.Context, loadSecrets bool) ([]*kubewaitingcontainerv1.KubernetesWaitingContainer, error) { @@ -259,7 +260,7 @@ func (c *Cache) ListKubernetesWaitingContainers(ctx context.Context, pageSize in upstreamList: c.Config.KubeWaitingContainers.ListKubernetesWaitingContainers, nextToken: func(t *kubewaitingcontainerv1.KubernetesWaitingContainer) string { spec := t.GetSpec() - return spec.GetUsername() + "/" + spec.GetCluster() + "/" + spec.GetNamespace() + "/" + spec.GetPodName() + "/" + t.GetMetadata().GetName() + return kubernetesWaitingContainerCacheKey(spec) }, } out, next, err := lister.list(ctx, pageSize, pageToken) @@ -283,7 +284,19 @@ func (c *Cache) GetKubernetesWaitingContainer(ctx context.Context, req *kubewait }, } - name := req.GetUsername() + "/" + req.GetCluster() + "/" + req.GetNamespace() + "/" + req.GetPodName() + "/" + req.GetContainerName() + name := kubernetesWaitingContainerCacheKey(req) out, err := getter.get(ctx, name) return out, trace.Wrap(err) } + +type kubernetesWaitingContainerCacheKeyFieldGetter interface { + GetUsername() string + GetCluster() string + GetNamespace() string + GetPodName() string + GetContainerName() string +} + +func kubernetesWaitingContainerCacheKey(c kubernetesWaitingContainerCacheKeyFieldGetter) string { + return c.GetUsername() + "/" + c.GetCluster() + "/" + c.GetNamespace() + "/" + c.GetPodName() + "/" + c.GetContainerName() +}