Skip to content

Commit 8b62ff7

Browse files
wenyingdcursoragent
andcommitted
feat(gateway): configure DNS records for Gateway API Route resources
- Reconcile DNS records for HTTPRoute/TLSRoute resources via the Gateway controller using VPCNetworkConfiguration allowed DNS zones - Implement missing controller-runtime v0.23.3 interface methods in mock implementations for cache.Informer and manager.Manager Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 4cfcb3a commit 8b62ff7

40 files changed

Lines changed: 7544 additions & 9 deletions

cmd/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ import (
2323
"sigs.k8s.io/controller-runtime/pkg/manager"
2424
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
2525
"sigs.k8s.io/controller-runtime/pkg/webhook"
26+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
2627

2728
"github.com/vmware-tanzu/nsx-operator/pkg/apis/legacy/v1alpha1"
2829
crdv1alpha1 "github.com/vmware-tanzu/nsx-operator/pkg/apis/vpc/v1alpha1"
2930
"github.com/vmware-tanzu/nsx-operator/pkg/config"
31+
"github.com/vmware-tanzu/nsx-operator/pkg/controllers/gateway"
3032
"github.com/vmware-tanzu/nsx-operator/pkg/controllers/inventory"
3133
"github.com/vmware-tanzu/nsx-operator/pkg/controllers/ipaddressallocation"
3234
namespacecontroller "github.com/vmware-tanzu/nsx-operator/pkg/controllers/namespace"
@@ -83,6 +85,7 @@ func init() {
8385
utilruntime.Must(crdv1alpha1.AddToScheme(scheme))
8486
utilruntime.Must(v1alpha1.AddToScheme(scheme))
8587
utilruntime.Must(vmv1alpha1.AddToScheme(scheme))
88+
utilruntime.Must(gatewayv1.Install(scheme))
8689
config.AddFlags()
8790

8891
cf, err = config.NewNSXOperatorConfigFromFile()
@@ -248,6 +251,7 @@ func startServiceController(mgr manager.Manager, nsxClient *nsx.Client) {
248251
pod.NewPodReconciler(mgr, subnetPortService, subnetService, vpcService, nodeService),
249252
networkpolicycontroller.NewNetworkPolicyReconciler(mgr, commonService, vpcService),
250253
service.NewServiceLbReconciler(mgr, commonService, dnsRecordService),
254+
gateway.NewGatewayReconciler(mgr, dnsRecordService),
251255
subnetbindingcontroller.NewReconciler(mgr, subnetService, subnetBindingService),
252256
subnetipreservationcontroller.NewReconciler(mgr, subnetIPReservationService, subnetService),
253257
)

go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ require (
5656
github.com/gofrs/uuid v4.4.0+incompatible
5757
go.openly.dev/pointy v1.3.0
5858
go.uber.org/mock v0.6.0
59+
sigs.k8s.io/gateway-api v1.5.0
5960
)
6061

6162
require (
@@ -64,7 +65,6 @@ require (
6465
github.com/cespare/xxhash/v2 v2.3.0 // indirect
6566
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
6667
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
67-
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
6868
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
6969
github.com/fsnotify/fsnotify v1.9.0 // indirect
7070
github.com/fxamacker/cbor/v2 v2.9.1 // indirect
@@ -97,7 +97,6 @@ require (
9797
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
9898
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
9999
github.com/onsi/ginkgo/v2 v2.28.1 // indirect
100-
github.com/onsi/gomega v1.39.1 // indirect
101100
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
102101
github.com/prometheus/client_model v0.6.2 // indirect
103102
github.com/prometheus/common v0.67.5 // indirect

go.sum

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsP
2323
github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo=
2424
github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes=
2525
github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
26-
github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
27-
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
26+
github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k=
27+
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
2828
github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=
2929
github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=
3030
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
@@ -293,6 +293,8 @@ k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0x
293293
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
294294
sigs.k8s.io/controller-runtime v0.23.3 h1:VjB/vhoPoA9l1kEKZHBMnQF33tdCLQKJtydy4iqwZ80=
295295
sigs.k8s.io/controller-runtime v0.23.3/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
296+
sigs.k8s.io/gateway-api v1.5.0 h1:duoo14Ky/fJXpjpmyMISE2RTBGnfCg8zICfTYLTnBJA=
297+
sigs.k8s.io/gateway-api v1.5.0/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o=
296298
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
297299
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
298300
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=

pkg/controllers/common/types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const (
2525
MetricResTypeNode = "node"
2626
MetricResTypeServiceLb = "servicelb"
2727
MetricResTypeStatefulSet = "statefulset"
28+
MetricResTypeGateway = "gateway"
2829
MaxConcurrentReconciles = 8
2930
NSXOperatorError = "nsx-op/error"
3031
//sync the error with NCP side
@@ -35,6 +36,9 @@ const (
3536

3637
LabelK8sMasterRole = "node-role.kubernetes.io/master"
3738
LabelK8sControlRole = "node-role.kubernetes.io/control-plane"
39+
40+
ManagedK8sGatewayClassIstio = "istio"
41+
ManagedK8sGatewayClassAviLB = "avi-lb"
3842
)
3943

4044
var (
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* Copyright © 2026 Broadcom, Inc. All Rights Reserved.
2+
SPDX-License-Identifier: Apache-2.0 */
3+
4+
package gateway
5+
6+
import (
7+
"k8s.io/apimachinery/pkg/types"
8+
9+
"github.com/vmware-tanzu/nsx-operator/pkg/nsx/services/dns"
10+
extdns "github.com/vmware-tanzu/nsx-operator/pkg/third_party/externaldns/endpoint"
11+
)
12+
13+
// Route DNS: hostnames + ipCache → extdns.Endpoint.
14+
// Gateway annotation-hostname DNS (collectGatewayEndpointsByAnnotation / buildEndpointsFromAnnotations)
15+
// was moved to dns-networkinfo-hostname to separate the hostname-conflict-resolution feature.
16+
17+
type parentGatewayMatch struct {
18+
nn types.NamespacedName
19+
filter string
20+
ips extdns.Targets
21+
}
22+
23+
func mergeTargetsUnion(a, b extdns.Targets) extdns.Targets {
24+
return extdns.NewTargets(append(append([]string(nil), a...), b...)...)
25+
}
26+
27+
// buildRouteDNSMergedEndpoints builds owner-scoped Route DNS rows (Gateway or ListenerSet→root Gateway, same rules as aggregation).
28+
func (a routeReconcilerAdapter[PT, T]) buildRouteDNSMergedEndpoints(route PT) (*dns.AggregatedDNSEndpoints, map[string]string, error) {
29+
owner := route.GetResourceRef()
30+
eps, allowed, err := a.reconciler.buildRouteDNSEndpointsForAggregation(route.GetNamespace(), owner, route.GetParentRefs(), route.GetRouteParentStatus(), route.GetObjectMeta(), route.GetSpecHostnames())
31+
if err != nil || len(eps) == 0 {
32+
return nil, allowed, err
33+
}
34+
return dns.NewOwnerScopedAggregatedRouteDNS(owner, eps), allowed, nil
35+
}
36+
37+
// buildEndpoints appends extdns endpoints per hostname; sets EndpointLabelParentGateway to gatewayLabel (comma-separated if merged).
38+
func buildEndpoints(out *[]*extdns.Endpoint, hostnames []string, targets extdns.Targets, parentGatewayLabel string) {
39+
ttl := extdns.TTL(0)
40+
for _, h := range hostnames {
41+
if h == "" {
42+
continue
43+
}
44+
for _, ep := range extdns.EndpointsForHostname(h, targets, ttl) {
45+
if ep == nil {
46+
continue
47+
}
48+
if parentGatewayLabel != "" {
49+
ep.WithLabel(dns.EndpointLabelParentGateway, parentGatewayLabel)
50+
}
51+
*out = append(*out, ep)
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)