From 972b20aee7c764217d8772502856aca5333c59c1 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Wed, 26 Jul 2023 13:45:13 -0400 Subject: [PATCH] api-gateway: subscribe to bound-api-gateway only after receiving api-gateway This fixes a race condition due to our dependency on having the listener(s) from the api-gateway config entry in order to fully and properly process the resources on the bound-api-gateway config entry. --- agent/proxycfg/api_gateway.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/agent/proxycfg/api_gateway.go b/agent/proxycfg/api_gateway.go index 41eb5921259e..35bbc8759618 100644 --- a/agent/proxycfg/api_gateway.go +++ b/agent/proxycfg/api_gateway.go @@ -54,12 +54,6 @@ func (h *handlerAPIGateway) initialize(ctx context.Context) (ConfigSnapshot, err return snap, err } - // Watch the bound-api-gateway's config entry - err = h.subscribeToConfigEntry(ctx, structs.BoundAPIGateway, h.service, h.proxyID.EnterpriseMeta, boundGatewayConfigWatchID) - if err != nil { - return snap, err - } - snap.APIGateway.Listeners = make(map[string]structs.APIGatewayListener) snap.APIGateway.BoundListeners = make(map[string]structs.BoundAPIGatewayListener) snap.APIGateway.HTTPRoutes = watch.NewMap[structs.ResourceReference, *structs.HTTPRouteConfigEntry]() @@ -143,10 +137,12 @@ func (h *handlerAPIGateway) handleRootCAUpdate(u UpdateEvent, snap *ConfigSnapsh return nil } -// handleGatewayConfigUpdate responds to changes in the watched config entry for a gateway. -// In particular, we want to make sure that we're subscribing to any attached resources such -// as routes and certificates. These additional subscriptions will enable us to update the -// config snapshot appropriately for any route or certificate changes. +// handleGatewayConfigUpdate responds to changes in the watched config entries for a gateway. +// Once the base api-gateway config entry has been seen, we store the list of listeners and +// then subscribe to the corresponding bound-api-gateway config entry. We use the bound-api-gateway +// config entry to subscribing to any attached resources, including routes and certificates. +// These additional subscriptions will enable us to update the config snapshot appropriately +// for any route or certificate changes. func (h *handlerAPIGateway) handleGatewayConfigUpdate(ctx context.Context, u UpdateEvent, snap *ConfigSnapshot, correlationID string) error { resp, ok := u.Result.(*structs.ConfigEntryResponse) if !ok { @@ -244,6 +240,12 @@ func (h *handlerAPIGateway) handleGatewayConfigUpdate(ctx context.Context, u Upd } snap.APIGateway.GatewayConfigLoaded = true + + // Watch the corresponding bound-api-gateway's config entry + err := h.subscribeToConfigEntry(ctx, structs.BoundAPIGateway, h.service, h.proxyID.EnterpriseMeta, boundGatewayConfigWatchID) + if err != nil { + return err + } break default: return fmt.Errorf("invalid type for config entry: %T", resp.Entry)