feat(agentnetwork): record which proxy serves an account

Adds ServingProxyAddress to the agent-network settings row and makes the
synthesized service advertise it as the proxy that serves the account. Empty
-- the value for every existing row -- means the shared proxy named by
Cluster serves the account, which is the previous behaviour exactly.

This is the only mutable column on the row. Cluster, Subdomain and Zone are
fixed once written, but moving an account onto a dedicated proxy, and moving
it back, is exactly one write here. Because mesh DNS peer selection and the
mapping-delivery filter both join on the advertised address, that single write
is what redirects an account's traffic, with no change to either join.

Only the advertised address follows the new column. The placeholder target's
ID stays pinned to Cluster: it names a target the router rewrites per request
and is not a routing decision.

Nothing in this repository writes the column; it is set by whatever process
assigns dedicated proxies. A store setter is included so that assignment can
be a single scoped update rather than a read-modify-write over the whole row,
which would race with unrelated settings changes.
This commit is contained in:
Brad Ison
2026-08-03 23:43:36 +02:00
parent e493efd532
commit 7f3a29d688
8 changed files with 183 additions and 6 deletions
@@ -385,6 +385,24 @@ func (s *SqlStore) CreateAgentNetworkSettings(ctx context.Context, settings *age
return nil
}
// SetAgentNetworkServingProxyAddress points the account's gateway at a specific
// serving proxy, or clears it (address == "") to return the account to the
// shared proxy. Scoped to the one column on purpose: this runs concurrently
// with unrelated settings updates, and a full-row upsert would clobber them.
func (s *SqlStore) SetAgentNetworkServingProxyAddress(ctx context.Context, accountID, address string) error {
result := s.db.Model(&agentNetworkTypes.Settings{}).
Where("account_id = ?", accountID).
Update("serving_proxy_address", address)
if result.Error != nil {
log.WithContext(ctx).Errorf("failed to set agent network serving proxy address: %v", result.Error)
return status.Errorf(status.Internal, "failed to set agent network serving proxy address")
}
if result.RowsAffected == 0 {
return status.Errorf(status.NotFound, "agent network settings for account %s not found", accountID)
}
return nil
}
// IncrementAgentNetworkConsumption atomically upserts the consumption
// row keyed on (account, dim_kind, dim_id, window_seconds, window_start)
// and adds the supplied deltas. Concurrent calls from multiple proxy