Files
netbird-kubernetes-operator/internal/controller/gatewayclass_controller.go
T

110 lines
3.1 KiB
Go
Raw Normal View History

2026-03-19 13:01:58 +01:00
package controller
import (
"context"
"time"
"github.com/fluxcd/pkg/runtime/patch"
2026-04-23 19:18:06 +02:00
"github.com/netbirdio/kubernetes-operator/internal/k8sutil"
2026-03-19 13:01:58 +01:00
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
)
const (
GatewayControllerName = "gateway.netbird.io/controller"
)
type GatewayClassReconciler struct {
client.Client
}
func (r *GatewayClassReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
gwc := &gatewayv1.GatewayClass{}
err := r.Client.Get(ctx, req.NamespacedName, gwc)
2026-03-19 13:01:58 +01:00
if err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
sp := patch.NewSerialPatcher(gwc, r.Client)
2026-03-19 13:01:58 +01:00
// Controller name does not match.
if gwc.Spec.ControllerName != GatewayControllerName {
return ctrl.Result{}, nil
}
// Gateway class is being deleted.
if !gwc.GetDeletionTimestamp().IsZero() {
return r.reconcileDelete(ctx, sp, gwc)
2026-03-19 13:01:58 +01:00
}
// Validate configuration.
2026-03-23 09:59:48 +01:00
message := func() string {
if gwc.Name != "netbird-public" && gwc.Name != "netbird-private" {
return "GatewayClass name must be netbird-public or netbird-private."
}
if gwc.Spec.ParametersRef != nil {
return "Parameters references is not supported."
}
return ""
}()
if message != "" {
2026-03-19 13:01:58 +01:00
cond := metav1.Condition{
Type: string(gatewayv1.GatewayClassConditionStatusAccepted),
Status: metav1.ConditionFalse,
Reason: string(gatewayv1.GatewayClassReasonInvalidParameters),
2026-03-23 09:59:48 +01:00
Message: message,
2026-03-19 13:01:58 +01:00
}
meta.SetStatusCondition(&gwc.Status.Conditions, cond)
err := sp.Patch(ctx, gwc)
2026-03-19 13:01:58 +01:00
if err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
2026-03-19 13:01:58 +01:00
}
// Set condition to accepted.
2026-04-23 19:18:06 +02:00
controllerutil.AddFinalizer(gwc, k8sutil.Finalizer("gatewayclass"))
2026-03-19 13:01:58 +01:00
cond := metav1.Condition{
Type: string(gatewayv1.GatewayClassConditionStatusAccepted),
Status: metav1.ConditionTrue,
Reason: string(gatewayv1.GatewayClassReasonAccepted),
Message: "Reconciled by Netbird Operator.",
}
meta.SetStatusCondition(&gwc.Status.Conditions, cond)
err = sp.Patch(ctx, gwc)
2026-03-19 13:01:58 +01:00
if err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}
func (r *GatewayClassReconciler) reconcileDelete(ctx context.Context, sp *patch.SerialPatcher, gwc *gatewayv1.GatewayClass) (ctrl.Result, error) {
2026-03-19 13:01:58 +01:00
var gatewayList gatewayv1.GatewayList
err := r.Client.List(ctx, &gatewayList)
if err != nil {
return ctrl.Result{}, err
}
for _, gw := range gatewayList.Items {
if string(gw.Spec.GatewayClassName) == gwc.ObjectMeta.Name {
return ctrl.Result{RequeueAfter: 5 * time.Second}, nil
}
}
2026-04-23 19:18:06 +02:00
controllerutil.RemoveFinalizer(gwc, k8sutil.Finalizer("gatewayclass"))
err = sp.Patch(ctx, gwc)
if err != nil {
return ctrl.Result{}, err
2026-03-19 13:01:58 +01:00
}
return ctrl.Result{}, nil
}
// SetupWithManager sets up the controller with the Manager.
func (r *GatewayClassReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&gatewayv1.GatewayClass{}).
Complete(r)
}