diff --git a/examples/gateway-api-public/gateway.yaml b/examples/gateway-api-public/gateway.yaml index b77d775..d56aae3 100644 --- a/examples/gateway-api-public/gateway.yaml +++ b/examples/gateway-api-public/gateway.yaml @@ -13,14 +13,9 @@ metadata: spec: gatewayClassName: public listeners: - - protocol: HTTP + - protocol: gateway.netbird.io/NBRoutingPeer + name: netbird port: 80 - name: dummy - infrastructure: - parametersRef: - group: netbird.io - kind: NBRoutingPeer - name: netbird --- apiVersion: netbird.io/v1 kind: NBRoutingPeer diff --git a/internal/controller/gateway_controller.go b/internal/controller/gateway_controller.go index 3a7ad98..2a99e41 100644 --- a/internal/controller/gateway_controller.go +++ b/internal/controller/gateway_controller.go @@ -18,8 +18,10 @@ package controller import ( "context" + "errors" "fmt" "slices" + "strings" "time" netbird "github.com/netbirdio/netbird/shared/management/client/rest" @@ -72,36 +74,19 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct } // Verify Gateway configuration. - if gw.Spec.Infrastructure == nil || gw.Spec.Infrastructure.ParametersRef == nil { + routingPeerName, err := getRoutingPeerName(gw.Spec.Listeners) + if err != nil { cond := metav1.Condition{ Type: string(gatewayv1.GatewayConditionAccepted), Status: metav1.ConditionFalse, Reason: string(gatewayv1.GatewayReasonInvalidParameters), - Message: "Gateway expected to reference a NBRoutingPeer", + Message: err.Error(), } if meta.SetStatusCondition(&gw.Status.Conditions, cond) { err = r.Status().Update(ctx, &gw) if err != nil { return ctrl.Result{}, err } - return ctrl.Result{}, nil - } - return ctrl.Result{}, nil - } - parametersRef := gw.Spec.Infrastructure.ParametersRef - if parametersRef.Group != "netbird.io" && parametersRef.Kind != "NBRoutingPeer" { - cond := metav1.Condition{ - Type: string(gatewayv1.GatewayConditionAccepted), - Status: metav1.ConditionFalse, - Reason: string(gatewayv1.GatewayReasonInvalidParameters), - Message: fmt.Sprintf("unsupported parameter group and kind %s.%s", parametersRef.Group, parametersRef.Kind), - } - if meta.SetStatusCondition(&gw.Status.Conditions, cond) { - err = r.Status().Update(ctx, &gw) - if err != nil { - return ctrl.Result{}, err - } - return ctrl.Result{}, nil } return ctrl.Result{}, nil } @@ -127,7 +112,7 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct // Ensure routing peer is ready. nbrp := &netbirdiov1.NBRoutingPeer{} - err = r.Get(ctx, types.NamespacedName{Namespace: req.Namespace, Name: parametersRef.Name}, nbrp) + err = r.Get(ctx, types.NamespacedName{Namespace: req.Namespace, Name: routingPeerName}, nbrp) if err != nil { return ctrl.Result{}, err } @@ -139,7 +124,7 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct Type: string(gatewayv1.GatewayConditionProgrammed), Status: metav1.ConditionFalse, Reason: string(gatewayv1.GatewayReasonProgrammed), - Message: fmt.Sprintf("NBRoutingPeer %s is not ready", parametersRef.Name), + Message: fmt.Sprintf("NBRoutingPeer %s is not ready", routingPeerName), } if meta.SetStatusCondition(&gw.Status.Conditions, cond) { err = r.Status().Update(ctx, &gw) @@ -210,3 +195,17 @@ func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error { For(&gatewayv1.Gateway{}). Complete(r) } + +func getRoutingPeerName(listeners []gatewayv1.Listener) (string, error) { + if len(listeners) > 1 { + return "", errors.New("netbird Gateway only supports a single listener") + } + group, kind, ok := strings.Cut(string(listeners[0].Protocol), "/") + if !ok { + return "", fmt.Errorf("invalid protocol %s, expected gateway.netbird.io/NBRoutingPeer", listeners[0].Protocol) + } + if group != "gateway.netbird.io" || kind != "NBRoutingPeer" { + return "", fmt.Errorf("invalid group %s and kind %s, expected gateway.netbird.io/NBRoutingPeer", group, kind) + } + return string(listeners[0].Name), nil +} diff --git a/internal/controller/httproute_controller.go b/internal/controller/httproute_controller.go index 34f832e..54b2008 100644 --- a/internal/controller/httproute_controller.go +++ b/internal/controller/httproute_controller.go @@ -8,6 +8,7 @@ import ( netbird "github.com/netbirdio/netbird/shared/management/client/rest" "github.com/netbirdio/netbird/shared/management/http/api" corev1 "k8s.io/api/core/v1" + kerrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -69,8 +70,13 @@ func (r *HTTPRouteReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( logger.Info("gateway is not ready", "name", gw.ObjectMeta.Name) return ctrl.Result{RequeueAfter: 1 * time.Second}, nil } + + routingPeerName, err := getRoutingPeerName(gw.Spec.Listeners) + if err != nil { + return ctrl.Result{}, err + } nbrp := &netbirdiov1.NBRoutingPeer{} - err = r.Get(ctx, types.NamespacedName{Namespace: gw.Namespace, Name: gw.Spec.Infrastructure.ParametersRef.Name}, nbrp) + err = r.Get(ctx, types.NamespacedName{Namespace: gw.Namespace, Name: routingPeerName}, nbrp) if err != nil { return ctrl.Result{}, err } @@ -234,6 +240,9 @@ func (r *HTTPRouteReconciler) reconcileDelete(ctx context.Context, hr gatewayv1. key := client.ObjectKey{Namespace: hr.Namespace, Name: string(ref.Name)} var svc corev1.Service err := r.Client.Get(ctx, key, &svc) + if kerrors.IsNotFound(err) { + continue + } if err != nil { return ctrl.Result{}, err }