Skip to content

Commit 90c6185

Browse files
committed
fix: Fix route-indexer in the StaticService controller
1 parent e1ef0f6 commit 90c6185

File tree

2 files changed

+84
-15
lines changed

2 files changed

+84
-15
lines changed

internal/controllers/udproute.go

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package controllers
22

33
import (
44
"context"
5+
"fmt"
6+
57
// "errors"
68
// "fmt"
79

@@ -364,24 +366,26 @@ func (r *udpRouteReconciler) Reconcile(ctx context.Context, req reconcile.Reques
364366
}
365367

366368
func (r *udpRouteReconciler) validateBackendServiceForReconcile(svc *v1.Service) bool {
367-
return r.validateBackendForReconcile(store.GetObjectKey(svc))
369+
return r.validateBackendForReconcile(store.GetObjectKey(svc), serviceUDPRouteIndex, serviceUDPRouteIndexV1A2)
368370
}
369371

370-
func (r *udpRouteReconciler) validateStaticServiceForReconcile(svc *stnrgwv1.StaticService) bool {
371-
return r.validateBackendForReconcile(store.GetObjectKey(svc))
372+
func (r *udpRouteReconciler) validateStaticServiceForReconcile(staticSvc *stnrgwv1.StaticService) bool {
373+
return r.validateBackendForReconcile(store.GetObjectKey(staticSvc),
374+
staticServiceUDPRouteIndex, staticServiceUDPRouteIndexV1A2)
372375
}
373376

374377
//nolint:staticcheck
375378
func (r *udpRouteReconciler) validateBackendEndpointsForReconcile(e *v1.Endpoints) bool {
376-
return r.validateBackendForReconcile(store.GetObjectKey(e))
379+
return r.validateBackendForReconcile(store.GetObjectKey(e), serviceUDPRouteIndex, serviceUDPRouteIndexV1A2)
377380
}
378381

379-
// validateBackendForReconcile checks whether the Service belongs to a valid UDPRoute.
380-
func (r *udpRouteReconciler) validateBackendForReconcile(key string) bool {
382+
// validateBackendForReconcile checks whether the Service or StaticService belongs to a valid
383+
// UDPRoute. Uses the indexers in the argument.
384+
func (r *udpRouteReconciler) validateBackendForReconcile(key, index, indexV1A2 string) bool {
381385
// find the routes referring to this service
382386
routeList := &stnrgwv1.UDPRouteList{}
383387
if err := r.List(context.Background(), routeList, &client.ListOptions{
384-
FieldSelector: fields.OneTermEqualSelector(serviceUDPRouteIndex, key),
388+
FieldSelector: fields.OneTermEqualSelector(index, key),
385389
}); err != nil {
386390
r.log.Error(err, "Unable to find associated UDPRoute", "service", key)
387391
return false
@@ -390,19 +394,22 @@ func (r *udpRouteReconciler) validateBackendForReconcile(key string) bool {
390394
// find V1A2 routes referring to this service
391395
routeListV1A2 := &gwapiv1a2.UDPRouteList{}
392396
if err := r.List(context.Background(), routeListV1A2, &client.ListOptions{
393-
FieldSelector: fields.OneTermEqualSelector(serviceUDPRouteIndexV1A2, key),
397+
FieldSelector: fields.OneTermEqualSelector(indexV1A2, key),
394398
}); err != nil {
395399
r.log.Error(err, "Unable to find associated UDPRouteV1A2", "service", key)
396400
return false
397401
}
398402

399-
if len(routeList.Items) == 0 && len(routeListV1A2.Items) == 0 {
400-
r.log.Info("Validating backend", "udproute", "not found")
401-
return false
403+
routeNum := len(routeList.Items) + len(routeListV1A2.Items)
404+
resStr := "not found"
405+
if routeNum > 0 {
406+
resStr = fmt.Sprintf("found %d routes", routeNum)
402407
}
403408

404-
r.log.Info("Validate backend", "udproute", "found")
405-
return true
409+
r.log.Info("Validating backend", "key", key, "index", fmt.Sprintf("%s/%s", index, indexV1A2),
410+
"udproute", resStr)
411+
412+
return routeNum != 0
406413
}
407414

408415
// validateEndpointSliceForReconcile checks whether an EndpointSlice belongs to a Service that

test/managed_mode_test.go

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,7 +1380,7 @@ func testManagedMode() {
13801380
}, timeout, interval).Should(BeTrue())
13811381
})
13821382

1383-
It("should survive converting the route to a StaticService backend", func() {
1383+
It("should survive adding a StaticService backend", func() {
13841384
ctrl.Log.Info("adding static service")
13851385
createOrUpdateStaticService(ctx, k8sClient, testStaticSvc, nil)
13861386

@@ -1612,6 +1612,68 @@ func testManagedMode() {
16121612
Expect(s.Status).Should(Equal(metav1.ConditionTrue))
16131613
})
16141614

1615+
It("should handle a StaticService endpoint being changed", func() {
1616+
ctrl.Log.Info("updating static service")
1617+
updatedStaticSvc := testStaticSvc.DeepCopy()
1618+
updatedStaticSvc.Spec = stnrgwv1.StaticServiceSpec{
1619+
Prefixes: []string{"10.11.12.13", "10.11.12.14", "10.11.12.16"},
1620+
}
1621+
createOrUpdateStaticService(ctx, k8sClient, updatedStaticSvc, nil)
1622+
1623+
ctrl.Log.Info("trying to load STUNner config")
1624+
Eventually(checkConfig(ch, func(c *stnrv1.StunnerConfig) bool {
1625+
if len(c.Clusters) == 1 && contains(c.Clusters[0].Endpoints, "10.11.12.16") {
1626+
conf = c
1627+
return true
1628+
}
1629+
return false
1630+
}), timeout, interval).Should(BeTrue())
1631+
})
1632+
1633+
It("should render a correct STUNner config", func() {
1634+
Expect(conf.Listeners).To(HaveLen(2))
1635+
1636+
// not sure about the order
1637+
l := conf.Listeners[0]
1638+
if l.Name != "testnamespace/gateway-1/gateway-1-listener-udp" {
1639+
l = conf.Listeners[1]
1640+
}
1641+
1642+
Expect(l.Name).Should(Equal("testnamespace/gateway-1/gateway-1-listener-udp"))
1643+
Expect(l.Protocol).Should(Equal("TURN-UDP"))
1644+
Expect(l.Port).Should(Equal(1))
1645+
Expect(l.Routes).To(HaveLen(1))
1646+
Expect(l.Routes[0]).Should(Equal("testnamespace/udproute-ok"))
1647+
1648+
l = conf.Listeners[1]
1649+
if l.Name != "testnamespace/gateway-1/gateway-1-listener-dtls" {
1650+
l = conf.Listeners[0]
1651+
}
1652+
1653+
Expect(l.Name).Should(Equal("testnamespace/gateway-1/gateway-1-listener-dtls"))
1654+
Expect(l.Protocol).Should(Equal("TURN-DTLS"))
1655+
Expect(l.Port).Should(Equal(2))
1656+
Expect(l.Routes).To(HaveLen(1))
1657+
Expect(l.Key).NotTo(Equal(""))
1658+
Expect(l.Cert).NotTo(Equal(""))
1659+
Expect(l.Routes[0]).Should(Equal("testnamespace/udproute-ok"))
1660+
1661+
Expect(conf.Clusters).To(HaveLen(1))
1662+
1663+
c := conf.Clusters[0]
1664+
1665+
Expect(c.Name).Should(Equal("testnamespace/udproute-ok"))
1666+
Expect(c.Type).Should(Equal("STATIC"))
1667+
Expect(c.Endpoints).To(HaveLen(8))
1668+
Expect(c.Endpoints).Should(ContainElement("10.11.12.13"))
1669+
Expect(c.Endpoints).Should(ContainElement("10.11.12.14"))
1670+
Expect(c.Endpoints).Should(ContainElement("10.11.12.16"))
1671+
Expect(c.Endpoints).Should(ContainElement("1.2.3.4"))
1672+
Expect(c.Endpoints).Should(ContainElement("1.2.3.5"))
1673+
Expect(c.Endpoints).Should(ContainElement("1.2.3.6"))
1674+
Expect(c.Endpoints).Should(ContainElement("1.2.3.7"))
1675+
})
1676+
16151677
It("should survive converting the route to v1a2 route", func() {
16161678
ctrl.Log.Info("reseting gateway")
16171679
createOrUpdateGateway(ctx, k8sClient, testGw, func(current *gwapiv1.Gateway) {
@@ -1736,7 +1798,7 @@ func testManagedMode() {
17361798
Equal(string(gwapiv1.GatewayConditionProgrammed)))
17371799
Expect(s.Status).Should(Equal(metav1.ConditionTrue))
17381800

1739-
// stragely recreating the gateway lets api-server to find the public ip
1801+
// strangely recreating the gateway lets api-server to find the public ip
17401802
// for the gw so Ready status becomes true (should investigate this)
17411803
Expect(gw.Status.Listeners).To(HaveLen(2))
17421804

0 commit comments

Comments
 (0)