Skip to content

Commit 93acaf9

Browse files
committed
support multiple gateways
1 parent f2bc918 commit 93acaf9

31 files changed

+4792
-4423
lines changed

internal/mode/static/handler.go

Lines changed: 85 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -185,64 +185,67 @@ func (h *eventHandlerImpl) sendNginxConfig(
185185
return
186186
}
187187

188-
if gr.Gateway == nil {
189-
// still need to update GatewayClass status
190-
obj := &status.QueueObject{
191-
UpdateType: status.UpdateAll,
188+
for _, gw := range gr.Gateways {
189+
if gw == nil {
190+
// still need to update GatewayClass status
191+
obj := &status.QueueObject{
192+
UpdateType: status.UpdateAll,
193+
}
194+
h.cfg.statusQueue.Enqueue(obj)
195+
return
192196
}
193-
h.cfg.statusQueue.Enqueue(obj)
194-
return
195-
}
196197

197-
go func() {
198-
if err := h.cfg.nginxProvisioner.RegisterGateway(ctx, gr.Gateway, gr.DeploymentName.Name); err != nil {
199-
logger.Error(err, "error from provisioner")
200-
}
201-
}()
198+
go func() {
199+
if err := h.cfg.nginxProvisioner.RegisterGateway(ctx, gw, gw.DeploymentName.Name); err != nil {
200+
logger.Error(err, "error from provisioner")
201+
}
202+
}()
202203

203-
if !gr.Gateway.Valid {
204-
obj := &status.QueueObject{
205-
Deployment: gr.DeploymentName,
206-
UpdateType: status.UpdateAll,
204+
if !gw.Valid {
205+
obj := &status.QueueObject{
206+
Deployment: gw.DeploymentName,
207+
UpdateType: status.UpdateAll,
208+
}
209+
h.cfg.statusQueue.Enqueue(obj)
210+
return
207211
}
208-
h.cfg.statusQueue.Enqueue(obj)
209-
return
210-
}
211212

212-
stopCh := make(chan struct{})
213-
deployment := h.cfg.nginxDeployments.GetOrStore(ctx, gr.DeploymentName, stopCh)
214-
if deployment == nil {
215-
panic("expected deployment, got nil")
216-
}
213+
stopCh := make(chan struct{})
214+
deployment := h.cfg.nginxDeployments.GetOrStore(ctx, gw.DeploymentName, stopCh)
215+
if deployment == nil {
216+
panic("expected deployment, got nil")
217+
}
217218

218-
configApplied := h.processStateAndBuildConfig(ctx, logger, gr, changeType, deployment)
219+
configApplied := h.processStateAndBuildConfig(ctx, logger, gr, gw, changeType, deployment)
219220

220-
configErr := deployment.GetLatestConfigError()
221-
upstreamErr := deployment.GetLatestUpstreamError()
222-
err := errors.Join(configErr, upstreamErr)
221+
configErr := deployment.GetLatestConfigError()
222+
upstreamErr := deployment.GetLatestUpstreamError()
223+
err := errors.Join(configErr, upstreamErr)
223224

224-
if configApplied || err != nil {
225-
obj := &status.QueueObject{
226-
UpdateType: status.UpdateAll,
227-
Error: err,
228-
Deployment: gr.DeploymentName,
225+
if configApplied || err != nil {
226+
obj := &status.QueueObject{
227+
UpdateType: status.UpdateAll,
228+
Error: err,
229+
Deployment: gw.DeploymentName,
230+
}
231+
h.cfg.statusQueue.Enqueue(obj)
229232
}
230-
h.cfg.statusQueue.Enqueue(obj)
231233
}
232234
}
233235

234236
func (h *eventHandlerImpl) processStateAndBuildConfig(
235237
ctx context.Context,
236238
logger logr.Logger,
237239
gr *graph.Graph,
240+
currentGateway *graph.Gateway,
238241
changeType state.ChangeType,
239242
deployment *agent.Deployment,
240243
) bool {
241244
var configApplied bool
242245
switch changeType {
243246
case state.EndpointsOnlyChange:
244247
h.version++
245-
cfg := dataplane.BuildConfiguration(ctx, gr, h.cfg.serviceResolver, h.version, h.cfg.plus)
248+
cfg := dataplane.BuildConfiguration(ctx, gr, currentGateway, h.cfg.serviceResolver, h.version, h.cfg.plus)
246249
depCtx, getErr := h.getDeploymentContext(ctx)
247250
if getErr != nil {
248251
logger.Error(getErr, "error getting deployment context for usage reporting")
@@ -260,7 +263,7 @@ func (h *eventHandlerImpl) processStateAndBuildConfig(
260263
deployment.FileLock.Unlock()
261264
case state.ClusterStateChange:
262265
h.version++
263-
cfg := dataplane.BuildConfiguration(ctx, gr, h.cfg.serviceResolver, h.version, h.cfg.plus)
266+
cfg := dataplane.BuildConfiguration(ctx, gr, currentGateway, h.cfg.serviceResolver, h.version, h.cfg.plus)
264267
depCtx, getErr := h.getDeploymentContext(ctx)
265268
if getErr != nil {
266269
logger.Error(getErr, "error getting deployment context for usage reporting")
@@ -292,56 +295,58 @@ func (h *eventHandlerImpl) waitForStatusUpdates(ctx context.Context) {
292295
}
293296

294297
var nginxReloadRes graph.NginxReloadResult
295-
switch {
296-
case item.Error != nil:
297-
h.cfg.logger.Error(item.Error, "Failed to update NGINX configuration")
298-
nginxReloadRes.Error = item.Error
299-
case gr.Gateway != nil:
300-
h.cfg.logger.Info("NGINX configuration was successfully updated")
301-
}
302-
gr.LatestReloadResult = nginxReloadRes
303-
304-
switch item.UpdateType {
305-
case status.UpdateAll:
306-
h.updateStatuses(ctx, gr)
307-
case status.UpdateGateway:
308-
gwAddresses, err := getGatewayAddresses(
309-
ctx,
310-
h.cfg.k8sClient,
311-
item.GatewayService,
312-
gr.Gateway,
313-
h.cfg.gatewayClassName,
314-
)
315-
if err != nil {
316-
msg := "error getting Gateway Service IP address"
317-
h.cfg.logger.Error(err, msg)
318-
h.cfg.eventRecorder.Eventf(
298+
for _, gw := range gr.Gateways {
299+
switch {
300+
case item.Error != nil:
301+
h.cfg.logger.Error(item.Error, "Failed to update NGINX configuration")
302+
nginxReloadRes.Error = item.Error
303+
case gw != nil:
304+
h.cfg.logger.Info("NGINX configuration was successfully updated")
305+
}
306+
gr.LatestReloadResult = nginxReloadRes
307+
308+
switch item.UpdateType {
309+
case status.UpdateAll:
310+
h.updateStatuses(ctx, gr, gw)
311+
case status.UpdateGateway:
312+
gwAddresses, err := getGatewayAddresses(
313+
ctx,
314+
h.cfg.k8sClient,
319315
item.GatewayService,
320-
v1.EventTypeWarning,
321-
"GetServiceIPFailed",
322-
msg+": %s",
323-
err.Error(),
316+
gw,
317+
h.cfg.gatewayClassName,
324318
)
325-
continue
319+
if err != nil {
320+
msg := "error getting Gateway Service IP address"
321+
h.cfg.logger.Error(err, msg)
322+
h.cfg.eventRecorder.Eventf(
323+
item.GatewayService,
324+
v1.EventTypeWarning,
325+
"GetServiceIPFailed",
326+
msg+": %s",
327+
err.Error(),
328+
)
329+
continue
330+
}
331+
332+
transitionTime := metav1.Now()
333+
334+
gatewayStatuses := status.PrepareGatewayRequests(
335+
gw,
336+
transitionTime,
337+
gwAddresses,
338+
gr.LatestReloadResult,
339+
)
340+
h.cfg.statusUpdater.UpdateGroup(ctx, groupGateways, gatewayStatuses...)
341+
default:
342+
panic(fmt.Sprintf("unknown event type %T", item.UpdateType))
326343
}
327-
328-
transitionTime := metav1.Now()
329-
gatewayStatuses := status.PrepareGatewayRequests(
330-
gr.Gateway,
331-
gr.IgnoredGateways,
332-
transitionTime,
333-
gwAddresses,
334-
gr.LatestReloadResult,
335-
)
336-
h.cfg.statusUpdater.UpdateGroup(ctx, groupGateways, gatewayStatuses...)
337-
default:
338-
panic(fmt.Sprintf("unknown event type %T", item.UpdateType))
339344
}
340345
}
341346
}
342347

343-
func (h *eventHandlerImpl) updateStatuses(ctx context.Context, gr *graph.Graph) {
344-
gwAddresses, err := getGatewayAddresses(ctx, h.cfg.k8sClient, nil, gr.Gateway, h.cfg.gatewayClassName)
348+
func (h *eventHandlerImpl) updateStatuses(ctx context.Context, gr *graph.Graph, gw *graph.Gateway) {
349+
gwAddresses, err := getGatewayAddresses(ctx, h.cfg.k8sClient, nil, gw, h.cfg.gatewayClassName)
345350
if err != nil {
346351
msg := "error getting Gateway Service IP address"
347352
h.cfg.logger.Error(err, msg)
@@ -392,8 +397,7 @@ func (h *eventHandlerImpl) updateStatuses(ctx context.Context, gr *graph.Graph)
392397
// We put Gateway status updates separately from the rest of the statuses because we want to be able
393398
// to update them separately from the rest of the graph whenever the public IP of NGF changes.
394399
gwReqs := status.PrepareGatewayRequests(
395-
gr.Gateway,
396-
gr.IgnoredGateways,
400+
gw,
397401
transitionTime,
398402
gwAddresses,
399403
gr.LatestReloadResult,

internal/mode/static/handler_test.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,11 @@ var _ = Describe("eventHandler", func() {
9696
ctx, cancel = context.WithCancel(context.Background()) //nolint:fatcontext // ignore for test
9797

9898
baseGraph = &graph.Graph{
99-
Gateway: &graph.Gateway{
100-
Valid: true,
101-
Source: &gatewayv1.Gateway{},
99+
Gateways: map[types.NamespacedName]*graph.Gateway{
100+
{}: {
101+
Valid: true,
102+
Source: &gatewayv1.Gateway{},
103+
},
102104
},
103105
}
104106

@@ -185,7 +187,7 @@ var _ = Describe("eventHandler", func() {
185187

186188
handler.HandleEventBatch(context.Background(), logr.Discard(), batch)
187189

188-
dcfg := dataplane.GetDefaultConfiguration(&graph.Graph{}, 1)
190+
dcfg := dataplane.GetDefaultConfiguration(&graph.Graph{}, 1, &graph.Gateway{})
189191

190192
checkUpsertEventExpectations(e)
191193
expectReconfig(dcfg, fakeCfgFiles)
@@ -201,7 +203,7 @@ var _ = Describe("eventHandler", func() {
201203

202204
handler.HandleEventBatch(context.Background(), logr.Discard(), batch)
203205

204-
dcfg := dataplane.GetDefaultConfiguration(&graph.Graph{}, 1)
206+
dcfg := dataplane.GetDefaultConfiguration(&graph.Graph{}, 1, &graph.Gateway{})
205207

206208
checkDeleteEventExpectations(e)
207209
expectReconfig(dcfg, fakeCfgFiles)
@@ -238,7 +240,7 @@ var _ = Describe("eventHandler", func() {
238240

239241
handler.HandleEventBatch(context.Background(), logr.Discard(), batch)
240242

241-
dcfg := dataplane.GetDefaultConfiguration(&graph.Graph{}, 2)
243+
dcfg := dataplane.GetDefaultConfiguration(&graph.Graph{}, 2, &graph.Gateway{})
242244
Expect(helpers.Diff(handler.GetLatestConfiguration(), &dcfg)).To(BeEmpty())
243245
})
244246
})
@@ -268,6 +270,7 @@ var _ = Describe("eventHandler", func() {
268270
IgnoredGatewayClasses: map[types.NamespacedName]*gatewayv1.GatewayClass{
269271
client.ObjectKeyFromObject(ignoredGC): ignoredGC,
270272
},
273+
Gateways: map[types.NamespacedName]*graph.Gateway{},
271274
}
272275

273276
fakeProcessor.ProcessReturns(state.ClusterStateChange, gr)
@@ -392,7 +395,11 @@ var _ = Describe("eventHandler", func() {
392395
batch := []interface{}{e}
393396

394397
BeforeEach(func() {
395-
fakeProcessor.ProcessReturns(state.EndpointsOnlyChange, &graph.Graph{Gateway: &graph.Gateway{Valid: true}})
398+
fakeProcessor.ProcessReturns(state.EndpointsOnlyChange, &graph.Graph{
399+
Gateways: map[types.NamespacedName]*graph.Gateway{
400+
{}: {Valid: true},
401+
},
402+
})
396403
})
397404

398405
When("running NGINX Plus", func() {
@@ -401,7 +408,7 @@ var _ = Describe("eventHandler", func() {
401408

402409
handler.HandleEventBatch(context.Background(), logr.Discard(), batch)
403410

404-
dcfg := dataplane.GetDefaultConfiguration(&graph.Graph{}, 1)
411+
dcfg := dataplane.GetDefaultConfiguration(&graph.Graph{}, 1, &graph.Gateway{})
405412
dcfg.NginxPlus = dataplane.NginxPlus{AllowedAddresses: []string{"127.0.0.1"}}
406413
Expect(helpers.Diff(handler.GetLatestConfiguration(), &dcfg)).To(BeEmpty())
407414

@@ -414,7 +421,7 @@ var _ = Describe("eventHandler", func() {
414421
It("should not call the NGINX Plus API", func() {
415422
handler.HandleEventBatch(context.Background(), logr.Discard(), batch)
416423

417-
dcfg := dataplane.GetDefaultConfiguration(&graph.Graph{}, 1)
424+
dcfg := dataplane.GetDefaultConfiguration(&graph.Graph{}, 1, &graph.Gateway{})
418425
Expect(helpers.Diff(handler.GetLatestConfiguration(), &dcfg)).To(BeEmpty())
419426

420427
Expect(fakeGenerator.GenerateCallCount()).To(Equal(1))
@@ -460,12 +467,16 @@ var _ = Describe("eventHandler", func() {
460467
batch := []interface{}{e}
461468
readyChannel := handler.cfg.graphBuiltHealthChecker.getReadyCh()
462469

463-
fakeProcessor.ProcessReturns(state.ClusterStateChange, &graph.Graph{Gateway: &graph.Gateway{Valid: true}})
470+
fakeProcessor.ProcessReturns(state.ClusterStateChange, &graph.Graph{
471+
Gateways: map[types.NamespacedName]*graph.Gateway{
472+
{}: {Valid: true},
473+
},
474+
})
464475

465476
Expect(handler.cfg.graphBuiltHealthChecker.readyCheck(nil)).ToNot(Succeed())
466477
handler.HandleEventBatch(context.Background(), logr.Discard(), batch)
467478

468-
dcfg := dataplane.GetDefaultConfiguration(&graph.Graph{}, 1)
479+
dcfg := dataplane.GetDefaultConfiguration(&graph.Graph{}, 1, &graph.Gateway{})
469480
Expect(helpers.Diff(handler.GetLatestConfiguration(), &dcfg)).To(BeEmpty())
470481

471482
Expect(readyChannel).To(BeClosed())

0 commit comments

Comments
 (0)