Skip to content

Commit f1eb00f

Browse files
committed
fix: gate experimental gateway api resources
1 parent 803b9a0 commit f1eb00f

20 files changed

Lines changed: 508 additions & 147 deletions

cmd/manager/app.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ import (
3333
"github.com/nantian-gw/gateway/internal/admin"
3434
"github.com/nantian-gw/gateway/internal/config"
3535
"github.com/nantian-gw/gateway/internal/controller"
36-
backendlbv1alpha2 "github.com/nantian-gw/gateway/internal/gatewayapiexperimental/backendlbv1alpha2"
3736
aiservicev1alpha1 "github.com/nantian-gw/gateway/internal/gatewayapiexperimental/aiservicev1alpha1"
37+
backendlbv1alpha2 "github.com/nantian-gw/gateway/internal/gatewayapiexperimental/backendlbv1alpha2"
3838
tokenpolicyv1alpha1 "github.com/nantian-gw/gateway/internal/gatewayapiexperimental/tokenpolicyv1alpha1"
3939
wasmpluginv1alpha1 "github.com/nantian-gw/gateway/internal/gatewayapiexperimental/wasmpluginv1alpha1"
4040
"github.com/nantian-gw/gateway/internal/grpcserver"
@@ -172,27 +172,34 @@ func run(configPath string) error {
172172
},
173173
},
174174
)
175-
statuser := status.NewWithAddressesAndReader(
175+
statusOptions := status.Options{EnableExperimentalGateway: cfg.Features.EnableExperimentalGateway}
176+
statuser := status.NewWithAddressesAndReaderOptions(
176177
mgr.GetClient(),
177178
mgr.GetAPIReader(),
178179
cfg.ControllerName,
179180
cfg.AdvertisedAddresses(),
180181
logger,
182+
statusOptions,
181183
)
182184
statuser.SetEventRecorder(mgr.GetEventRecorderFor("gateway-status"))
183185
if err := translator.SetupIndexes(ctx, mgr.GetFieldIndexer()); err != nil {
184186
return fmt.Errorf("set up translator indexes: %w", err)
185187
}
186-
if err := infrastructure.SetupIndexes(ctx, mgr.GetFieldIndexer()); err != nil {
188+
if err := infrastructure.SetupIndexes(
189+
ctx,
190+
mgr.GetFieldIndexer(),
191+
infrastructure.Options{EnableExperimentalGateway: cfg.Features.EnableExperimentalGateway},
192+
); err != nil {
187193
return fmt.Errorf("set up infrastructure indexes: %w", err)
188194
}
189-
if err := status.SetupIndexes(ctx, mgr.GetFieldIndexer()); err != nil {
195+
if err := status.SetupIndexes(ctx, mgr.GetFieldIndexer(), statusOptions); err != nil {
190196
return fmt.Errorf("set up status indexes: %w", err)
191197
}
192198

193199
infraOptions := infrastructure.DefaultOptions()
194200
infraOptions.SnapshotStore = store
195201
infraOptions.NodeStatus = nodes
202+
infraOptions.EnableExperimentalGateway = cfg.Features.EnableExperimentalGateway
196203
infra := infrastructure.NewWithOptions(mgr.GetClient(), mgr.GetAPIReader(), cfg.ControllerName, infraOptions, logger)
197204
statusScopedReconcile := func(ctx context.Context, scope controller.ReconcilerRunnerScope) error {
198205
switch scope {
@@ -239,14 +246,15 @@ func run(configPath string) error {
239246
logger,
240247
reconcilerRunner.QueueRunForScopes,
241248
)
249+
syncer.SetOptions(controller.SyncerOptions{EnableExperimentalGateway: cfg.Features.EnableExperimentalGateway})
242250
syncer.SetSettleDelay(cfg.SyncSettleDelayDuration())
243251
if err := syncer.SetupWithManager(mgr); err != nil {
244252
return fmt.Errorf("set up snapshot sync controller: %w", err)
245253
}
246254
if err := mgr.Add(syncer); err != nil {
247255
return fmt.Errorf("add syncer runnable: %w", err)
248256
}
249-
if err := status.SetupControllers(mgr, statuser); err != nil {
257+
if err := status.SetupControllers(mgr, statuser, statusOptions); err != nil {
250258
return fmt.Errorf("set up status controllers: %w", err)
251259
}
252260
if err := mgr.Add(reconcilerRunner); err != nil {

internal/controller/reconciler.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,28 +91,28 @@ func (s *Syncer) SetupWithManager(mgr ctrl.Manager) error {
9191
Watches(&corev1.ConfigMap{}, snapshotRequests).
9292
Watches(&discoveryv1.EndpointSlice{}, snapshotRequests, snapshotInputPredicate)
9393

94-
if resourceSupported(mgr, &gatewayv1alpha2.TCPRoute{}) {
94+
if s.options.EnableExperimentalGateway && resourceSupported(mgr, &gatewayv1alpha2.TCPRoute{}) {
9595
controllerBuilder = controllerBuilder.Watches(
9696
&gatewayv1alpha2.TCPRoute{},
9797
snapshotRequests,
9898
snapshotMutationPredicate,
9999
)
100100
}
101-
if resourceSupported(mgr, &gatewayv1alpha2.UDPRoute{}) {
101+
if s.options.EnableExperimentalGateway && resourceSupported(mgr, &gatewayv1alpha2.UDPRoute{}) {
102102
controllerBuilder = controllerBuilder.Watches(
103103
&gatewayv1alpha2.UDPRoute{},
104104
snapshotRequests,
105105
snapshotMutationPredicate,
106106
)
107107
}
108-
if resourceSupported(mgr, &gatewayv1alpha2.TLSRoute{}) {
108+
if s.options.EnableExperimentalGateway && resourceSupported(mgr, &gatewayv1alpha2.TLSRoute{}) {
109109
controllerBuilder = controllerBuilder.Watches(
110110
&gatewayv1alpha2.TLSRoute{},
111111
snapshotRequests,
112112
snapshotMutationPredicate,
113113
)
114114
}
115-
if resourceSupported(mgr, &gatewayv1.ListenerSet{}) {
115+
if s.options.EnableExperimentalGateway && resourceSupported(mgr, &gatewayv1.ListenerSet{}) {
116116
controllerBuilder = controllerBuilder.Watches(
117117
&gatewayv1.ListenerSet{},
118118
snapshotRequests,

internal/controller/syncer.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,21 @@ type Syncer struct {
3333
retryPending snapshotPendingBuild
3434
backendTLSPolicyConfigMapIndex bool
3535
missingFieldIndexFallbacks map[missingFieldIndexFallbackLogKey]struct{}
36+
options SyncerOptions
3637
}
3738

3839
type ComponentReconciler interface {
3940
Reconcile(context.Context) error
4041
}
4142

43+
type SyncerOptions struct {
44+
EnableExperimentalGateway bool
45+
}
46+
47+
func defaultSyncerOptions() SyncerOptions {
48+
return SyncerOptions{EnableExperimentalGateway: true}
49+
}
50+
4251
func NewSyncer(
4352
client client.Client,
4453
translator *translator.Translator,
@@ -62,7 +71,15 @@ func NewSyncer(
6271
logger: logger,
6372
leaderRun: leaderRun,
6473
settleDelay: 0,
74+
options: defaultSyncerOptions(),
75+
}
76+
}
77+
78+
func (s *Syncer) SetOptions(options SyncerOptions) {
79+
if s == nil {
80+
return
6581
}
82+
s.options = options
6683
}
6784

6885
func (s *Syncer) Run(ctx context.Context) {

internal/infrastructure/inspector_support.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"k8s.io/apimachinery/pkg/selection"
1212
"sigs.k8s.io/controller-runtime/pkg/client"
1313
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
14+
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
1415

1516
"github.com/nantian-gw/gateway/internal/ir"
1617
"github.com/nantian-gw/gateway/internal/mesh"
@@ -194,17 +195,22 @@ func (r *Reconciler) loadMeshServiceParents(ctx context.Context) ([]mesh.Service
194195
if err != nil {
195196
return nil, err
196197
}
197-
tcpRoutes, err := listTCPRoutesWithServiceParents(ctx, r.client)
198-
if err != nil {
199-
return nil, err
200-
}
201-
udpRoutes, err := listUDPRoutesWithServiceParents(ctx, r.client)
202-
if err != nil {
203-
return nil, err
204-
}
205-
tlsRoutes, err := listTLSRoutesWithServiceParents(ctx, r.client)
206-
if err != nil {
207-
return nil, err
198+
var tcpRoutes []gatewayv1alpha2.TCPRoute
199+
var udpRoutes []gatewayv1alpha2.UDPRoute
200+
var tlsRoutes []gatewayv1alpha2.TLSRoute
201+
if r.options.EnableExperimentalGateway {
202+
tcpRoutes, err = listTCPRoutesWithServiceParents(ctx, r.client)
203+
if err != nil {
204+
return nil, err
205+
}
206+
udpRoutes, err = listUDPRoutesWithServiceParents(ctx, r.client)
207+
if err != nil {
208+
return nil, err
209+
}
210+
tlsRoutes, err = listTLSRoutesWithServiceParents(ctx, r.client)
211+
if err != nil {
212+
return nil, err
213+
}
208214
}
209215

210216
return collectMeshServiceParents(

internal/infrastructure/reconciler.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,12 @@ var defaultDataplaneSelector = map[string]string{
3434
}
3535

3636
type Options struct {
37-
DataplaneNamespace string
38-
SharedServiceName string
39-
DataplaneSelector map[string]string
40-
SnapshotStore *ir.SnapshotStore
41-
NodeStatus *nodestatus.Registry
37+
DataplaneNamespace string
38+
SharedServiceName string
39+
DataplaneSelector map[string]string
40+
SnapshotStore *ir.SnapshotStore
41+
NodeStatus *nodestatus.Registry
42+
EnableExperimentalGateway bool
4243
}
4344

4445
type Reconciler struct {
@@ -85,9 +86,10 @@ func NewWithOptions(
8586

8687
func DefaultOptions() Options {
8788
return Options{
88-
DataplaneNamespace: defaultDataplaneNamespace,
89-
SharedServiceName: defaultSharedServiceName,
90-
DataplaneSelector: cloneStringMap(defaultDataplaneSelector),
89+
DataplaneNamespace: defaultDataplaneNamespace,
90+
SharedServiceName: defaultSharedServiceName,
91+
DataplaneSelector: cloneStringMap(defaultDataplaneSelector),
92+
EnableExperimentalGateway: true,
9193
}
9294
}
9395

internal/infrastructure/reconciler_mesh_scoped_queries_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,37 @@ func TestReconcileMeshServicesScopesServiceAndEndpointLookups(t *testing.T) {
199199
}
200200
}
201201

202+
func TestLoadMeshServiceParentsStandardModeSkipsExperimentalRouteLists(t *testing.T) {
203+
scheme := newScheme(t)
204+
baseClient := withInfrastructureRouteParentIndexes(
205+
fake.NewClientBuilder().WithScheme(scheme),
206+
).Build()
207+
reconciler := NewWithOptions(
208+
rawValidatingClient{
209+
Client: baseClient,
210+
listValidators: map[reflect.Type]func([]client.ListOption) error{
211+
reflect.TypeOf(&gatewayv1alpha2.TCPRouteList{}): func([]client.ListOption) error {
212+
return fmt.Errorf("standard mode should not list TCPRoutes")
213+
},
214+
reflect.TypeOf(&gatewayv1alpha2.UDPRouteList{}): func([]client.ListOption) error {
215+
return fmt.Errorf("standard mode should not list UDPRoutes")
216+
},
217+
reflect.TypeOf(&gatewayv1alpha2.TLSRouteList{}): func([]client.ListOption) error {
218+
return fmt.Errorf("standard mode should not list TLSRoutes")
219+
},
220+
},
221+
},
222+
nil,
223+
"gateway.networking.k8s.io/nantian-gw",
224+
Options{EnableExperimentalGateway: false},
225+
discardLogger(),
226+
)
227+
228+
if _, err := reconciler.loadMeshServiceParents(context.Background()); err != nil {
229+
t.Fatalf("loadMeshServiceParents returned error: %v", err)
230+
}
231+
}
232+
202233
func TestLoadMeshFrontendNetworkPolicyPortsScopesManagedMeshServices(t *testing.T) {
203234
scheme := newScheme(t)
204235

internal/infrastructure/route_indexes.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ const (
2525
serviceParentIndexMarker = "__service_parent__"
2626
)
2727

28-
func SetupIndexes(ctx context.Context, indexer client.FieldIndexer) error {
28+
func SetupIndexes(ctx context.Context, indexer client.FieldIndexer, options ...Options) error {
29+
enableExperimentalGateway := true
30+
if len(options) > 0 {
31+
enableExperimentalGateway = options[0].EnableExperimentalGateway
32+
}
33+
2934
if err := indexer.IndexField(ctx, &gatewayv1.GatewayClass{}, gatewayClassControllerNameIndex, gatewayClassControllerNameIndexKeys); err != nil {
3035
return fmt.Errorf("index GatewayClass controller name: %w", err)
3136
}
@@ -38,6 +43,10 @@ func SetupIndexes(ctx context.Context, indexer client.FieldIndexer) error {
3843
if err := indexer.IndexField(ctx, &gatewayv1.GRPCRoute{}, grpcRouteServiceParentIndex, grpcRouteServiceParentIndexKeys); err != nil {
3944
return fmt.Errorf("index GRPCRoute service parents: %w", err)
4045
}
46+
if !enableExperimentalGateway {
47+
return nil
48+
}
49+
4150
// v1alpha2 CRDs (TCPRoute, UDPRoute, TLSRoute) are in the experimental
4251
// Gateway API channel. Skip indexing if the CRDs are not installed.
4352
if err := indexer.IndexField(ctx, &gatewayv1alpha2.TCPRoute{}, tcpRouteServiceParentIndex, tcpRouteServiceParentIndexKeys); err != nil {

internal/status/controllers.go

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,25 +30,37 @@ type controllerSetup interface {
3030
SetupWithManager(ctrl.Manager) error
3131
}
3232

33-
func SetupControllers(mgr ctrl.Manager, reconciler *Reconciler) error {
33+
func SetupControllers(mgr ctrl.Manager, reconciler *Reconciler, options ...Options) error {
34+
for _, controller := range statusControllerSetups(reconciler, normalizeOptions(options)) {
35+
if err := controller.SetupWithManager(mgr); err != nil {
36+
return err
37+
}
38+
}
39+
40+
return nil
41+
}
42+
43+
func statusControllerSetups(reconciler *Reconciler, opts Options) []controllerSetup {
3444
controllers := []controllerSetup{
3545
&gatewayClassController{reconciler: reconciler},
36-
&gatewayController{reconciler: reconciler},
46+
&gatewayController{
47+
reconciler: reconciler,
48+
enableExperimentalGateway: opts.EnableExperimentalGateway,
49+
},
3750
&httpRouteController{reconciler: reconciler},
3851
&grpcRouteController{reconciler: reconciler},
39-
&tcpRouteController{reconciler: reconciler},
40-
&udpRouteController{reconciler: reconciler},
41-
&tlsRouteController{reconciler: reconciler},
42-
&listenerSetController{reconciler: reconciler},
4352
}
4453

45-
for _, controller := range controllers {
46-
if err := controller.SetupWithManager(mgr); err != nil {
47-
return err
48-
}
54+
if opts.EnableExperimentalGateway {
55+
controllers = append(controllers,
56+
&tcpRouteController{reconciler: reconciler},
57+
&udpRouteController{reconciler: reconciler},
58+
&tlsRouteController{reconciler: reconciler},
59+
&listenerSetController{reconciler: reconciler},
60+
)
4961
}
5062

51-
return nil
63+
return controllers
5264
}
5365

5466
func statusControllerOptions(maxConcurrentReconciles int) controller.Options {
@@ -102,7 +114,8 @@ func (c *gatewayClassController) SetupWithManager(mgr ctrl.Manager) error {
102114
}
103115

104116
type gatewayController struct {
105-
reconciler *Reconciler
117+
reconciler *Reconciler
118+
enableExperimentalGateway bool
106119
}
107120

108121
func (c *gatewayController) Reconcile(
@@ -120,7 +133,7 @@ func (c *gatewayController) SetupWithManager(mgr ctrl.Manager) error {
120133
gatewayInfrastructureStatusRequests,
121134
)
122135

123-
return ctrl.NewControllerManagedBy(mgr).
136+
controllerBuilder := ctrl.NewControllerManagedBy(mgr).
124137
Named("gateway-status").
125138
WithOptions(statusControllerOptions(2)).
126139
For(&gatewayv1.Gateway{}, generationChanged).
@@ -133,12 +146,16 @@ func (c *gatewayController) SetupWithManager(mgr ctrl.Manager) error {
133146
&discoveryv1.EndpointSlice{},
134147
gatewayInfrastructureRequests,
135148
builder.WithPredicates(gatewayFrontendEndpointSlicePredicate()),
136-
).
137-
Watches(
149+
)
150+
151+
if c.enableExperimentalGateway && resourceSupported(mgr.GetScheme(), mgr.GetRESTMapper(), &gatewayv1.ListenerSet{}) {
152+
controllerBuilder = controllerBuilder.Watches(
138153
&gatewayv1.ListenerSet{},
139154
handler.EnqueueRequestsFromMapFunc(gatewayListenerSetStatusRequests),
140-
).
141-
Complete(c)
155+
)
156+
}
157+
158+
return controllerBuilder.Complete(c)
142159
}
143160

144161
func gatewayInfrastructureServicePredicate() predicate.Predicate {

0 commit comments

Comments
 (0)