Skip to content
This repository was archived by the owner on Dec 2, 2025. It is now read-only.

Commit 3541a1a

Browse files
Niklaus-xiegitee-org
authored andcommitted
!52 cross namespace routing for gateway and httproute
Merge pull request !52 from niklaus-x/cross-ns-work0105
2 parents 75a131b + 158c620 commit 3541a1a

File tree

4 files changed

+115
-13
lines changed

4 files changed

+115
-13
lines changed

controllers/v1_controller.go

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,36 @@ type NodeReconciler struct {
4848
Scheme *runtime.Scheme
4949
}
5050

51+
type NamespaceReconciler struct {
52+
client.Client
53+
Scheme *runtime.Scheme
54+
}
55+
56+
func (r *NamespaceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
57+
if !pkg.ActiveSIGs.SyncedAtStart {
58+
<-time.After(100 * time.Millisecond)
59+
return ctrl.Result{Requeue: true}, nil
60+
}
61+
62+
var obj v1.Namespace
63+
64+
lctx := context.WithValue(ctx, utils.CtxKey_Logger, utils.NewLog(uuid.New().String(), "debug"))
65+
slog := utils.LogFromContext(lctx)
66+
slog.Debugf("Namespace event: " + req.Name)
67+
68+
if err := r.Get(ctx, req.NamespacedName, &obj); err != nil {
69+
if client.IgnoreNotFound(err) == nil {
70+
pkg.ActiveSIGs.UnsetNamespace(req.Name)
71+
return ctrl.Result{}, nil
72+
} else {
73+
return ctrl.Result{}, err
74+
}
75+
} else {
76+
pkg.ActiveSIGs.SetNamespace(obj.DeepCopy())
77+
return ctrl.Result{}, nil
78+
}
79+
}
80+
5181
func (r *EndpointsReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
5282
lctx := context.WithValue(ctx, utils.CtxKey_Logger, utils.NewLog(uuid.New().String(), "debug"))
5383
var obj v1.Endpoints
@@ -149,18 +179,20 @@ func (r *NodeReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
149179

150180
// SetupReconcilerForCoreV1WithManager sets up the v1 controllers with the Manager.
151181
func SetupReconcilerForCoreV1WithManager(mgr ctrl.Manager) error {
152-
rEps, rSvc, rNode :=
182+
rEps, rSvc, rNode, rNs :=
153183
&EndpointsReconciler{Client: mgr.GetClient(), Scheme: mgr.GetScheme()},
154184
&ServiceReconciler{Client: mgr.GetClient(), Scheme: mgr.GetScheme()},
155-
&NodeReconciler{Client: mgr.GetClient(), Scheme: mgr.GetScheme()}
185+
&NodeReconciler{Client: mgr.GetClient(), Scheme: mgr.GetScheme()},
186+
&NamespaceReconciler{Client: mgr.GetClient(), Scheme: mgr.GetScheme()}
156187

157-
err1, err2, err3 :=
188+
err1, err2, err3, err4 :=
158189
ctrl.NewControllerManagedBy(mgr).For(&v1.Endpoints{}).Complete(rEps),
159190
ctrl.NewControllerManagedBy(mgr).For(&v1.Service{}).Complete(rSvc),
160-
ctrl.NewControllerManagedBy(mgr).For(&v1.Node{}).Complete(rNode)
191+
ctrl.NewControllerManagedBy(mgr).For(&v1.Node{}).Complete(rNode),
192+
ctrl.NewControllerManagedBy(mgr).For(&v1.Namespace{}).Complete(rNs)
161193

162194
errmsg := ""
163-
for _, err := range []error{err1, err2, err3} {
195+
for _, err := range []error{err1, err2, err3, err4} {
164196
if err != nil {
165197
errmsg += err.Error() + ";"
166198
}

pkg/cache.go

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,31 +30,48 @@ func init() {
3030
HTTPRoute: map[string]*gatewayv1beta1.HTTPRoute{},
3131
Endpoints: map[string]*v1.Endpoints{},
3232
Service: map[string]*v1.Service{},
33-
GatewayClasses: map[string]*gatewayv1beta1.GatewayClass{},
33+
GatewayClass: map[string]*gatewayv1beta1.GatewayClass{},
34+
Namespace: map[string]*v1.Namespace{},
3435
}
3536
}
3637

38+
func (c *SIGCache) SetNamespace(obj *v1.Namespace) {
39+
c.mutex.Lock()
40+
defer c.mutex.Unlock()
41+
42+
if obj != nil {
43+
c.Namespace[obj.Name] = obj
44+
}
45+
}
46+
47+
func (c *SIGCache) UnsetNamespace(keyname string) {
48+
c.mutex.Lock()
49+
defer c.mutex.Unlock()
50+
51+
delete(c.Namespace, keyname)
52+
}
53+
3754
func (c *SIGCache) SetGatewayClass(obj *gatewayv1beta1.GatewayClass) {
3855
c.mutex.Lock()
3956
defer c.mutex.Unlock()
4057

4158
if obj != nil {
42-
c.GatewayClasses[obj.Name] = obj
59+
c.GatewayClass[obj.Name] = obj
4360
}
4461
}
4562

4663
func (c *SIGCache) UnsetGatewayClass(keyname string) {
4764
c.mutex.Lock()
4865
defer c.mutex.Unlock()
4966

50-
delete(c.GatewayClasses, keyname)
67+
delete(c.GatewayClass, keyname)
5168
}
5269

5370
func (c *SIGCache) GetGatewayClass(keyname string) *gatewayv1beta1.GatewayClass {
5471
c.mutex.RLock()
5572
defer c.mutex.RUnlock()
5673

57-
return c.GatewayClasses[keyname]
74+
return c.GatewayClass[keyname]
5875
}
5976

6077
func (c *SIGCache) SetGateway(obj *gatewayv1beta1.Gateway) {
@@ -211,6 +228,15 @@ func (c *SIGCache) _attachedHTTPRoutes(gw *gatewayv1beta1.Gateway) []*gatewayv1b
211228
return []*gatewayv1beta1.HTTPRoute{}
212229
}
213230

231+
allowedRoutes := map[string]*gatewayv1beta1.AllowedRoutes{}
232+
for _, listener := range gw.Spec.Listeners {
233+
vsname := gwListenerName(gw, &listener)
234+
235+
if listener.AllowedRoutes != nil {
236+
allowedRoutes[vsname] = listener.AllowedRoutes
237+
}
238+
}
239+
214240
hrs := []*gatewayv1beta1.HTTPRoute{}
215241
for _, hr := range ActiveSIGs.HTTPRoute {
216242
for _, pr := range hr.Spec.ParentRefs {
@@ -219,7 +245,15 @@ func (c *SIGCache) _attachedHTTPRoutes(gw *gatewayv1beta1.Gateway) []*gatewayv1b
219245
ns = string(*pr.Namespace)
220246
}
221247
if utils.Keyname(ns, string(pr.Name)) == utils.Keyname(gw.Namespace, gw.Name) {
222-
hrs = append(hrs, hr)
248+
vsname := hrParentName(hr, &pr)
249+
if allowed, ok := allowedRoutes[vsname]; ok {
250+
if routeNs, ok := ActiveSIGs.Namespace[hr.Namespace]; ok {
251+
matched := namespaceMatches(gw.Namespace, allowed.Namespaces, routeNs)
252+
if matched {
253+
hrs = append(hrs, hr)
254+
}
255+
}
256+
}
223257
}
224258
}
225259
}
@@ -274,7 +308,7 @@ func (c *SIGCache) AllAttachedServiceKeys() []string {
274308
defer c.mutex.RUnlock()
275309

276310
svcs := []string{}
277-
for _, gwc := range c.GatewayClasses {
311+
for _, gwc := range c.GatewayClass {
278312
for _, gw := range c._attachedGateways(gwc) {
279313
for _, hr := range c._attachedHTTPRoutes(gw) {
280314
svcs = append(svcs, c._attachedServiceKeys(hr)...)
@@ -438,6 +472,7 @@ func (c *SIGCache) syncCoreV1Resources(mgr manager.Manager) error {
438472
c.Endpoints[utils.Keyname(eps.Namespace, eps.Name)] = eps.DeepCopy()
439473
}
440474
}
475+
441476
if svcList, err := kubeClient.CoreV1().Services(v1.NamespaceAll).List(context.TODO(), metav1.ListOptions{}); err != nil {
442477
return err
443478
} else {
@@ -446,6 +481,16 @@ func (c *SIGCache) syncCoreV1Resources(mgr manager.Manager) error {
446481
c.Service[utils.Keyname(svc.Namespace, svc.Name)] = svc.DeepCopy()
447482
}
448483
}
484+
485+
if nsList, err := kubeClient.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{}); err != nil {
486+
return nil
487+
} else {
488+
for _, ns := range nsList.Items {
489+
slog.Debugf("found ns: %s", ns.Name)
490+
c.Namespace[ns.Name] = ns.DeepCopy()
491+
}
492+
}
493+
449494
if nList, err := kubeClient.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{}); err != nil {
450495
return err
451496
} else {
@@ -495,7 +540,7 @@ func (c *SIGCache) syncGatewayResources(mgr manager.Manager) error {
495540
for _, gwc := range gwcList.Items {
496541
if gwc.Spec.ControllerName == gatewayv1beta1.GatewayController(ActiveSIGs.ControllerName) {
497542
slog.Debugf("found gatewayclass %s", gwc.Name)
498-
c.GatewayClasses[gwc.Name] = gwc.DeepCopy()
543+
c.GatewayClass[gwc.Name] = gwc.DeepCopy()
499544
} else {
500545
msg := fmt.Sprintf("This gwc's ControllerName %s not equal to this controller. Ignore.", gwc.Spec.ControllerName)
501546
slog.Debugf(msg)

pkg/types.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ type SIGCache struct {
3232
HTTPRoute map[string]*gatewayv1beta1.HTTPRoute
3333
Endpoints map[string]*v1.Endpoints
3434
Service map[string]*v1.Service
35-
GatewayClasses map[string]*gatewayv1beta1.GatewayClass
35+
GatewayClass map[string]*gatewayv1beta1.GatewayClass
36+
Namespace map[string]*v1.Namespace
3637
}
3738

3839
type BIGIPConfigs []BIGIPConfig

pkg/utils.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package pkg
33
import (
44
"strings"
55

6+
v1 "k8s.io/api/core/v1"
7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8+
"k8s.io/apimachinery/pkg/labels"
69
gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
710
)
811

@@ -21,3 +24,24 @@ func hrParentName(hr *gatewayv1beta1.HTTPRoute, pr *gatewayv1beta1.ParentReferen
2124
func gwListenerName(gw *gatewayv1beta1.Gateway, ls *gatewayv1beta1.Listener) string {
2225
return strings.Join([]string{"gw", gw.Namespace, gw.Name, string(ls.Name)}, ".")
2326
}
27+
28+
func namespaceMatches(gwNamespace string, namespaces *gatewayv1beta1.RouteNamespaces, routeNs *v1.Namespace) bool {
29+
if namespaces == nil || namespaces.From == nil {
30+
return true
31+
}
32+
33+
switch *namespaces.From {
34+
case gatewayv1beta1.NamespacesFromAll:
35+
return true
36+
case gatewayv1beta1.NamespacesFromSame:
37+
return gwNamespace == routeNs.Name
38+
case gatewayv1beta1.NamespacesFromSelector:
39+
if selector, err := metav1.LabelSelectorAsSelector(namespaces.Selector); err != nil {
40+
return false
41+
} else {
42+
return selector.Matches(labels.Set(routeNs.Labels))
43+
}
44+
}
45+
46+
return true
47+
}

0 commit comments

Comments
 (0)