Skip to content

Commit ecebace

Browse files
authored
feat: Add support for Gateway API ReferenceGrant resource (#146)
1 parent 24e0082 commit ecebace

File tree

6 files changed

+229
-83
lines changed

6 files changed

+229
-83
lines changed

charts/templates/cluster_role.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,20 @@ rules:
170170
- get
171171
- list
172172
- watch
173+
- apiGroups:
174+
- gateway.networking.k8s.io
175+
resources:
176+
- referencegrants
177+
verbs:
178+
- get
179+
- list
180+
- watch
181+
- apiGroups:
182+
- gateway.networking.k8s.io
183+
resources:
184+
- referencegrants/status
185+
verbs:
186+
- get
173187
- apiGroups:
174188
- networking.k8s.io
175189
resources:

internal/controller/gateway_controller.go

Lines changed: 83 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818
"fmt"
1919
"reflect"
2020

21-
"github.com/api7/gopkg/pkg/log"
2221
"github.com/go-logr/logr"
2322
corev1 "k8s.io/api/core/v1"
2423
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -27,10 +26,14 @@ import (
2726
ctrl "sigs.k8s.io/controller-runtime"
2827
"sigs.k8s.io/controller-runtime/pkg/builder"
2928
"sigs.k8s.io/controller-runtime/pkg/client"
29+
"sigs.k8s.io/controller-runtime/pkg/event"
3030
"sigs.k8s.io/controller-runtime/pkg/handler"
3131
"sigs.k8s.io/controller-runtime/pkg/predicate"
3232
"sigs.k8s.io/controller-runtime/pkg/reconcile"
3333
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
34+
"sigs.k8s.io/gateway-api/apis/v1beta1"
35+
36+
"github.com/api7/gopkg/pkg/log"
3437

3538
"github.com/apache/apisix-ingress-controller/api/v1alpha1"
3639
"github.com/apache/apisix-ingress-controller/internal/controller/indexer"
@@ -83,6 +86,23 @@ func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error {
8386
&corev1.Secret{},
8487
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForSecret),
8588
).
89+
Watches(&v1beta1.ReferenceGrant{},
90+
handler.EnqueueRequestsFromMapFunc(r.listReferenceGrantsForGateway),
91+
builder.WithPredicates(predicate.Funcs{
92+
CreateFunc: func(e event.CreateEvent) bool {
93+
return referenceGrantHasGatewayFrom(e.Object)
94+
},
95+
UpdateFunc: func(e event.UpdateEvent) bool {
96+
return referenceGrantHasGatewayFrom(e.ObjectOld) || referenceGrantHasGatewayFrom(e.ObjectNew)
97+
},
98+
DeleteFunc: func(e event.DeleteEvent) bool {
99+
return referenceGrantHasGatewayFrom(e.Object)
100+
},
101+
GenericFunc: func(e event.GenericEvent) bool {
102+
return referenceGrantHasGatewayFrom(e.Object)
103+
},
104+
}),
105+
).
86106
Complete(r)
87107
}
88108

@@ -117,7 +137,7 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
117137
msg: acceptedMessage("gateway"),
118138
}
119139

120-
// create a translate context
140+
// create a translation context
121141
tctx := provider.NewDefaultTranslateContext(ctx)
122142

123143
r.processListenerConfig(tctx, gateway)
@@ -164,20 +184,25 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
164184
}
165185
}
166186

167-
ListenerStatuses, err := getListenerStatus(ctx, r.Client, gateway)
187+
var referenceGrantList v1beta1.ReferenceGrantList
188+
if err := r.List(ctx, &referenceGrantList); err != nil {
189+
r.Log.Error(err, "failed to list reference grants")
190+
return ctrl.Result{}, err
191+
}
192+
listenerStatuses, err := getListenerStatus(ctx, r.Client, gateway, referenceGrantList.Items)
168193
if err != nil {
169-
log.Error(err, "failed to get listener status", "gateway", gateway.GetName())
194+
r.Log.Error(err, "failed to get listener status", "gateway", types.NamespacedName{Namespace: gateway.GetNamespace(), Name: gateway.GetName()})
170195
return ctrl.Result{}, err
171196
}
172197

173198
accepted := SetGatewayConditionAccepted(gateway, acceptStatus.status, acceptStatus.msg)
174-
Programmed := SetGatewayConditionProgrammed(gateway, conditionProgrammedStatus, conditionProgrammedMsg)
175-
if accepted || Programmed || len(addrs) > 0 || len(ListenerStatuses) > 0 {
199+
programmed := SetGatewayConditionProgrammed(gateway, conditionProgrammedStatus, conditionProgrammedMsg)
200+
if accepted || programmed || len(addrs) > 0 || len(listenerStatuses) > 0 {
176201
if len(addrs) > 0 {
177202
gateway.Status.Addresses = addrs
178203
}
179-
if len(ListenerStatuses) > 0 {
180-
gateway.Status.Listeners = ListenerStatuses
204+
if len(listenerStatuses) > 0 {
205+
gateway.Status.Listeners = listenerStatuses
181206
}
182207

183208
return ctrl.Result{}, r.Status().Update(ctx, gateway)
@@ -348,6 +373,56 @@ func (r *GatewayReconciler) listGatewaysForSecret(ctx context.Context, obj clien
348373
return requests
349374
}
350375

376+
func (r *GatewayReconciler) listReferenceGrantsForGateway(ctx context.Context, obj client.Object) (requests []reconcile.Request) {
377+
grant, ok := obj.(*v1beta1.ReferenceGrant)
378+
if !ok {
379+
r.Log.Error(
380+
errors.New("unexpected object type"),
381+
"ReferenceGrant watch predicate received unexpected object type",
382+
"expected", FullTypeName(new(v1beta1.ReferenceGrant)), "found", FullTypeName(obj),
383+
)
384+
return nil
385+
}
386+
387+
var gatewayList gatewayv1.GatewayList
388+
if err := r.List(ctx, &gatewayList); err != nil {
389+
r.Log.Error(err, "failed to list gateways in watch predicate", "ReferenceGrant", grant.GetName())
390+
return nil
391+
}
392+
393+
for _, gateway := range gatewayList.Items {
394+
for _, from := range grant.Spec.From {
395+
gw := v1beta1.ReferenceGrantFrom{
396+
Group: gatewayv1.GroupName,
397+
Kind: KindGateway,
398+
Namespace: v1beta1.Namespace(gateway.GetNamespace()),
399+
}
400+
if from == gw {
401+
requests = append(requests, reconcile.Request{
402+
NamespacedName: types.NamespacedName{
403+
Namespace: gateway.GetNamespace(),
404+
Name: gateway.GetName(),
405+
},
406+
})
407+
}
408+
}
409+
}
410+
return requests
411+
}
412+
413+
func referenceGrantHasGatewayFrom(obj client.Object) bool {
414+
grant, ok := obj.(*v1beta1.ReferenceGrant)
415+
if !ok {
416+
return false
417+
}
418+
for _, from := range grant.Spec.From {
419+
if from.Kind == KindGateway && string(from.Group) == gatewayv1.GroupName {
420+
return true
421+
}
422+
}
423+
return false
424+
}
425+
351426
func (r *GatewayReconciler) processInfrastructure(tctx *provider.TranslateContext, gateway *gatewayv1.Gateway) error {
352427
rk := provider.ResourceKind{
353428
Kind: gateway.Kind,

0 commit comments

Comments
 (0)