Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
2fde114
add application load balancer controller manager
Mar 17, 2026
efaf6a0
chore: add alb ingress controller docs run-it-locally how-to
Mar 17, 2026
079953a
Fix errors in stackit package
fischerman Mar 17, 2026
04e5bf3
chore: add new Makefile build for alb ingress controller manager
Mar 17, 2026
38b50a0
Fix errors in ingress package (only non-test files)
fischerman Mar 17, 2026
686f0a7
Add mocks for ALB and certificates API
fischerman Mar 17, 2026
68811dc
Fix syntax errors in test in ingress package
fischerman Mar 17, 2026
8076443
wip: Add alb-controller-manager deploy files
jamand Mar 17, 2026
b3fb5bd
Fix main.go
fischerman Mar 17, 2026
746d072
Add mock generation for ALB and certificates API
fischerman Mar 17, 2026
1426840
Fix linter issues
fischerman Mar 17, 2026
127ab1d
Added waf config to change detection
Mar 17, 2026
175894e
Update docs for ALBCM
fischerman Mar 18, 2026
8501597
Fix ALB unit tests
fischerman Mar 18, 2026
f1846ac
feat: read configuration from cloud config
Mar 18, 2026
128e706
chore: add a short description for setIPAddresses function
Mar 18, 2026
1cab4cd
Include envtest for controller tests
fischerman Mar 18, 2026
b40a2b7
Fix linter issues
fischerman Mar 18, 2026
b37a3a5
Remove license from code
fischerman Mar 18, 2026
9b86598
chore: adjust issuer sample
Mar 20, 2026
c0385ae
chore: clarify isCertValid
Mar 20, 2026
3cc2fdf
chore: remove debug messages
Mar 20, 2026
37b5eef
fix: certificates not created because loadCerts skips all ingress tls…
Mar 21, 2026
9eea01b
fix: certificate deletion logic
Mar 22, 2026
d78e601
chore: adjsut externalIPAnnotation comment
Mar 22, 2026
c3b02c2
Adopt config to config structure
dergeberl Mar 26, 2026
0edd42e
Move ReadConfig to config package
dergeberl Mar 26, 2026
e1f3f44
Remove unused webhook
dergeberl Mar 26, 2026
24ced8a
Remove secure metrics
dergeberl Mar 26, 2026
9266476
Enable LeaderElectionReleaseOnCancel
dergeberl Mar 26, 2026
ac251eb
Make linter happy
dergeberl Mar 26, 2026
5c35199
Remove kubebuilder scaffold comments
dergeberl Mar 26, 2026
40fd8e4
Remove crd import in envtest; remove getFirstFoundEnvTestBinaryDir as…
dergeberl Mar 26, 2026
730655c
Remove dummy comment
dergeberl Mar 26, 2026
870df27
Refactor SetupWithManager
dergeberl Mar 26, 2026
7af9e33
WIP: Change how to build alb spec
dergeberl Mar 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec
BUILD_IMAGES ?= stackit-csi-plugin cloud-controller-manager
BUILD_IMAGES ?= stackit-csi-plugin cloud-controller-manager application-load-balancer-controller-manager
SOURCES := Makefile go.mod go.sum $(shell find $(DEST) -name '*.go' 2>/dev/null)
VERSION ?= $(shell git describe --dirty --tags --match='v*' 2>/dev/null || git rev-parse --short HEAD)
REGISTRY ?= ghcr.io
Expand Down Expand Up @@ -139,6 +139,9 @@ mocks: $(MOCKGEN)
@$(MOCKGEN) -destination ./pkg/stackit/server_mock.go -package stackit ./pkg/stackit NodeClient
@$(MOCKGEN) -destination ./pkg/stackit/metadata/metadata_mock.go -package metadata ./pkg/stackit/metadata IMetadata
@$(MOCKGEN) -destination ./pkg/csi/util/mount/mount_mock.go -package mount ./pkg/csi/util/mount IMount
@$(MOCKGEN) -destination ./pkg/stackit/applicationloadbalancercertificates_mock.go -package stackit ./pkg/stackit CertificatesClient
@$(MOCKGEN) -destination ./pkg/stackit/applicationloadbalancer_mock.go -package stackit ./pkg/stackit ApplicationLoadBalancerClient


.PHONY: generate
generate: mocks
Expand Down
141 changes: 141 additions & 0 deletions cmd/application-load-balancer-controller-manager/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package main

import (
"flag"
"os"

"github.com/stackitcloud/cloud-provider-stackit/pkg/alb/ingress"
albclient "github.com/stackitcloud/cloud-provider-stackit/pkg/stackit"
stackitconfig "github.com/stackitcloud/cloud-provider-stackit/pkg/stackit/config"
sdkconfig "github.com/stackitcloud/stackit-sdk-go/core/config"
albsdk "github.com/stackitcloud/stackit-sdk-go/services/alb/v2api"
certsdk "github.com/stackitcloud/stackit-sdk-go/services/certificates/v2api"

"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
_ "k8s.io/client-go/plugin/pkg/client/auth"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
)

var (
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
)

func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
}

// nolint:funlen // TODO: Refactor into smaller functions.
func main() {
var metricsAddr string
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move into a options struct

var enableLeaderElection bool
var leaderElectionNamespace string
var leaderElectionID string
var probeAddr string
var cloudConfig string
flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
flag.StringVar(&leaderElectionNamespace, "leader-election-namespace", "default", "The namespace in which the leader "+
"election resource will be created.")
flag.StringVar(&leaderElectionID, "leader-election-id", "d0fbe9c4.stackit.cloud", "The name of the resource that "+
"leader election will use for holding the leader lock.")
flag.StringVar(&cloudConfig, "cloud-config", "cloud.yaml", "The path to the cloud config file.")
opts := zap.Options{
Development: true,
}
opts.BindFlags(flag.CommandLine)
flag.Parse()

ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))

