From d45faced13f245e5017ae7ddee523882ff0d6255 Mon Sep 17 00:00:00 2001 From: Benjamin Gentil Date: Mon, 27 Jul 2026 11:31:25 +0200 Subject: [PATCH] feat(api): add automountServiceAccountToken field for control-plane deployment (#1219) This field allows disabling the automatic mounting of the service account token to the control-plane deployment pods. --- api/v1alpha1/tenantcontrolplane_types.go | 2 + api/v1alpha1/zz_generated.deepcopy.go | 5 +++ ...i.clastix.io_tenantcontrolplanes_spec.yaml | 3 ++ ...kamaji.clastix.io_tenantcontrolplanes.yaml | 3 ++ docs/content/reference/api.md | 7 ++++ internal/builders/controlplane/deployment.go | 2 + .../builders/controlplane/deployment_test.go | 40 +++++++++++++++++++ 7 files changed, 62 insertions(+) diff --git a/api/v1alpha1/tenantcontrolplane_types.go b/api/v1alpha1/tenantcontrolplane_types.go index 9174a72..14b5b19 100644 --- a/api/v1alpha1/tenantcontrolplane_types.go +++ b/api/v1alpha1/tenantcontrolplane_types.go @@ -327,6 +327,8 @@ type DeploymentSpec struct { //+kubebuilder:default="default" // ServiceAccountName allows to specify the service account to be mounted to the pods of the Control plane deployment ServiceAccountName string `json:"serviceAccountName,omitempty"` + // AutomountServiceAccountToken allows to enable the automatic mounting of the service account token to the pods of the Control plane deployment + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty"` // ContainerSecurityContexts allows to specify the security context for the individual control plane components. ContainerSecurityContexts *ControlPlaneContainerSecurityContexts `json:"containerSecurityContexts,omitempty"` // PodSecurityContext allows to specify the security context for the control plane pod. diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index a83069e..c9b8ecd 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -797,6 +797,11 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { *out = new(ControlPlaneProbes) (*in).DeepCopyInto(*out) } + if in.AutomountServiceAccountToken != nil { + in, out := &in.AutomountServiceAccountToken, &out.AutomountServiceAccountToken + *out = new(bool) + **out = **in + } if in.ContainerSecurityContexts != nil { in, out := &in.ContainerSecurityContexts, &out.ContainerSecurityContexts *out = new(ControlPlaneContainerSecurityContexts) diff --git a/charts/kamaji-crds/hack/kamaji.clastix.io_tenantcontrolplanes_spec.yaml b/charts/kamaji-crds/hack/kamaji.clastix.io_tenantcontrolplanes_spec.yaml index 360b750..9debdfd 100644 --- a/charts/kamaji-crds/hack/kamaji.clastix.io_tenantcontrolplanes_spec.yaml +++ b/charts/kamaji-crds/hack/kamaji.clastix.io_tenantcontrolplanes_spec.yaml @@ -6301,6 +6301,9 @@ versions: x-kubernetes-list-type: atomic type: object type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken allows to enable the automatic mounting of the service account token to the pods of the Control plane deployment + type: boolean containerSecurityContexts: description: ContainerSecurityContexts allows to specify the security context for the individual control plane components. properties: diff --git a/charts/kamaji/crds/kamaji.clastix.io_tenantcontrolplanes.yaml b/charts/kamaji/crds/kamaji.clastix.io_tenantcontrolplanes.yaml index 0e4411a..70dd8e0 100644 --- a/charts/kamaji/crds/kamaji.clastix.io_tenantcontrolplanes.yaml +++ b/charts/kamaji/crds/kamaji.clastix.io_tenantcontrolplanes.yaml @@ -6309,6 +6309,9 @@ spec: x-kubernetes-list-type: atomic type: object type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken allows to enable the automatic mounting of the service account token to the pods of the Control plane deployment + type: boolean containerSecurityContexts: description: ContainerSecurityContexts allows to specify the security context for the individual control plane components. properties: diff --git a/docs/content/reference/api.md b/docs/content/reference/api.md index d5b9be3..998dd77 100644 --- a/docs/content/reference/api.md +++ b/docs/content/reference/api.md @@ -31345,6 +31345,13 @@ Defining the options for the deployed Tenant Control Plane as Deployment resourc More info: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/
false + + automountServiceAccountToken + boolean + + AutomountServiceAccountToken allows to enable the automatic mounting of the service account token to the pods of the Control plane deployment
+ + false containerSecurityContexts object diff --git a/internal/builders/controlplane/deployment.go b/internal/builders/controlplane/deployment.go index 50e9956..101bc86 100644 --- a/internal/builders/controlplane/deployment.go +++ b/internal/builders/controlplane/deployment.go @@ -1213,6 +1213,8 @@ func (d Deployment) setAffinity(spec *corev1.PodSpec, tcp kamajiv1alpha1.TenantC } func (d Deployment) setServiceAccount(spec *corev1.PodSpec, tcp kamajiv1alpha1.TenantControlPlane) { + spec.AutomountServiceAccountToken = tcp.Spec.ControlPlane.Deployment.AutomountServiceAccountToken + if len(tcp.Spec.ControlPlane.Deployment.ServiceAccountName) > 0 { spec.ServiceAccountName = tcp.Spec.ControlPlane.Deployment.ServiceAccountName diff --git a/internal/builders/controlplane/deployment_test.go b/internal/builders/controlplane/deployment_test.go index 2c19e68..fd51e57 100644 --- a/internal/builders/controlplane/deployment_test.go +++ b/internal/builders/controlplane/deployment_test.go @@ -284,4 +284,44 @@ var _ = Describe("Controlplane Deployment", func() { Expect(c.ReadinessProbe.HTTPGet.Port.IntValue()).To(Equal(6443)) }) }) + + Describe("ServiceAccount", func() { + It("should default to 'default' SA with nil automount", func() { + podSpec := &corev1.PodSpec{} + tcp := kamajiv1alpha1.TenantControlPlane{} + d.setServiceAccount(podSpec, tcp) + Expect(podSpec.ServiceAccountName).To(Equal("default")) + Expect(podSpec.AutomountServiceAccountToken).To(BeNil()) + }) + + It("should set a custom SA name with nil automount", func() { + podSpec := &corev1.PodSpec{} + tcp := kamajiv1alpha1.TenantControlPlane{} + tcp.Spec.ControlPlane.Deployment.ServiceAccountName = "custom-sa" + d.setServiceAccount(podSpec, tcp) + Expect(podSpec.ServiceAccountName).To(Equal("custom-sa")) + Expect(podSpec.AutomountServiceAccountToken).To(BeNil()) + }) + + It("should enable automount when AutomountServiceAccountToken is true", func() { + podSpec := &corev1.PodSpec{} + tcp := kamajiv1alpha1.TenantControlPlane{} + tcp.Spec.ControlPlane.Deployment.AutomountServiceAccountToken = pointer.To(true) + d.setServiceAccount(podSpec, tcp) + Expect(podSpec.ServiceAccountName).To(Equal("default")) + Expect(podSpec.AutomountServiceAccountToken).ToNot(BeNil()) + Expect(*podSpec.AutomountServiceAccountToken).To(BeTrue()) + }) + + It("should disable automount when AutomountServiceAccountToken is false", func() { + podSpec := &corev1.PodSpec{} + tcp := kamajiv1alpha1.TenantControlPlane{} + tcp.Spec.ControlPlane.Deployment.AutomountServiceAccountToken = pointer.To(false) + tcp.Spec.ControlPlane.Deployment.ServiceAccountName = "another-sa" + d.setServiceAccount(podSpec, tcp) + Expect(podSpec.ServiceAccountName).To(Equal("another-sa")) + Expect(podSpec.AutomountServiceAccountToken).ToNot(BeNil()) + Expect(*podSpec.AutomountServiceAccountToken).To(BeFalse()) + }) + }) })