From d7a5624841227071b7b557fdf136b4aa7ff73897 Mon Sep 17 00:00:00 2001 From: Tom Meadows Date: Mon, 15 Dec 2025 10:27:59 +0000 Subject: [PATCH] cmd/k8s-operator: fix statefulset template yaml indentation (#18194) Fixes #17000 Signed-off-by: chaosinthecrd --- cmd/k8s-operator/deploy/manifests/proxy.yaml | 8 ++-- .../deploy/manifests/userspace-proxy.yaml | 8 ++-- cmd/k8s-operator/ingress_test.go | 42 +++++++++++++------ cmd/k8s-operator/sts.go | 12 +++++- cmd/k8s-operator/testutils_test.go | 13 ++++++ 5 files changed, 62 insertions(+), 21 deletions(-) diff --git a/cmd/k8s-operator/deploy/manifests/proxy.yaml b/cmd/k8s-operator/deploy/manifests/proxy.yaml index 3c9a3eaa3..74e36cf78 100644 --- a/cmd/k8s-operator/deploy/manifests/proxy.yaml +++ b/cmd/k8s-operator/deploy/manifests/proxy.yaml @@ -16,12 +16,12 @@ spec: privileged: true command: ["/bin/sh", "-c"] args: [sysctl -w net.ipv4.ip_forward=1 && if sysctl net.ipv6.conf.all.forwarding; then sysctl -w net.ipv6.conf.all.forwarding=1; fi] - resources: - requests: - cpu: 1m - memory: 1Mi containers: - name: tailscale + resources: + requests: + cpu: 1m + memory: 1Mi imagePullPolicy: Always env: - name: TS_USERSPACE diff --git a/cmd/k8s-operator/deploy/manifests/userspace-proxy.yaml b/cmd/k8s-operator/deploy/manifests/userspace-proxy.yaml index 6617f6d4b..f93ab5855 100644 --- a/cmd/k8s-operator/deploy/manifests/userspace-proxy.yaml +++ b/cmd/k8s-operator/deploy/manifests/userspace-proxy.yaml @@ -10,12 +10,12 @@ spec: deletionGracePeriodSeconds: 10 spec: serviceAccountName: proxies - resources: - requests: - cpu: 1m - memory: 1Mi containers: - name: tailscale + resources: + requests: + cpu: 1m + memory: 1Mi imagePullPolicy: Always env: - name: TS_USERSPACE diff --git a/cmd/k8s-operator/ingress_test.go b/cmd/k8s-operator/ingress_test.go index 038c746a9..52afc3be4 100644 --- a/cmd/k8s-operator/ingress_test.go +++ b/cmd/k8s-operator/ingress_test.go @@ -15,6 +15,7 @@ import ( corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/tools/record" @@ -70,7 +71,8 @@ func TestTailscaleIngress(t *testing.T) { Web: map[ipn.HostPort]*ipn.WebServerConfig{ "${TS_CERT_DOMAIN}:443": {Handlers: map[string]*ipn.HTTPHandler{ "/": {Proxy: "http://1.2.3.4:8080/"}, - }}}, + }}, + }, }, } @@ -164,7 +166,8 @@ func TestTailscaleIngressHostname(t *testing.T) { Web: map[ipn.HostPort]*ipn.WebServerConfig{ "${TS_CERT_DOMAIN}:443": {Handlers: map[string]*ipn.HTTPHandler{ "/": {Proxy: "http://1.2.3.4:8080/"}, - }}}, + }}, + }, }, } @@ -238,7 +241,17 @@ func TestTailscaleIngressWithProxyClass(t *testing.T) { Spec: tsapi.ProxyClassSpec{StatefulSet: &tsapi.StatefulSet{ Labels: tsapi.Labels{"foo": "bar"}, Annotations: map[string]string{"bar.io/foo": "some-val"}, - Pod: &tsapi.Pod{Annotations: map[string]string{"foo.io/bar": "some-val"}}, + Pod: &tsapi.Pod{ + Annotations: map[string]string{"foo.io/bar": "some-val"}, + TailscaleContainer: &tsapi.Container{ + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("500m"), + corev1.ResourceMemory: resource.MustParse("28Mi"), + }, + }, + }, + }, }}, } fc := fake.NewClientBuilder(). @@ -286,13 +299,14 @@ func TestTailscaleIngressWithProxyClass(t *testing.T) { Web: map[ipn.HostPort]*ipn.WebServerConfig{ "${TS_CERT_DOMAIN}:443": {Handlers: map[string]*ipn.HTTPHandler{ "/": {Proxy: "http://1.2.3.4:8080/"}, - }}}, + }}, + }, }, } expectEqual(t, fc, expectedSecret(t, fc, opts)) expectEqual(t, fc, expectedHeadlessService(shortName, "ingress")) - expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeResourceReqs) + expectEqual(t, fc, expectedSTSUserspace(t, fc, opts)) // 2. Ingress is updated to specify a ProxyClass, ProxyClass is not yet // ready, so proxy resource configuration does not change. @@ -300,7 +314,7 @@ func TestTailscaleIngressWithProxyClass(t *testing.T) { mak.Set(&ing.ObjectMeta.Labels, LabelAnnotationProxyClass, "custom-metadata") }) expectReconciled(t, ingR, "default", "test") - expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeResourceReqs) + expectEqual(t, fc, expectedSTSUserspace(t, fc, opts)) // 3. ProxyClass is set to Ready by proxy-class reconciler. Ingress get // reconciled and configuration from the ProxyClass is applied to the @@ -316,7 +330,7 @@ func TestTailscaleIngressWithProxyClass(t *testing.T) { }) expectReconciled(t, ingR, "default", "test") opts.proxyClass = pc.Name - expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeResourceReqs) + expectEqual(t, fc, expectedSTSUserspace(t, fc, opts)) // 4. tailscale.com/proxy-class label is removed from the Ingress, the // Ingress gets reconciled and the custom ProxyClass configuration is @@ -390,7 +404,8 @@ func TestTailscaleIngressWithServiceMonitor(t *testing.T) { Web: map[ipn.HostPort]*ipn.WebServerConfig{ "${TS_CERT_DOMAIN}:443": {Handlers: map[string]*ipn.HTTPHandler{ "/": {Proxy: "http://1.2.3.4:8080/"}, - }}}, + }}, + }, }, resourceVersion: "1", } @@ -731,7 +746,8 @@ func TestEmptyPath(t *testing.T) { Web: map[ipn.HostPort]*ipn.WebServerConfig{ "${TS_CERT_DOMAIN}:443": {Handlers: map[string]*ipn.HTTPHandler{ "/": {Proxy: "http://1.2.3.4:8080/"}, - }}}, + }}, + }, }, } @@ -764,9 +780,11 @@ func service() *corev1.Service { }, Spec: corev1.ServiceSpec{ ClusterIP: "1.2.3.4", - Ports: []corev1.ServicePort{{ - Port: 8080, - Name: "http"}, + Ports: []corev1.ServicePort{ + { + Port: 8080, + Name: "http", + }, }, }, } diff --git a/cmd/k8s-operator/sts.go b/cmd/k8s-operator/sts.go index 3e4e72696..62f91bf92 100644 --- a/cmd/k8s-operator/sts.go +++ b/cmd/k8s-operator/sts.go @@ -922,7 +922,17 @@ func applyProxyClassToStatefulSet(pc *tsapi.ProxyClass, ss *appsv1.StatefulSet, if overlay.SecurityContext != nil { base.SecurityContext = overlay.SecurityContext } - base.Resources = overlay.Resources + + if len(overlay.Resources.Requests) > 0 { + base.Resources.Requests = overlay.Resources.Requests + } + if len(overlay.Resources.Limits) > 0 { + base.Resources.Limits = overlay.Resources.Limits + } + if len(overlay.Resources.Claims) > 0 { + base.Resources.Limits = overlay.Resources.Limits + } + for _, e := range overlay.Env { // Env vars configured via ProxyClass might override env // vars that have been specified by the operator, i.e diff --git a/cmd/k8s-operator/testutils_test.go b/cmd/k8s-operator/testutils_test.go index b4c468c8e..9eb06394c 100644 --- a/cmd/k8s-operator/testutils_test.go +++ b/cmd/k8s-operator/testutils_test.go @@ -23,6 +23,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/types" @@ -95,6 +96,12 @@ func expectedSTS(t *testing.T, cl client.Client, opts configOpts) *appsv1.Statef SecurityContext: &corev1.SecurityContext{ Privileged: ptr.To(true), }, + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1m"), + corev1.ResourceMemory: resource.MustParse("1Mi"), + }, + }, ImagePullPolicy: "Always", } if opts.shouldEnableForwardingClusterTrafficViaIngress { @@ -288,6 +295,12 @@ func expectedSTSUserspace(t *testing.T, cl client.Client, opts configOpts) *apps {Name: "tailscaledconfig-0", ReadOnly: true, MountPath: path.Join("/etc/tsconfig", opts.secretName)}, {Name: "serve-config-0", ReadOnly: true, MountPath: path.Join("/etc/tailscaled", opts.secretName)}, }, + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1m"), + corev1.ResourceMemory: resource.MustParse("1Mi"), + }, + }, } if opts.enableMetrics { tsContainer.Env = append(tsContainer.Env,