From 2a2abb30900e644bb588cf6f044228da6484a57e Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Tue, 17 Mar 2026 14:41:11 +0100 Subject: [PATCH] WIP --- .../stackit-alb-controller-manager/Chart.yaml | 4 - .../values.yaml | 17 ---- .../Chart.yaml | 4 + .../templates/configmap.yaml | 21 +++++ .../templates/poddisruptionbudget.yaml | 15 ++++ ...application-load-balancer-controller.yaml} | 45 +++++------ .../templates/vpa.yaml | 6 +- .../values.yaml | 21 +++++ charts/internal/seed-controlplane/values.yaml | 4 +- .../app/app.go | 4 +- hack/api-reference/api.md | 56 ++++++++++++- hack/api-reference/config.md | 5 +- imagevector/images.go | 4 +- imagevector/images.yaml | 8 +- pkg/apis/config/types.go | 5 +- pkg/apis/config/v1alpha1/types.go | 6 +- .../v1alpha1/zz_generated.conversion.go | 4 +- .../stackit/v1alpha1/types_cloudprofile.go | 4 +- .../stackit/v1alpha1/types_controlplane.go | 14 ++++ .../stackit/v1alpha1/zz_generated.deepcopy.go | 27 ++++++- pkg/apis/stackit/validation/controlplane.go | 24 ++++++ pkg/cmd/config.go | 4 +- pkg/controller/controlplane/add.go | 7 +- pkg/controller/controlplane/valuesprovider.go | 80 ++++++++++--------- .../controlplane/valuesprovider_test.go | 16 ++-- pkg/controller/healthcheck/add.go | 46 ++++++----- pkg/openstack/types.go | 4 +- 27 files changed, 313 insertions(+), 142 deletions(-) delete mode 100644 charts/internal/seed-controlplane/charts/stackit-alb-controller-manager/Chart.yaml delete mode 100644 charts/internal/seed-controlplane/charts/stackit-alb-controller-manager/values.yaml create mode 100644 charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/Chart.yaml create mode 100644 charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/templates/configmap.yaml create mode 100644 charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/templates/poddisruptionbudget.yaml rename charts/internal/seed-controlplane/charts/{stackit-alb-controller-manager/templates/alb-controller-manager.yaml => stackit-application-load-balancer-controller/templates/stackit-application-load-balancer-controller.yaml} (72%) rename charts/internal/seed-controlplane/charts/{stackit-alb-controller-manager => stackit-application-load-balancer-controller}/templates/vpa.yaml (73%) create mode 100644 charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/values.yaml diff --git a/charts/internal/seed-controlplane/charts/stackit-alb-controller-manager/Chart.yaml b/charts/internal/seed-controlplane/charts/stackit-alb-controller-manager/Chart.yaml deleted file mode 100644 index bddaaec5..00000000 --- a/charts/internal/seed-controlplane/charts/stackit-alb-controller-manager/Chart.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -description: Helm chart for STACKIT stackit-alb-controller-manager -name: stackit-alb-controller-manager -version: 0.1.0 diff --git a/charts/internal/seed-controlplane/charts/stackit-alb-controller-manager/values.yaml b/charts/internal/seed-controlplane/charts/stackit-alb-controller-manager/values.yaml deleted file mode 100644 index 321616eb..00000000 --- a/charts/internal/seed-controlplane/charts/stackit-alb-controller-manager/values.yaml +++ /dev/null @@ -1,17 +0,0 @@ -replicas: 1 -config: - region: "" -# stackitNetworkID: foo -# stackitProjectID: foo -# region: foo -# applicationLBApiUrl: foo -# certificateApiUrl: foo -podAnnotations: {} -podLabels: {} -images: - stackit-alb-controller-manager: image:tag -vpa: - resourcePolicy: - maxAllowed: - cpu: 1 - memory: 512Mi diff --git a/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/Chart.yaml b/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/Chart.yaml new file mode 100644 index 00000000..c2cf00b0 --- /dev/null +++ b/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: Helm chart for STACKIT stackit-application-load-balancer-controller +name: stackit-application-load-balancer-controller +version: 0.1.0 diff --git a/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/templates/configmap.yaml b/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/templates/configmap.yaml new file mode 100644 index 00000000..e3f4ec1c --- /dev/null +++ b/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/templates/configmap.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: stackit-application-load-balancer-controller + namespace: {{ .Release.Namespace }} +data: + cloud.yaml: |- + global: + region: {{ .Values.config.global.region }} + projectId: {{ .Values.config.global.projectId }} + {{- with .Values.config.global.apiEndpoints }} + apiEndpoints: + {{- if .applicationLoadBalancerApi }} + applicationLoadBalancerApi: {{ .applicationLoadBalancerApi }} + {{- end }} + {{- if .applicationLoadBalancerCertificateApi }} + applicationLoadBalancerCertificateApi: {{ .applicationLoadBalancerCertificateApi }} + {{- end }} + {{- end }} + applicationLoadBalancer: + networkId: {{ .Values.config.applicationLoadBalancer.networkId }} diff --git a/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/templates/poddisruptionbudget.yaml b/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/templates/poddisruptionbudget.yaml new file mode 100644 index 00000000..09a23e85 --- /dev/null +++ b/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/templates/poddisruptionbudget.yaml @@ -0,0 +1,15 @@ +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: stackit-application-load-balancer-controller + namespace: {{ .Release.Namespace }} + labels: + app: kubernetes + role: stackit-application-load-balancer-controller +spec: + maxUnavailable: 1 + selector: + matchLabels: + app: kubernetes + role: stackit-application-load-balancer-controller + unhealthyPodEvictionPolicy: AlwaysAllow diff --git a/charts/internal/seed-controlplane/charts/stackit-alb-controller-manager/templates/alb-controller-manager.yaml b/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/templates/stackit-application-load-balancer-controller.yaml similarity index 72% rename from charts/internal/seed-controlplane/charts/stackit-alb-controller-manager/templates/alb-controller-manager.yaml rename to charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/templates/stackit-application-load-balancer-controller.yaml index 6ab8baf8..2f6f8cea 100644 --- a/charts/internal/seed-controlplane/charts/stackit-alb-controller-manager/templates/alb-controller-manager.yaml +++ b/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/templates/stackit-application-load-balancer-controller.yaml @@ -1,11 +1,11 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: stackit-alb-controller-manager + name: stackit-application-load-balancer-controller namespace: {{ .Release.Namespace }} labels: app: kubernetes - role: stackit-alb-controller-manager + role: stackit-application-load-balancer-controller high-availability-config.resources.gardener.cloud/type: controller spec: replicas: {{ .Values.replicas }} @@ -13,7 +13,7 @@ spec: selector: matchLabels: app: kubernetes - role: stackit-alb-controller-manager + role: stackit-application-load-balancer-controller template: metadata: {{- if .Values.podAnnotations }} @@ -23,7 +23,7 @@ spec: labels: gardener.cloud/role: controlplane app: kubernetes - role: stackit-alb-controller-manager + role: stackit-application-load-balancer-controller networking.gardener.cloud/to-dns: allowed networking.gardener.cloud/to-public-networks: allowed networking.gardener.cloud/to-private-networks: allowed @@ -36,35 +36,26 @@ spec: automountServiceAccountToken: false priorityClassName: gardener-system-300 containers: - - name: stackit-alb-controller-manager - image: {{ index .Values.images "stackit-alb-controller-manager" }} + - name: stackit-application-load-balancer-controller + image: {{ index .Values.images "stackit-application-load-balancer-controller" }} args: - --kubeconfig=/var/run/secrets/gardener.cloud/shoot/generic-kubeconfig/kubeconfig - --leader-elect=true + - --metrics-bind-address=":{{ .Values.config.metricsPort }}" - --leader-election-namespace=kube-system - - --leader-election-id=stackit-alb-controller-manager + - --leader-election-id=stackit-application-load-balancer-controller + - --cloud-config=/etc/config/cloud.yaml env: - name: STACKIT_SERVICE_ACCOUNT_KEY_PATH value: /etc/serviceaccount/serviceaccount.json - - name: STACKIT_REGION - value: {{ .Values.config.region }} - - name: PROJECT_ID - value: {{ .Values.config.stackitProjectID }} - - name: NETWORK_ID - value: {{ .Values.config.stackitNetworkID }} - -{{- if .Values.config.tokenUrl }} +{{- if .Values.tokenEndpoint }} - name: STACKIT_TOKEN_BASEURL - value: {{ .Values.config.tokenUrl }} -{{- end }} -{{- if .Values.config.applicationLBApiUrl }} - - name: STACKIT_LOAD_BALANCER_API_ALB_URL - value: {{ .Values.config.applicationLBApiUrl }} -{{- end }} -{{- if .Values.config.certificateApiUrl }} - - name: STACKIT_LOAD_BALANCER_API_CERT_URL - value: {{ .Values.config.certificateApiUrl }} + value: {{ .Values.tokenEndpoint }} {{- end }} + ports: + - containerPort: {{ .Values.metricsPort }} + name: metrics + protocol: TCP {{- if .Values.resources }} resources: {{ toYaml .Values.resources | indent 10 }} @@ -73,6 +64,8 @@ spec: - mountPath: /var/run/secrets/gardener.cloud/shoot/generic-kubeconfig name: kubeconfig readOnly: true + - mountPath: /etc/config + name: config-volume - mountPath: /etc/serviceaccount name: sa-secret - mountPath: /etc/ssl/certs/keystone-ca.crt @@ -80,6 +73,10 @@ spec: subPath: keystone-ca.crt readOnly: true volumes: + - name: config-volume + configMap: + defaultMode: 420 + name: stackit-application-load-balancer-controller - name: sa-secret secret: defaultMode: 420 diff --git a/charts/internal/seed-controlplane/charts/stackit-alb-controller-manager/templates/vpa.yaml b/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/templates/vpa.yaml similarity index 73% rename from charts/internal/seed-controlplane/charts/stackit-alb-controller-manager/templates/vpa.yaml rename to charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/templates/vpa.yaml index 28ca5342..27137bf1 100644 --- a/charts/internal/seed-controlplane/charts/stackit-alb-controller-manager/templates/vpa.yaml +++ b/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/templates/vpa.yaml @@ -1,18 +1,18 @@ apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler metadata: - name: stackit-alb-controller-manager-vpa + name: stackit-application-load-balancer-controller namespace: {{ .Release.Namespace }} spec: targetRef: apiVersion: apps/v1 kind: Deployment - name: stackit-alb-controller-manager + name: stackit-application-load-balancer-controller updatePolicy: updateMode: Auto resourcePolicy: containerPolicies: - - containerName: stackit-alb-controller-manager + - containerName: stackit-application-load-balancer-controller minAllowed: memory: 80M maxAllowed: diff --git a/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/values.yaml b/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/values.yaml new file mode 100644 index 00000000..14d889bc --- /dev/null +++ b/charts/internal/seed-controlplane/charts/stackit-application-load-balancer-controller/values.yaml @@ -0,0 +1,21 @@ +replicas: 1 +config: + global: + region: "" + projectId: "" + # apiEndpoints: + # applicationLoadBalancerApi: "foo" + # applicationLoadBalancerCertificateApi: "foo" + applicationLoadBalancer: + networkId: "" +#tokenEndpoint: "foo" +metricsPort: 9090 +podAnnotations: {} +podLabels: {} +images: + stackit-alb-controller-manager: image:tag +vpa: + resourcePolicy: + maxAllowed: + cpu: 1 + memory: 512Mi diff --git a/charts/internal/seed-controlplane/values.yaml b/charts/internal/seed-controlplane/values.yaml index 8cf3a7ad..e561e5c2 100644 --- a/charts/internal/seed-controlplane/values.yaml +++ b/charts/internal/seed-controlplane/values.yaml @@ -6,7 +6,7 @@ stackit-cloud-controller-manager: enabled: false csi-driver-controller: enabled: true -stackit-alb-controller-manager: +stackit-application-load-balancer-controller: enabled: false stackit-pod-identity-webhook: - enabled: false \ No newline at end of file + enabled: false diff --git a/cmd/gardener-extension-provider-stackit/app/app.go b/cmd/gardener-extension-provider-stackit/app/app.go index 92d1770f..391a84f5 100644 --- a/cmd/gardener-extension-provider-stackit/app/app.go +++ b/cmd/gardener-extension-provider-stackit/app/app.go @@ -190,11 +190,11 @@ func NewControllerManagerCommand(ctx context.Context) *cobra.Command { configFileOpts.Completed().ApplyETCDStorage(&stackitseedprovider.DefaultAddOptions.ETCDStorage) configFileOpts.Completed().ApplyHealthCheckConfig(&healthcheck.DefaultAddOptions.HealthCheckConfig) configFileOpts.Completed().ApplyRegistryCaches(&stackitwebhookcontrolplane.DefaultAddOptions.RegistryCaches) - configFileOpts.Completed().ApplyDeployALBIngressController(&stackitcontrolplane.DeployALBIngressController) + configFileOpts.Completed().ApplyAllowApplicationLoadBalancerController(&stackitcontrolplane.DefaultAddOptions.AllowApplicationLoadBalancerController) + configFileOpts.Completed().ApplyAllowApplicationLoadBalancerController(&healthcheck.DefaultAddOptions.AllowApplicationLoadBalancerController) configFileOpts.Completed().ApplyCustomLabelDomain(&stackitworker.DefaultAddOptions.CustomLabelDomain) configFileOpts.Completed().ApplyCustomLabelDomain(&stackitcontrolplane.DefaultAddOptions.CustomLabelDomain) configFileOpts.Completed().ApplyCustomLabelDomain(&infrastructure.DefaultAddOptions.CustomLabelDomain) - log.Info("DeployALBIngressController?", "deploy", configFileOpts.Completed().Config.DeployALBIngressController) bastionCtrlOpts.Completed().Apply(&stackitbastion.DefaultAddOptions.Controller) configFileOpts.Completed().ApplyCustomLabelDomain(&stackitbastion.DefaultAddOptions.CustomLabelDomain) diff --git a/hack/api-reference/api.md b/hack/api-reference/api.md index 77bdac1f..b92cb114 100644 --- a/hack/api-reference/api.md +++ b/hack/api-reference/api.md @@ -81,14 +81,14 @@ string -loadbalancerCertificate
+applicationLoadBalancerCertificate
string (Optional) -

