2026-03-19 13:01:58 +01:00
|
|
|
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.
|
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
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
}
|