[management] Fix agent-network settings and provider update contracts

Declarative API clients (the Terraform provider, scripted PUTs) hit three
places where the agent-network API broke its own contract or left users
stuck, forcing client-side workarounds.

The settings GET answered 200 with a JSON null body for unbootstrapped
accounts while the OpenAPI spec documented 404; it now returns the 404.
The settings PUT still replaces every mutable field like the other PUT
endpoints, but a request may now carry the cluster: on an account without
a settings row it bootstraps one (assigning the subdomain), so settings
can be managed before the first provider exists; on a bootstrapped account
a differing cluster is rejected instead of silently ignored.

The provider PUT handler built a fresh row from the request, so the fields
the schema documents as omit-preserves (extra_values, metadata_disabled,
enabled, skip_tls_verification, identity headers) silently reset to zero
when omitted. The handler now overlays the request onto the stored row,
making the documented nil-gating real. Identity headers are always present
in provider responses so an explicitly cleared header round-trips as an
empty string rather than vanishing.
This commit is contained in:
Claude
2026-08-02 03:29:50 +00:00
parent e56eb14c52
commit bf38f20198
13 changed files with 354 additions and 62 deletions

View File

@@ -102,11 +102,20 @@ func TestAgentNetwork_UpdateSettings_PreservesImmutableAndTogglesCollection(t *t
require.NotEmpty(t, before.Subdomain, "subdomain pinned at bootstrap")
assert.False(t, before.EnablePromptCollection, "prompt collection defaults off")
// Attempt to flip toggles AND smuggle a different cluster/subdomain — the
// immutable fields must be ignored.
// A cluster different from the one pinned at bootstrap must be rejected
// outright — never silently swapped or ignored.
_, err = mgr.UpdateSettings(ctx, adminUserID, &agenttypes.Settings{
AccountID: accountID,
Cluster: "attacker.cluster",
EnableLogCollection: true,
})
require.Error(t, err, "UpdateSettings with a mismatched cluster must fail")
// Flipping the toggles works with the pinned cluster echoed back (and
// with it omitted); the subdomain is never taken from the request.
updated, err := mgr.UpdateSettings(ctx, adminUserID, &agenttypes.Settings{
AccountID: accountID,
Cluster: "attacker.cluster",
Cluster: clusterAddr,
Subdomain: "evil",
EnableLogCollection: true,
EnablePromptCollection: true,