LoadbalancerCertificate is the Endpoint of the LoadBalancerCertificate API.

+

ApplicationLoadBalancerCertificate is the Endpoint of the ApplicationLoadBalancerCertificate API.

@@ -155,7 +155,57 @@ string array

+ApplicationLoadBalancerConfig defines the configuration for the +Application Load Balancer (ALB) integration. +

+ + + + + + + + + + + + + + + + + + + +
FieldDescription
+enabled
+ +boolean + +
+

Enabled specifies whether the Application Load Balancer is activated.

+
+ingress
+ +ApplicationLoadBalancerConfigIngress + +
+

Ingress contains the configuration specific to the ALB's Ingress controller.

+
+ + +

ApplicationLoadBalancerConfigIngress +

+ + +

+(Appears on:ApplicationLoadBalancerConfig) +

+ +

+ApplicationLoadBalancerConfigIngress defines the settings for the +Application Load Balancer Ingress resources.

@@ -175,7 +225,7 @@ boolean diff --git a/hack/api-reference/config.md b/hack/api-reference/config.md index bc0036a3..5db40e6f 100644 --- a/hack/api-reference/config.md +++ b/hack/api-reference/config.md @@ -76,13 +76,14 @@ ControllerConfiguration defines the configuration for the STACKIT provider. diff --git a/imagevector/images.go b/imagevector/images.go index c7e393d5..9d8cdeb8 100644 --- a/imagevector/images.go +++ b/imagevector/images.go @@ -31,8 +31,8 @@ const ( ImageNameMachineControllerManagerProviderOpenstack = "machine-controller-manager-provider-openstack" // ImageNameMachineControllerManagerProviderStackit is a constant for an image in the image vector with name 'machine-controller-manager-provider-stackit'. ImageNameMachineControllerManagerProviderStackit = "machine-controller-manager-provider-stackit" - // ImageNameStackitAlbControllerManager is a constant for an image in the image vector with name 'stackit-alb-controller-manager'. - ImageNameStackitAlbControllerManager = "stackit-alb-controller-manager" + // ImageNameStackitApplicationLoadBalancerController is a constant for an image in the image vector with name 'stackit-application-load-balancer-controller'. + ImageNameStackitApplicationLoadBalancerController = "stackit-application-load-balancer-controller" // ImageNameStackitCloudControllerManager is a constant for an image in the image vector with name 'stackit-cloud-controller-manager'. ImageNameStackitCloudControllerManager = "stackit-cloud-controller-manager" // ImageNameStackitPodIdentityWebhook is a constant for an image in the image vector with name 'stackit-pod-identity-webhook'. diff --git a/imagevector/images.yaml b/imagevector/images.yaml index 928d3fc3..fad709bb 100644 --- a/imagevector/images.yaml +++ b/imagevector/images.yaml @@ -132,9 +132,11 @@ images: repository: registry.k8s.io/sig-storage/livenessprobe tag: "v2.18.0" -- name: stackit-alb-controller-manager - repository: reg3.infra.ske.eu01.stackit.cloud/temp/alb-controller-manager - tag: "1245" +- name: stackit-application-load-balancer-controller + sourceRepository: github.com/stackitcloud/application-load-balancer-controller + repository: ghcr.io/stackitcloud/application-load-balancer-controller-dev + tag: "albc" + - name: stackit-pod-identity-webhook sourceRepository: github.com/stackitcloud/stackit-pod-identity-webhook repository: ghcr.io/stackitcloud/stackit-pod-identity-webhook diff --git a/pkg/apis/config/types.go b/pkg/apis/config/types.go index 4eed9a47..d0f061e0 100644 --- a/pkg/apis/config/types.go +++ b/pkg/apis/config/types.go @@ -31,8 +31,9 @@ type ControllerConfiguration struct { // Deprecated: will be removed in a future version RegistryCaches []RegistryCacheConfiguration - // DeployALBIngressController - DeployALBIngressController bool + // AllowApplicationLoadBalancerController specifies whether the application load balancer controller can + // be enabled in the ControlPlane configuration of the Shoot cluster. + AllowApplicationLoadBalancerController bool // CustomLabelDomain is the domain prefix for custom labels applied to STACKIT infrastructure resources. // For example, cluster labels will use "/cluster" (default: "kubernetes.io"). diff --git a/pkg/apis/config/v1alpha1/types.go b/pkg/apis/config/v1alpha1/types.go index f6570f88..c65b697c 100644 --- a/pkg/apis/config/v1alpha1/types.go +++ b/pkg/apis/config/v1alpha1/types.go @@ -33,8 +33,10 @@ type ControllerConfiguration struct { // +optional RegistryCaches []RegistryCacheConfiguration `json:"registryCaches,omitempty"` - // DeployALBIngressController - DeployALBIngressController bool `json:"deployALBIngressController"` + // AllowApplicationLoadBalancerController specifies whether the application load balancer controller can + // be enabled in the ControlPlane configuration of the Shoot cluster. + // +optional + AllowApplicationLoadBalancerController bool `json:"allowApplicationLoadBalancerController,omitempty"` // CustomLabelDomain is the domain prefix for custom labels applied to STACKIT infrastructure resources. // For example, cluster labels will use "/cluster" (default: "kubernetes.io"). diff --git a/pkg/apis/config/v1alpha1/zz_generated.conversion.go b/pkg/apis/config/v1alpha1/zz_generated.conversion.go index a870fc9c..1e29f17e 100644 --- a/pkg/apis/config/v1alpha1/zz_generated.conversion.go +++ b/pkg/apis/config/v1alpha1/zz_generated.conversion.go @@ -85,7 +85,7 @@ func autoConvert_v1alpha1_ControllerConfiguration_To_config_ControllerConfigurat } out.HealthCheckConfig = (*apisconfigv1alpha1.HealthCheckConfig)(unsafe.Pointer(in.HealthCheckConfig)) out.RegistryCaches = *(*[]config.RegistryCacheConfiguration)(unsafe.Pointer(&in.RegistryCaches)) - out.DeployALBIngressController = in.DeployALBIngressController + out.AllowApplicationLoadBalancerController = in.AllowApplicationLoadBalancerController out.CustomLabelDomain = in.CustomLabelDomain return nil } @@ -102,7 +102,7 @@ func autoConvert_config_ControllerConfiguration_To_v1alpha1_ControllerConfigurat } out.HealthCheckConfig = (*apisconfigv1alpha1.HealthCheckConfig)(unsafe.Pointer(in.HealthCheckConfig)) out.RegistryCaches = *(*[]RegistryCacheConfiguration)(unsafe.Pointer(&in.RegistryCaches)) - out.DeployALBIngressController = in.DeployALBIngressController + out.AllowApplicationLoadBalancerController = in.AllowApplicationLoadBalancerController out.CustomLabelDomain = in.CustomLabelDomain return nil } diff --git a/pkg/apis/stackit/v1alpha1/types_cloudprofile.go b/pkg/apis/stackit/v1alpha1/types_cloudprofile.go index 38a3ad36..d856e793 100644 --- a/pkg/apis/stackit/v1alpha1/types_cloudprofile.go +++ b/pkg/apis/stackit/v1alpha1/types_cloudprofile.go @@ -217,9 +217,9 @@ type APIEndpoints struct { // ApplicationLoadBalancer is the Endpoint of the Application LoadBalancer API. // +optional ApplicationLoadBalancer *string `json:"applicationLoadBalancer,omitempty"` - // LoadbalancerCertificate is the Endpoint of the LoadBalancerCertificate API. + // ApplicationLoadBalancerCertificate is the Endpoint of the ApplicationLoadBalancerCertificate API. // +optional - LoadBalancerCertificate *string `json:"loadbalancerCertificate,omitempty"` + ApplicationLoadBalancerCertificate *string `json:"applicationLoadBalancerCertificate,omitempty"` // TokenEndpoint is the token endpoint URL. // +optional TokenEndpoint *string `json:"tokenEndpoint,omitempty"` diff --git a/pkg/apis/stackit/v1alpha1/types_controlplane.go b/pkg/apis/stackit/v1alpha1/types_controlplane.go index 5c10c28a..35020bba 100644 --- a/pkg/apis/stackit/v1alpha1/types_controlplane.go +++ b/pkg/apis/stackit/v1alpha1/types_controlplane.go @@ -33,7 +33,21 @@ type ControlPlaneConfig struct { ApplicationLoadBalancer *ApplicationLoadBalancerConfig `json:"applicationLoadBalancer,omitempty"` } +// ApplicationLoadBalancerConfig defines the configuration for the +// Application Load Balancer (ALB) integration. type ApplicationLoadBalancerConfig struct { + // Enabled specifies whether the Application Load Balancer is activated. + Enabled bool `json:"enabled"` + + // Ingress contains the configuration specific to the ALB's Ingress controller. + Ingress *ApplicationLoadBalancerConfigIngress `json:"ingress,omitempty"` +} + +// ApplicationLoadBalancerConfigIngress defines the settings for the +// Application Load Balancer Ingress resources. +type ApplicationLoadBalancerConfigIngress struct { + // Enabled specifies whether the Ingress controller functionality + // for the ALB is activated to manage external access to services. Enabled bool `json:"enabled"` } diff --git a/pkg/apis/stackit/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/stackit/v1alpha1/zz_generated.deepcopy.go index aa21ec41..6d0c32e7 100644 --- a/pkg/apis/stackit/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/stackit/v1alpha1/zz_generated.deepcopy.go @@ -36,8 +36,8 @@ func (in *APIEndpoints) DeepCopyInto(out *APIEndpoints) { *out = new(string) **out = **in } - if in.LoadBalancerCertificate != nil { - in, out := &in.LoadBalancerCertificate, &out.LoadBalancerCertificate + if in.ApplicationLoadBalancerCertificate != nil { + in, out := &in.ApplicationLoadBalancerCertificate, &out.ApplicationLoadBalancerCertificate *out = new(string) **out = **in } @@ -83,6 +83,11 @@ func (in *AccessControl) DeepCopy() *AccessControl { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ApplicationLoadBalancerConfig) DeepCopyInto(out *ApplicationLoadBalancerConfig) { *out = *in + if in.Ingress != nil { + in, out := &in.Ingress, &out.Ingress + *out = new(ApplicationLoadBalancerConfigIngress) + **out = **in + } return } @@ -96,6 +101,22 @@ func (in *ApplicationLoadBalancerConfig) DeepCopy() *ApplicationLoadBalancerConf return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ApplicationLoadBalancerConfigIngress) DeepCopyInto(out *ApplicationLoadBalancerConfigIngress) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationLoadBalancerConfigIngress. +func (in *ApplicationLoadBalancerConfigIngress) DeepCopy() *ApplicationLoadBalancerConfigIngress { + if in == nil { + return nil + } + out := new(ApplicationLoadBalancerConfigIngress) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Bastion) DeepCopyInto(out *Bastion) { *out = *in @@ -334,7 +355,7 @@ func (in *ControlPlaneConfig) DeepCopyInto(out *ControlPlaneConfig) { if in.ApplicationLoadBalancer != nil { in, out := &in.ApplicationLoadBalancer, &out.ApplicationLoadBalancer *out = new(ApplicationLoadBalancerConfig) - **out = **in + (*in).DeepCopyInto(*out) } return } diff --git a/pkg/apis/stackit/validation/controlplane.go b/pkg/apis/stackit/validation/controlplane.go index 86d88aac..f839d222 100644 --- a/pkg/apis/stackit/validation/controlplane.go +++ b/pkg/apis/stackit/validation/controlplane.go @@ -26,6 +26,10 @@ func ValidateControlPlaneConfig(controlPlaneConfig *stackitv1alpha1.ControlPlane allErrs = append(allErrs, validateCloudController(controlPlaneConfig.CloudControllerManager, fldPath.Child("cloudControllerManager"))...) } + if controlPlaneConfig.ApplicationLoadBalancer != nil { + allErrs = append(allErrs, validateApplicationLoadBalancer(controlPlaneConfig.ApplicationLoadBalancer, fldPath.Child("applicationLoadBalancer"))...) + } + allErrs = append(allErrs, validateStorage(controlPlaneConfig.Storage, fldPath.Child("storage"))...) return allErrs @@ -56,6 +60,26 @@ func validateCloudController(cloudcontroller *stackitv1alpha1.CloudControllerMan return allErrs } +func validateApplicationLoadBalancer(applicationLoadBalancerConfig *stackitv1alpha1.ApplicationLoadBalancerConfig, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + if !applicationLoadBalancerConfig.Enabled { + return allErrs + } + + controllerEnabled := false + + if applicationLoadBalancerConfig.Ingress != nil && applicationLoadBalancerConfig.Ingress.Enabled { + controllerEnabled = true + } + + if !controllerEnabled { + allErrs = append(allErrs, field.Invalid(fldPath.Root(), applicationLoadBalancerConfig, "at least one controller has to be enabled is required")) + } + + return allErrs +} + func validateStorage(storage *stackitv1alpha1.Storage, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList if storage == nil { diff --git a/pkg/cmd/config.go b/pkg/cmd/config.go index cf5a74b2..7f3a6cd2 100644 --- a/pkg/cmd/config.go +++ b/pkg/cmd/config.go @@ -77,8 +77,8 @@ func (c *Config) ApplyRegistryCaches(regCaches *[]config.RegistryCacheConfigurat *regCaches = c.Config.RegistryCaches } -func (c *Config) ApplyDeployALBIngressController(deployALBIngressController *bool) { - *deployALBIngressController = c.Config.DeployALBIngressController +func (c *Config) ApplyAllowApplicationLoadBalancerController(allowApplicationLoadBalancerController *bool) { + *allowApplicationLoadBalancerController = c.Config.AllowApplicationLoadBalancerController } // ApplyCustomLabelDomain sets the custom label domain configuration for infrastructure resources. diff --git a/pkg/controller/controlplane/add.go b/pkg/controller/controlplane/add.go index a0e11e6f..9c539194 100644 --- a/pkg/controller/controlplane/add.go +++ b/pkg/controller/controlplane/add.go @@ -22,8 +22,6 @@ import ( var ( // DefaultAddOptions are the default AddOptions for AddToManager. DefaultAddOptions = AddOptions{} - - DeployALBIngressController bool ) // AddOptions are options to apply when adding the OpenStack controlplane controller to the manager. @@ -38,6 +36,9 @@ type AddOptions struct { ExtensionClasses []extensionsv1alpha1.ExtensionClass // CustomLabelDomain is the domain prefix for custom labels applied to STACKIT infrastructure resources. CustomLabelDomain string + // AllowApplicationLoadBalancerController specifies whether the application load balancer controller can + // be enabled in the ControlPlane configuration of the Shoot cluster. + AllowApplicationLoadBalancerController bool } // AddToManagerWithOptions adds a controller with the given Options to the given manager. @@ -46,7 +47,7 @@ func AddToManagerWithOptions(ctx context.Context, mgr manager.Manager, opts AddO genericActuator, err := genericactuator.NewActuator(mgr, stackit.Name, secretConfigsFunc, shootAccessSecretsFunc, configChart, controlPlaneChart, controlPlaneShootChart, controlPlaneShootCRDsChart, storageClassChart, - NewValuesProvider(mgr, DeployALBIngressController, opts.CustomLabelDomain), extensionscontroller.ChartRendererFactoryFunc(util.NewChartRendererForShoot), + NewValuesProvider(mgr, opts.AllowApplicationLoadBalancerController, opts.CustomLabelDomain), extensionscontroller.ChartRendererFactoryFunc(util.NewChartRendererForShoot), imagevector.ImageVector(), "", nil, opts.WebhookServerNamespace) if err != nil { return err diff --git a/pkg/controller/controlplane/valuesprovider.go b/pkg/controller/controlplane/valuesprovider.go index 180ac234..853bea17 100644 --- a/pkg/controller/controlplane/valuesprovider.go +++ b/pkg/controller/controlplane/valuesprovider.go @@ -203,12 +203,12 @@ var ( }, }, { - Name: openstack.STACKITALBControllerManagerName, - Images: []string{imagevector.ImageNameStackitAlbControllerManager}, + Name: openstack.STACKITApplicationLoadBalancerControllerName, + Images: []string{imagevector.ImageNameStackitApplicationLoadBalancerController}, Objects: []*chart.Object{ - // stackit-alb-controller-manager - {Type: &appsv1.Deployment{}, Name: openstack.STACKITALBControllerManagerName}, - {Type: &vpaautoscalingv1.VerticalPodAutoscaler{}, Name: openstack.STACKITALBControllerManagerName}, + // stackit-application-load-balancer-controller + {Type: &appsv1.Deployment{}, Name: openstack.STACKITApplicationLoadBalancerControllerName}, + {Type: &vpaautoscalingv1.VerticalPodAutoscaler{}, Name: openstack.STACKITApplicationLoadBalancerControllerName}, }, }, { @@ -356,22 +356,22 @@ var ( ) // NewValuesProvider creates a new ValuesProvider for the generic actuator. -func NewValuesProvider(mgr manager.Manager, deployALBIngressController bool, customLabelDomain string) genericactuator.ValuesProvider { +func NewValuesProvider(mgr manager.Manager, allowApplicationLoadBalancerController bool, customLabelDomain string) genericactuator.ValuesProvider { return &valuesProvider{ - client: mgr.GetClient(), - decoder: serializer.NewCodecFactory(mgr.GetScheme(), serializer.EnableStrict).UniversalDecoder(), - deployALBIngressController: deployALBIngressController, - customLabelDomain: customLabelDomain, + client: mgr.GetClient(), + decoder: serializer.NewCodecFactory(mgr.GetScheme(), serializer.EnableStrict).UniversalDecoder(), + allowApplicationLoadBalancerController: allowApplicationLoadBalancerController, + customLabelDomain: customLabelDomain, } } // valuesProvider is a ValuesProvider that provides OpenStack-specific values for the 2 charts applied by the generic actuator. type valuesProvider struct { genericactuator.NoopValuesProvider - client k8sclient.Client - decoder runtime.Decoder - deployALBIngressController bool - customLabelDomain string + client k8sclient.Client + decoder runtime.Decoder + allowApplicationLoadBalancerController bool + customLabelDomain string } // GetConfigChartValues returns the values for the config chart applied by the generic actuator. @@ -763,17 +763,18 @@ func (vp *valuesProvider) getControlPlaneChartValues(ctx context.Context, cpConf stackit.PodIdentityWebhookName: podIdentityWebhook, }) - if vp.deployALBIngressController { - fmt.Println("deploying ALB Ingress Controller") - albcm, err := getSTACKITALBCMChartValues(cpConfig, cluster, infra, stackitCredentialsConfig, apiEndpoints, scaledDown, stackitRegion) + if vp.allowApplicationLoadBalancerController && DeploySTACKITApplicationLoadBalancer(cpConfig) { + // Currently only the ingress source is allowed and the validation does not allow to enable the ALB controller of no source is enabled. + // When adding support for GatewayAPI it is required to adopt the configuration of the ALB controller here. + albcm, err := getSTACKITApplicationLoadBalancerCMChartValues(cpConfig, cluster, infra, stackitCredentialsConfig, apiEndpoints, scaledDown, stackitRegion) if err != nil { return nil, err } - controlPlaneValues[openstack.STACKITALBControllerManagerName] = albcm + controlPlaneValues[openstack.STACKITApplicationLoadBalancerControllerName] = albcm } else { // NOTE: ensure deletion of ALB deployment, if disabled - if err := vp.deleteControlPlaneComponentsForGivenChart(ctx, cp.Namespace, openstack.STACKITALBControllerManagerName); err != nil { + if err := vp.deleteControlPlaneComponentsForGivenChart(ctx, cp.Namespace, openstack.STACKITApplicationLoadBalancerControllerName); err != nil { return nil, err } } @@ -1004,7 +1005,7 @@ func getCSIControllerChartValues(cluster *extensionscontroller.Cluster, userAgen return values } -func getSTACKITALBCMChartValues( +func getSTACKITApplicationLoadBalancerCMChartValues( cpConfig *stackitv1alpha1.ControlPlaneConfig, cluster *extensionscontroller.Cluster, infra *stackitv1alpha1.InfrastructureStatus, @@ -1013,37 +1014,44 @@ func getSTACKITALBCMChartValues( scaledDown bool, stackitRegion string, ) (map[string]any, error) { - if !DeploySTACKITALB(cpConfig) { - return nil, nil - } - if credentials == nil { return nil, fmt.Errorf("no STACKIT credentials are provided in cluster %s", cluster.Shoot.Name) } - - config := map[string]any{ - "region": stackitRegion, - "stackitProjectID": credentials.ProjectID, + if infra == nil { + return map[string]any{}, fmt.Errorf("can't determine networkID from as InfrastructureStatus is nil in cluster %s", cluster.Shoot.Name) } - if infra != nil { - config["stackitNetworkID"] = infra.Networks.ID + globalSettings := map[string]any{ + "region": stackitRegion, + "projectId": credentials.ProjectID, } if apiEndpoints != nil { + endpoints := map[string]any{} if apiEndpoints.ApplicationLoadBalancer != nil { - config["applicationLBApiUrl"] = apiEndpoints.ApplicationLoadBalancer + endpoints["applicationLoadBalancerApi"] = apiEndpoints.ApplicationLoadBalancer } - if apiEndpoints.LoadBalancerCertificate != nil { - config["certificateApiUrl"] = *apiEndpoints.LoadBalancerCertificate + if apiEndpoints.ApplicationLoadBalancerCertificate != nil { + endpoints["applicationLoadBalancerCertificateApi"] = *apiEndpoints.ApplicationLoadBalancerCertificate } - if apiEndpoints.TokenEndpoint != nil { - config["tokenUrl"] = *apiEndpoints.TokenEndpoint + if len(endpoints) > 0 { + globalSettings["apiEndpoints"] = endpoints } } + config := map[string]any{ + "global": globalSettings, + "applicationLoadBalancer": map[string]any{ + "networkId": infra.Networks.ID, + }, + } + + if apiEndpoints != nil && apiEndpoints.TokenEndpoint != nil { + config["tokenEndpoint"] = *apiEndpoints.TokenEndpoint + } + values := map[string]any{ "enabled": true, "replicas": extensionscontroller.GetControlPlaneReplicas(cluster, scaledDown, 1), @@ -1053,7 +1061,7 @@ func getSTACKITALBCMChartValues( return values, nil } -func DeploySTACKITALB(cpConfig *stackitv1alpha1.ControlPlaneConfig) bool { +func DeploySTACKITApplicationLoadBalancer(cpConfig *stackitv1alpha1.ControlPlaneConfig) bool { return ptr.Deref(cpConfig.ApplicationLoadBalancer, stackitv1alpha1.ApplicationLoadBalancerConfig{}).Enabled } diff --git a/pkg/controller/controlplane/valuesprovider_test.go b/pkg/controller/controlplane/valuesprovider_test.go index 7ac628d5..a493d232 100644 --- a/pkg/controller/controlplane/valuesprovider_test.go +++ b/pkg/controller/controlplane/valuesprovider_test.go @@ -16,7 +16,6 @@ import ( v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants" extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1" "github.com/gardener/gardener/pkg/utils" - secretutils "github.com/gardener/gardener/pkg/utils/secrets" secretsmanager "github.com/gardener/gardener/pkg/utils/secrets/manager" fakesecretsmanager "github.com/gardener/gardener/pkg/utils/secrets/manager/fake" testutils "github.com/gardener/gardener/pkg/utils/test" @@ -503,6 +502,11 @@ var _ = Describe("ValuesProvider", func() { } BeforeEach(func() { + Expect(feature.MutableGate.SetFromMap(map[string]bool{string(feature.STACKITALBControllerManager): true})).To(Succeed()) + DeferCleanup(func() { + Expect(feature.MutableGate.SetFromMap(map[string]bool{string(feature.STACKITALBControllerManager): false})).To(Succeed()) + }) + c.EXPECT().Get(ctx, cpConfigKey, &corev1.Secret{}).DoAndReturn(clientGet(cpConfig)) c.EXPECT().Delete(context.TODO(), &networkingv1.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: "allow-kube-apiserver-to-csi-snapshot-validation", Namespace: cp.Namespace}}) @@ -567,7 +571,7 @@ var _ = Describe("ValuesProvider", func() { }, }), stackit.PodIdentityWebhookName: stackitPodIdentityWebhookChartSeedValues, - openstack.STACKITALBControllerManagerName: empty(), + openstack.STACKITApplicationLoadBalancerControllerManagerName: empty(), })) }) @@ -611,7 +615,7 @@ var _ = Describe("ValuesProvider", func() { }, }), stackit.PodIdentityWebhookName: stackitPodIdentityWebhookChartSeedValues, - openstack.STACKITALBControllerManagerName: empty(), + openstack.STACKITApplicationLoadBalancerControllerManagerName: empty(), })) }) @@ -665,7 +669,7 @@ var _ = Describe("ValuesProvider", func() { stackitCCMDeletion(ctx, c) } - vpStackitConf := NewValuesProvider(mgr, true, "kubernetes.io") + vpStackitConf := NewValuesProvider(mgr, "kubernetes.io") values, err := vpStackitConf.GetControlPlaneChartValues(ctx, cp, &testCluster, fakeSecretsManager, checksums, false) Expect(err).NotTo(HaveOccurred()) Expect(values).To(HaveKey(openstack.STACKITCloudControllerManagerName)) @@ -777,7 +781,7 @@ var _ = Describe("ValuesProvider", func() { } testCluster.CloudProfile = cloudProfile - vpCustomDomain := NewValuesProvider(mgr, true, customDomain) + vpCustomDomain := NewValuesProvider(mgr, customDomain) values, err := vpCustomDomain.GetControlPlaneChartValues(ctx, cp, &testCluster, fakeSecretsManager, checksums, false) Expect(err).NotTo(HaveOccurred()) @@ -881,7 +885,7 @@ var _ = Describe("ValuesProvider", func() { values, err := vp.GetControlPlaneChartValues(ctx, cp, cluster, fakeSecretsManager, checksums, false) Expect(err).NotTo(HaveOccurred()) - Expect(values[openstack.STACKITALBControllerManagerName]).To(Equal(stackitAlbChartValues)) + Expect(values[openstack.STACKITApplicationLoadBalancerControllerManagerName]).To(Equal(stackitAlbChartValues)) }) }) diff --git a/pkg/controller/healthcheck/add.go b/pkg/controller/healthcheck/add.go index 4ab43580..564360d2 100644 --- a/pkg/controller/healthcheck/add.go +++ b/pkg/controller/healthcheck/add.go @@ -31,20 +31,31 @@ import ( var ( defaultSyncPeriod = time.Second * 30 // DefaultAddOptions are the default DefaultAddArgs for AddToManager. - DefaultAddOptions = healthcheck.DefaultAddArgs{ - HealthCheckConfig: healthcheckconfig.HealthCheckConfig{ - SyncPeriod: metav1.Duration{Duration: defaultSyncPeriod}, - ShootRESTOptions: &healthcheckconfig.RESTOptions{ - QPS: new(float32(100)), - Burst: new(130), + DefaultAddOptions = AddOptions{ + DefaultAddArgs: healthcheck.DefaultAddArgs{ + HealthCheckConfig: healthcheckconfig.HealthCheckConfig{ + SyncPeriod: metav1.Duration{Duration: defaultSyncPeriod}, + ShootRESTOptions: &healthcheckconfig.RESTOptions{ + QPS: new(float32(100)), + Burst: new(130), + }, }, }, } ) +// AddOptions are options to apply when adding the STACKIT healthcheck controller to the manager. +type AddOptions struct { + // DefaultAddArgs + healthcheck.DefaultAddArgs + // AllowApplicationLoadBalancerController specifies whether the application load balancer controller can + // be enabled in the ControlPlane configuration of the Shoot cluster. + AllowApplicationLoadBalancerController bool +} + // RegisterHealthChecks registers health checks for each extension resource // HealthChecks are grouped by extension (e.g worker), extension.type (e.g aws) and Health Check Type (e.g ShootControlPlaneHealthy) -func RegisterHealthChecks(ctx context.Context, mgr manager.Manager, opts healthcheck.DefaultAddArgs) error { +func RegisterHealthChecks(ctx context.Context, mgr manager.Manager, opts AddOptions) error { healthchecks := []healthcheck.ConditionTypeToHealthCheck{ { ConditionType: string(gardencorev1beta1.ShootControlPlaneHealthy), @@ -75,16 +86,11 @@ func RegisterHealthChecks(ctx context.Context, mgr manager.Manager, opts healthc HealthCheck: general.NewSeedDeploymentHealthChecker(controlplane.CSIStackitPrefix + "-" + openstack.CSISnapshotControllerName), PreCheckFunc: checkCSISTACKIT, }, - } - - if controlplane.DeployALBIngressController { - healthchecks = append(healthchecks, - healthcheck.ConditionTypeToHealthCheck{ - ConditionType: string(gardencorev1beta1.ShootControlPlaneHealthy), - HealthCheck: general.NewSeedDeploymentHealthChecker(openstack.STACKITALBControllerManagerName), - PreCheckFunc: checkALB, - }, - ) + { + ConditionType: string(gardencorev1beta1.ShootControlPlaneHealthy), + HealthCheck: general.NewSeedDeploymentHealthChecker(openstack.STACKITApplicationLoadBalancerControllerName), + PreCheckFunc: checkALB, + }, } if err := healthcheck.DefaultRegistration( @@ -93,7 +99,7 @@ func RegisterHealthChecks(ctx context.Context, mgr manager.Manager, opts healthc func() client.ObjectList { return &extensionsv1alpha1.ControlPlaneList{} }, func() extensionsv1alpha1.Object { return &extensionsv1alpha1.ControlPlane{} }, mgr, - opts, + opts.DefaultAddArgs, nil, healthchecks, sets.New[gardencorev1beta1.ConditionType](), @@ -107,7 +113,7 @@ func RegisterHealthChecks(ctx context.Context, mgr manager.Manager, opts healthc func() client.ObjectList { return &extensionsv1alpha1.WorkerList{} }, func() extensionsv1alpha1.Object { return &extensionsv1alpha1.Worker{} }, mgr, - opts, + opts.DefaultAddArgs, nil, []healthcheck.ConditionTypeToHealthCheck{{ ConditionType: string(gardencorev1beta1.ShootEveryNodeReady), @@ -173,7 +179,7 @@ func checkALB(_ context.Context, client client.Client, _ client.Object, clusterO return false } - return controlplane.DeploySTACKITALB(cpConfig) + return controlplane.DeploySTACKITApplicationLoadBalancer(cpConfig) && DefaultAddOptions.AllowApplicationLoadBalancerController } // AddToManager adds a controller with the default Options. diff --git a/pkg/openstack/types.go b/pkg/openstack/types.go index fc3a090c..9ac0b6bf 100644 --- a/pkg/openstack/types.go +++ b/pkg/openstack/types.go @@ -71,8 +71,8 @@ const ( CloudControllerManagerName = "cloud-controller-manager" // STACKITCloudControllerManagerName is a constant for the name of the CloudController deployed by the worker controller. (stackit) STACKITCloudControllerManagerName = "stackit-cloud-controller-manager" - // STACKITALBControllerManagerName is a constant for the name of the ALB CloudController. (stackit) - STACKITALBControllerManagerName = "stackit-alb-controller-manager" + // STACKITApplicationLoadBalancerControllerName is a constant for the name of the ALB CloudController. (stackit) + STACKITApplicationLoadBalancerControllerName = "stackit-application-load-balancer-controller" // CSIDiskDriverTopologyKey is the label on persistent volumes that represents availability by zone. // See https://github.com/kubernetes/cloud-provider-openstack/blob/master/examples/cinder-csi-plugin/topology/example.yaml // See https://gitlab.cern.ch/cloud/cloud-provider-openstack/-/blob/release-1.19/docs/using-cinder-csi-plugin.md#enable-topology-aware-dynamic-provisioning-for-cinder-volumes
-

+

Enabled specifies whether the Ingress controller functionality
for the ALB is activated to manage external access to services.

-deployALBIngressController
+allowApplicationLoadBalancerController
boolean
-

DeployALBIngressController

+(Optional) +

AllowApplicationLoadBalancerController specifies whether the application load balancer controller can
be enabled in the ControlPlane configuration of the Shoot cluster.