config, err := stackitconfig.ReadALBConfigFromFile(cloudConfig)
if err != nil {
setupLog.Error(err, "Failed to read cloud config")
os.Exit(1)
}

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
Metrics: metricsserver.Options{
BindAddress: metricsAddr,
},
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: leaderElectionID,
LeaderElectionNamespace: leaderElectionNamespace,
LeaderElectionReleaseOnCancel: true,
})
if err != nil {
setupLog.Error(err, "unable to start manager")
os.Exit(1)
}
albOpts := []sdkconfig.ConfigurationOption{}
if config.Global.APIEndpoints.ApplicationLoadBalancerAPI != "" {
albOpts = append(albOpts, sdkconfig.WithEndpoint(config.Global.APIEndpoints.ApplicationLoadBalancerAPI))
}

certOpts := []sdkconfig.ConfigurationOption{}
if config.Global.APIEndpoints.ApplicationLoadBalancerCertificateAPI != "" {
certOpts = append(certOpts, sdkconfig.WithEndpoint(config.Global.APIEndpoints.ApplicationLoadBalancerCertificateAPI))
}

// Setup ALB API client
sdkClient, err := albsdk.NewAPIClient(albOpts...)
if err != nil {
setupLog.Error(err, "unable to create ALB SDK client", "controller", "IngressClass")
os.Exit(1)
}
albClient, err := albclient.NewApplicationLoadBalancerClient(sdkClient)
if err != nil {
setupLog.Error(err, "unable to create ALB client", "controller", "IngressClass")
os.Exit(1)
}

// Setup Certificates API client
certificateAPI, err := certsdk.NewAPIClient(certOpts...)
if err != nil {
setupLog.Error(err, "unable to create certificate SDK client", "controller", "IngressClass")
os.Exit(1)
}
certificateClient, err := albclient.NewCertClient(certificateAPI)
if err != nil {
setupLog.Error(err, "unable to create Certificates client", "controller", "IngressClass")
os.Exit(1)
}

if err = (&ingress.IngressClassReconciler{
Client: mgr.GetClient(),
Recorder: mgr.GetEventRecorderFor("ingressclass-controller"),
ALBClient: albClient,
CertificateClient: certificateClient,
Scheme: mgr.GetScheme(),
ALBConfig: config,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "IngressClass")
os.Exit(1)
}

if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up health check")
os.Exit(1)
}
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up ready check")
os.Exit(1)
}

setupLog.Info("starting manager")
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
os.Exit(1)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: kube-system
name: stackit-application-load-balancer-contoller-manager
labels:
app: stackit-application-load-balancer-contoller-manager
spec:
replicas: 2
strategy:
type: RollingUpdate
selector:
matchLabels:
app: stackit-application-load-balancer-contoller-manager
template:
metadata:
labels:
app: stackit-application-load-balancer-contoller-manager
spec:
serviceAccountName: stackit-application-load-balancer-contoller-manager
terminationGracePeriodSeconds: 30
containers:
- name: stackit-application-load-balancer-contoller-manager
# TODO(jamand): Adapt image tag
image: ghcr.io/stackitcloud/cloud-provider-stackit/stackit-application-load-balancer-contoller-manager:XXX
args:
- "--authorization-always-allow-paths=/metrics"
- "--leader-elect=true"
- "--leader-elect-resource-name=stackit-application-load-balancer-contoller-manager"
- "--enable-http2"
- "--metrics-bind-address=8080"
- "--secureMetrics=false"
# TODO(jamand): Check webhook cert + enableHTTP2 flag
env:
- name: STACKIT_SERVICE_ACCOUNT_KEY_PATH
value: /etc/serviceaccount/sa_key.json
ports:
- containerPort: 8080
hostPort: 8080
name: metrics
protocol: TCP
- containerPort: 8081
hostPort: 8081
name: probe
protocol: TCP
resources:
limits:
cpu: "0.5"
memory: 500Mi
requests:
cpu: "0.1"
memory: 100Mi
volumeMounts:
- mountPath: /etc/serviceaccount
name: cloud-secret
volumes:
- name: cloud-secret
secret:
secretName: stackit-cloud-secret
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- deployment.yaml
- rbac.yaml

60 changes: 60 additions & 0 deletions deploy/application-load-balancer-controller-manager/rbac.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: kube-system
name: stackit-application-load-balancer-contoller-manager
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: stackit-application-load-balancer-contoller-manager
rules:
# TODO(jamand): Go through rules again
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- update
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- apiGroups:
- "networking.k8s.io"
resources:
- ingress
verbs:
- get
- apiGroups:
- "networking.k8s.io"
resources:
- ingress/status
verbs:
- patch
- apiGroups:
- "networking.k8s.io"
resources:
- ingressclass
verbs:
- list
- patch
- update
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: stackit-application-load-balancer-contoller-manager
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: stackit-application-load-balancer-contoller-manager
subjects:
- kind: ServiceAccount
name: stackit-application-load-balancer-contoller-manager
namespace: kube-system
20 changes: 20 additions & 0 deletions deploy/application-load-balancer-controller-manager/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
labels:
app: stackit-application-load-balancer-contoller-manager
namespace: kube-system
name: stackit-application-load-balancer-contoller-manager
spec:
selector:
app: stackit-application-load-balancer-contoller-manager
ports:
- name: probe
port: 8081
targetPort: probe
protocol: TCP
- name: metrics
port: 8080
targetPort: metrics
protocol: TCP
type: ClusterIP
Loading