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.
This commit is contained in:
Brad Ison
2026-08-03 17:38:29 +02:00
parent fabfacee55
commit 6203528f3a
9 changed files with 23 additions and 7 deletions

View File

@@ -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()

View File

@@ -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 <subdomain>.<cluster> 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())),
}

View File

@@ -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,
}

View File

@@ -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 <subdomain>.<zone>.
//
// 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

View File

@@ -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.

View File

@@ -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{

View File

@@ -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,

View File

@@ -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)

View File

@@ -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)