Files
netbird-kubernetes-operator/internal/controller/gatewayclass_controller.go
T
Philip LaineandGitHub 7acd175882 Gateway API support (#117)
This change adds support for the new proxy service to the operator
through Gateway API. This change attempts to standardize concepts around
the Gateway API to allow for compatibility with other projects.

Fixes #111
Fixes #44

Signed-off-by: Philip Laine <philip.laine@gmail.com>
2026-03-19 13:01:58 +01:00

108 lines
2.9 KiB
Go

package controller
import (
"context"
"time"
"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 (
GatewayClassFinalizer = "gateway.netbird.io/gatewayclass"
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)
if err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// 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, gwc)
}
// Validate configuration.
if gwc.Spec.ParametersRef != nil {
cond := metav1.Condition{
Type: string(gatewayv1.GatewayClassConditionStatusAccepted),
Status: metav1.ConditionFalse,
Reason: string(gatewayv1.GatewayClassReasonInvalidParameters),
Message: "Parameters references is not supported.",
}
if meta.SetStatusCondition(&gwc.Status.Conditions, cond) {
err = r.Client.Status().Update(ctx, &gwc)
if err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}
}
// Add finalizer to validate deletion.
if controllerutil.AddFinalizer(&gwc, GatewayClassFinalizer) {
err = r.Client.Update(ctx, &gwc)
if err != nil {
return ctrl.Result{}, err
}
}
// Set condition to accepted.
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 = r.Client.Status().Update(ctx, &gwc)
if err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}
func (r *GatewayClassReconciler) reconcileDelete(ctx context.Context, gwc gatewayv1.GatewayClass) (ctrl.Result, error) {
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
}
}
if controllerutil.RemoveFinalizer(&gwc, GatewayClassFinalizer) {
err = r.Client.Update(ctx, &gwc)
if err != nil {
return ctrl.Result{}, err
}
}
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)
}