From 419fba40e02c693cc02c0416d4d837a47d69e7a8 Mon Sep 17 00:00:00 2001 From: David Bond Date: Thu, 16 Oct 2025 10:11:34 +0100 Subject: [PATCH] k8s-operator/api-proxy: put kube api server events behind environment variable (#17550) This commit modifies the k8s-operator's api proxy implementation to only enable forwarding of api requests to tsrecorder when an environment variable is set. This new environment variable is named `TS_EXPERIMENTAL_KUBE_API_EVENTS`. Updates https://github.com/tailscale/corp/issues/32448 Signed-off-by: David Bond --- k8s-operator/api-proxy/proxy.go | 9 +++++++++ k8s-operator/api-proxy/proxy_events_test.go | 1 + 2 files changed, 10 insertions(+) diff --git a/k8s-operator/api-proxy/proxy.go b/k8s-operator/api-proxy/proxy.go index fdb798152..762a52f1f 100644 --- a/k8s-operator/api-proxy/proxy.go +++ b/k8s-operator/api-proxy/proxy.go @@ -28,6 +28,7 @@ import ( "k8s.io/client-go/transport" "tailscale.com/client/local" "tailscale.com/client/tailscale/apitype" + "tailscale.com/envknob" ksr "tailscale.com/k8s-operator/sessionrecording" "tailscale.com/kube/kubetypes" "tailscale.com/net/netx" @@ -96,6 +97,7 @@ func NewAPIServerProxy(zlog *zap.SugaredLogger, restConfig *rest.Config, ts *tsn upstreamURL: u, ts: ts, sendEventFunc: sessionrecording.SendEvent, + eventsEnabled: envknob.Bool("TS_EXPERIMENTAL_KUBE_API_EVENTS"), } ap.rp = &httputil.ReverseProxy{ Rewrite: func(pr *httputil.ProxyRequest) { @@ -192,6 +194,9 @@ type APIServerProxy struct { upstreamURL *url.URL sendEventFunc func(ap netip.AddrPort, event io.Reader, dial netx.DialFunc) error + + // Flag used to enable sending API requests as events to tsrecorder. + eventsEnabled bool } // serveDefault is the default handler for Kubernetes API server requests. @@ -310,6 +315,10 @@ func (ap *APIServerProxy) sessionForProto(w http.ResponseWriter, r *http.Request } func (ap *APIServerProxy) recordRequestAsEvent(req *http.Request, who *apitype.WhoIsResponse) error { + if !ap.eventsEnabled { + return nil + } + failOpen, addrs, err := determineRecorderConfig(who) if err != nil { return fmt.Errorf("error trying to determine whether the kubernetes api request needs to be recorded: %w", err) diff --git a/k8s-operator/api-proxy/proxy_events_test.go b/k8s-operator/api-proxy/proxy_events_test.go index 230927dc0..8bcf48436 100644 --- a/k8s-operator/api-proxy/proxy_events_test.go +++ b/k8s-operator/api-proxy/proxy_events_test.go @@ -61,6 +61,7 @@ func TestRecordRequestAsEvent(t *testing.T) { log: zl.Sugar(), ts: &tsnet.Server{}, sendEventFunc: sender.Send, + eventsEnabled: true, } defaultWho := &apitype.WhoIsResponse{