From 6203528f3ab1654c8b1547c7901f3eca3eb299f7 Mon Sep 17 00:00:00 2001 From: Brad Ison Date: Mon, 3 Aug 2026 17:38:29 +0200 Subject: [PATCH] feat(agentnetwork): thread the zone config through to the manager Adds AgentNetwork.Zone to the management config and passes it to the agent-network manager, alongside the existing plumbing in the combined binary. Nothing reads it yet -- the allocator that stamps it onto new rows comes next -- so this commit is inert on its own. --- .../modules/agentnetwork/handlers/handlers_test.go | 2 +- management/internals/modules/agentnetwork/manager.go | 6 ++++++ .../modules/agentnetwork/provider_bootstrap_test.go | 2 +- management/internals/server/config/config.go | 9 +++++++++ management/internals/server/modules.go | 1 + .../server/agentnetwork_budgetrule_realstack_test.go | 4 ++-- management/server/agentnetwork_realstack_test.go | 2 +- .../builtin/agentnetwork_chain_integration_test.go | 2 +- .../internal/proxy/agent_network_chain_realstack_test.go | 2 +- 9 files changed, 23 insertions(+), 7 deletions(-) diff --git a/management/internals/modules/agentnetwork/handlers/handlers_test.go b/management/internals/modules/agentnetwork/handlers/handlers_test.go index 27ebea5dd..3a51d9613 100644 --- a/management/internals/modules/agentnetwork/handlers/handlers_test.go +++ b/management/internals/modules/agentnetwork/handlers/handlers_test.go @@ -61,7 +61,7 @@ func newAgentNetworkHandlerFixture(t *testing.T) *agentNetworkHandlerFixture { Return(true, context.Background(), nil). AnyTimes() - manager := agentnetwork.NewManager(st, perms, nil, nil) + manager := agentnetwork.NewManager(st, perms, nil, nil, "") h := &handler{manager: manager} router := mux.NewRouter() diff --git a/management/internals/modules/agentnetwork/manager.go b/management/internals/modules/agentnetwork/manager.go index 2687e4534..852432377 100644 --- a/management/internals/modules/agentnetwork/manager.go +++ b/management/internals/modules/agentnetwork/manager.go @@ -122,6 +122,10 @@ type managerImpl struct { permissionsManager permissions.Manager proxyController proxy.Controller + // zone is the parent DNS zone stamped onto newly allocated settings rows. + // Empty keeps the legacy . endpoint form. + zone string + // reconcileCache holds the last set of synthesised proxy mappings // per account so reconcile can emit precise Create/Update/Delete // updates instead of a full re-push on every mutation. Keyed by @@ -145,12 +149,14 @@ func NewManager( permissionsManager permissions.Manager, accountManager account.Manager, proxyController proxy.Controller, + zone string, ) Manager { return &managerImpl{ store: store, accountManager: accountManager, permissionsManager: permissionsManager, proxyController: proxyController, + zone: zone, reconcileCache: make(map[string]map[string]*proto.ProxyMapping), labelRng: rand.New(rand.NewSource(time.Now().UnixNano())), } diff --git a/management/internals/modules/agentnetwork/provider_bootstrap_test.go b/management/internals/modules/agentnetwork/provider_bootstrap_test.go index 1a2904c51..49c329792 100644 --- a/management/internals/modules/agentnetwork/provider_bootstrap_test.go +++ b/management/internals/modules/agentnetwork/provider_bootstrap_test.go @@ -48,7 +48,7 @@ func newBootstrapFixture(t *testing.T) *bootstrapFixture { accounts.EXPECT().BufferUpdateAccountPeers(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() return &bootstrapFixture{ - manager: NewManager(st, perms, accounts, nil), + manager: NewManager(st, perms, accounts, nil, ""), store: st, perms: perms, } diff --git a/management/internals/server/config/config.go b/management/internals/server/config/config.go index dc60ed822..b893bcf6a 100644 --- a/management/internals/server/config/config.go +++ b/management/internals/server/config/config.go @@ -67,6 +67,15 @@ type Config struct { HighestSupportedSyncMessageVersion *int PerAccountHighestSupportedSyncMessageVersion map[string]int + + // AgentNetworkZone is the parent DNS zone that Agent Network gateway + // endpoints are allocated under, producing .. + // + // Empty (the default) preserves the legacy behaviour of deriving the + // endpoint from the serving cluster, so self-hosted deployments are + // unaffected. It is captured onto each settings row when that row is + // created; changing it later does not move existing tenants. + AgentNetworkZone string } // GetAuthAudiences returns the audience from the http config and device authorization flow config diff --git a/management/internals/server/modules.go b/management/internals/server/modules.go index 6b1365f3b..08490e47a 100644 --- a/management/internals/server/modules.go +++ b/management/internals/server/modules.go @@ -202,6 +202,7 @@ func (s *BaseServer) AgentNetworkManager() agentnetwork.Manager { s.PermissionsManager(), s.AccountManager(), s.ServiceProxyController(), + s.Config.AgentNetworkZone, ) // Sweep expired agent-network access logs per account retention, // reusing the reverse-proxy cleanup interval config. diff --git a/management/server/agentnetwork_budgetrule_realstack_test.go b/management/server/agentnetwork_budgetrule_realstack_test.go index d17f2e26a..4bf7a3d30 100644 --- a/management/server/agentnetwork_budgetrule_realstack_test.go +++ b/management/server/agentnetwork_budgetrule_realstack_test.go @@ -30,7 +30,7 @@ func TestAgentNetwork_BudgetRuleCRUD_RealManager(t *testing.T) { account := newAccountWithId(ctx, accountID, adminUserID, "agent-net.test", "", "", false) require.NoError(t, am.Store.SaveAccount(ctx, account), "SaveAccount must succeed") - mgr := agentnetwork.NewManager(am.Store, permissions.NewManager(am.Store), am, nil) + mgr := agentnetwork.NewManager(am.Store, permissions.NewManager(am.Store), am, nil, "") created, err := mgr.CreateBudgetRule(ctx, adminUserID, &agenttypes.AccountBudgetRule{ AccountID: accountID, @@ -82,7 +82,7 @@ func TestAgentNetwork_UpdateSettings_PreservesImmutableAndTogglesCollection(t *t account := newAccountWithId(ctx, accountID, adminUserID, "agent-net.test", "", "", false) require.NoError(t, am.Store.SaveAccount(ctx, account), "SaveAccount must succeed") - mgr := agentnetwork.NewManager(am.Store, permissions.NewManager(am.Store), am, nil) + mgr := agentnetwork.NewManager(am.Store, permissions.NewManager(am.Store), am, nil, "") // Creating a provider bootstraps the settings row (cluster + subdomain). _, err = mgr.CreateProvider(ctx, adminUserID, &agenttypes.Provider{ diff --git a/management/server/agentnetwork_realstack_test.go b/management/server/agentnetwork_realstack_test.go index e7855c575..5e210ea84 100644 --- a/management/server/agentnetwork_realstack_test.go +++ b/management/server/agentnetwork_realstack_test.go @@ -90,7 +90,7 @@ func TestAgentNetwork_ProviderCRUD_FansOutToProxyAndClientPeers(t *testing.T) { // Real agentnetwork manager wired to the real account manager. proxyController // is nil (no gRPC cluster fan-out here) — the reconcile still fires // UpdateAccountPeers, which is the path under test. - agentMgr := agentnetwork.NewManager(am.Store, permissions.NewManager(am.Store), am, nil) + agentMgr := agentnetwork.NewManager(am.Store, permissions.NewManager(am.Store), am, nil, "") provider, err := agentMgr.CreateProvider(ctx, adminUserID, &agenttypes.Provider{ AccountID: accountID, diff --git a/proxy/internal/middleware/builtin/agentnetwork_chain_integration_test.go b/proxy/internal/middleware/builtin/agentnetwork_chain_integration_test.go index 96777025c..f1bda33b1 100644 --- a/proxy/internal/middleware/builtin/agentnetwork_chain_integration_test.go +++ b/proxy/internal/middleware/builtin/agentnetwork_chain_integration_test.go @@ -53,7 +53,7 @@ func newChainIntegration(t *testing.T) *chainIntegrationFixture { require.NoError(t, err) t.Cleanup(cleanUp) - manager := agentnetwork.NewManager(st, nil, nil, nil) + manager := agentnetwork.NewManager(st, nil, nil, nil, "") server := &mgmtgrpc.ProxyServiceServer{} server.SetAgentNetworkLimitsService(manager) diff --git a/proxy/internal/proxy/agent_network_chain_realstack_test.go b/proxy/internal/proxy/agent_network_chain_realstack_test.go index 924d37ace..d22a888fe 100644 --- a/proxy/internal/proxy/agent_network_chain_realstack_test.go +++ b/proxy/internal/proxy/agent_network_chain_realstack_test.go @@ -102,7 +102,7 @@ func TestReverseProxy_AgentNetworkRequest_FullChain(t *testing.T) { require.NoError(t, err, "real sqlite test store must come up") t.Cleanup(cleanup) - anMgr := agentnetwork.NewManager(st, nil, nil, nil) + anMgr := agentnetwork.NewManager(st, nil, nil, nil, "") server := &mgmtgrpc.ProxyServiceServer{} server.SetAgentNetworkLimitsService(anMgr)