mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-03 03:08:43 -04:00
[management] Return agent-network settings defaults before bootstrap
Settings endpoints elsewhere in the API always answer with a JSON object: account settings rows are created with the account and DNS settings live on it with zero-value defaults. Agent-network settings deviated because the row is created lazily at bootstrap (cluster is a deployment choice and the subdomain must be generated uniquely per cluster), and GetSettings passed the store's not-found straight through to the wire. The manager now synthesises the defaults on read when no row exists yet, without persisting: log collection on with the default retention, and an empty cluster, subdomain and endpoint as the not-bootstrapped signal. The timestamps stay off the wire until a row is written. Bootstrap persists the same defaults, so the pre-bootstrap view and the freshly bootstrapped row agree.
This commit is contained in:
@@ -48,10 +48,9 @@ func (h *handler) updateSettings(w http.ResponseWriter, r *http.Request) {
|
||||
util.WriteJSONObject(r.Context(), w, updated.ToAPIResponse())
|
||||
}
|
||||
|
||||
// getSettings returns the account's agent-network settings. Freshly-onboarded
|
||||
// accounts have no settings row until a provider create (or a settings PUT
|
||||
// with a cluster) bootstraps one; per the OpenAPI contract that reads as a
|
||||
// plain 404.
|
||||
// getSettings returns the account's agent-network settings. Accounts that
|
||||
// haven't been bootstrapped yet read as the defaults with an empty cluster,
|
||||
// subdomain and endpoint; the manager synthesises that view.
|
||||
func (h *handler) getSettings(w http.ResponseWriter, r *http.Request) {
|
||||
userAuth, err := nbcontext.GetUserAuthFromContext(r.Context())
|
||||
if err != nil {
|
||||
|
||||
@@ -11,17 +11,32 @@ import (
|
||||
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||
)
|
||||
|
||||
// TestSettingsHandler_GetUnbootstrappedReturns404 pins the OpenAPI contract:
|
||||
// an account with no settings row answers a plain 404, never 200 with a
|
||||
// null/zero body, so API clients can rely on the status code alone.
|
||||
func TestSettingsHandler_GetUnbootstrappedReturns404(t *testing.T) {
|
||||
// TestSettingsHandler_GetUnbootstrappedReturnsDefaults pins the settings-read
|
||||
// convention shared with the account and DNS settings endpoints: settings
|
||||
// always read as a JSON object. Before bootstrap that object carries the
|
||||
// defaults with an empty cluster/subdomain/endpoint (the "not bootstrapped"
|
||||
// signal) and no timestamps — never a 404 and never the legacy null body.
|
||||
func TestSettingsHandler_GetUnbootstrappedReturnsDefaults(t *testing.T) {
|
||||
f := newAgentNetworkHandlerFixture(t)
|
||||
|
||||
rec := f.do(t, http.MethodGet, "/agent-network/settings", "")
|
||||
assert.Equal(t, http.StatusNotFound, rec.Code,
|
||||
"unbootstrapped account must read as 404: got %d body=%s", rec.Code, rec.Body.String())
|
||||
assert.NotEqual(t, "null", trimSpace(rec.Body.String()),
|
||||
require.Equal(t, http.StatusOK, rec.Code,
|
||||
"unbootstrapped account must read as 200 with defaults: got %d body=%s", rec.Code, rec.Body.String())
|
||||
require.NotEqual(t, "null", trimSpace(rec.Body.String()),
|
||||
"the legacy 200+null shape must not come back")
|
||||
|
||||
var got api.AgentNetworkSettings
|
||||
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &got))
|
||||
assert.Empty(t, got.Cluster, "cluster must be empty until bootstrapped")
|
||||
assert.Empty(t, got.Subdomain, "subdomain must be empty until bootstrapped")
|
||||
assert.Empty(t, got.Endpoint, "endpoint must be empty until bootstrapped, not a bare dot")
|
||||
assert.True(t, got.EnableLogCollection, "defaults must show log collection on, matching bootstrap")
|
||||
assert.False(t, got.EnablePromptCollection, "defaults must show prompt collection off")
|
||||
assert.False(t, got.RedactPii, "defaults must show redaction off")
|
||||
require.NotNil(t, got.AccessLogRetentionDays)
|
||||
assert.Equal(t, 30, *got.AccessLogRetentionDays, "defaults must show the bootstrap retention")
|
||||
assert.Nil(t, got.CreatedAt, "no timestamps before a row exists")
|
||||
assert.Nil(t, got.UpdatedAt, "no timestamps before a row exists")
|
||||
}
|
||||
|
||||
// TestSettingsHandler_PutBootstrapsWithCluster covers the settings-first
|
||||
|
||||
@@ -636,14 +636,23 @@ func (m *managerImpl) validateProviderRefs(ctx context.Context, accountID string
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSettings returns the agent-network settings row for the account.
|
||||
// Returns the underlying status.NotFound when no row has been
|
||||
// bootstrapped yet (i.e. the account has no providers).
|
||||
// GetSettings returns the agent-network settings row for the account. When no
|
||||
// row has been bootstrapped yet, the defaults are returned (without
|
||||
// persisting) with cluster and subdomain empty — settings always read as an
|
||||
// object, like the account and DNS settings endpoints.
|
||||
func (m *managerImpl) GetSettings(ctx context.Context, accountID, userID string) (*types.Settings, error) {
|
||||
if err := m.requirePermission(ctx, accountID, userID, operations.Read); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m.store.GetAgentNetworkSettings(ctx, store.LockingStrengthNone, accountID)
|
||||
settings, err := m.store.GetAgentNetworkSettings(ctx, store.LockingStrengthNone, accountID)
|
||||
switch {
|
||||
case err == nil:
|
||||
return settings, nil
|
||||
case isNotFound(err):
|
||||
return types.DefaultSettings(accountID), nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// bootstrapSettingsIfNeeded creates the per-account agent-network
|
||||
@@ -688,17 +697,11 @@ func (m *managerImpl) bootstrapSettingsIfNeeded(ctx context.Context, accountID,
|
||||
m.labelRngMu.Unlock()
|
||||
|
||||
now := time.Now().UTC()
|
||||
settings := &types.Settings{
|
||||
AccountID: accountID,
|
||||
Cluster: providerCluster,
|
||||
Subdomain: subdomain,
|
||||
// Logs on by default; usage is collected regardless. Retention bounds
|
||||
// how long full log rows are kept.
|
||||
EnableLogCollection: true,
|
||||
AccessLogRetentionDays: types.DefaultAccessLogRetentionDays,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
settings := types.DefaultSettings(accountID)
|
||||
settings.Cluster = providerCluster
|
||||
settings.Subdomain = subdomain
|
||||
settings.CreatedAt = now
|
||||
settings.UpdatedAt = now
|
||||
if err := m.store.SaveAgentNetworkSettings(ctx, settings); err != nil {
|
||||
return nil, fmt.Errorf("save agent network settings: %w", err)
|
||||
}
|
||||
@@ -902,8 +905,8 @@ func (*mockManager) UpdateBudgetRule(_ context.Context, _ string, r *types.Accou
|
||||
|
||||
func (*mockManager) DeleteBudgetRule(_ context.Context, _, _, _ string) error { return nil }
|
||||
|
||||
func (*mockManager) GetSettings(_ context.Context, _, _ string) (*types.Settings, error) {
|
||||
return nil, status.Errorf(status.NotFound, "agent network settings not found")
|
||||
func (*mockManager) GetSettings(_ context.Context, accountID, _ string) (*types.Settings, error) {
|
||||
return types.DefaultSettings(accountID), nil
|
||||
}
|
||||
|
||||
func (*mockManager) UpdateSettings(_ context.Context, _ string, s *types.Settings) (*types.Settings, error) {
|
||||
|
||||
@@ -43,18 +43,34 @@ type Settings struct {
|
||||
// schema cohesive.
|
||||
func (Settings) TableName() string { return "agent_network_settings" }
|
||||
|
||||
// DefaultSettings returns the settings an account observes before its row is
|
||||
// bootstrapped: log collection on with the default retention, everything else
|
||||
// off, and no cluster/subdomain assigned yet. Bootstrap persists exactly these
|
||||
// values plus the assigned cluster and subdomain, so the pre-bootstrap read
|
||||
// and the freshly bootstrapped row agree.
|
||||
func DefaultSettings(accountID string) *Settings {
|
||||
return &Settings{
|
||||
AccountID: accountID,
|
||||
EnableLogCollection: true,
|
||||
AccessLogRetentionDays: DefaultAccessLogRetentionDays,
|
||||
}
|
||||
}
|
||||
|
||||
// Endpoint returns the bare hostname agents reach this account at:
|
||||
// `<subdomain>.<cluster>`.
|
||||
// `<subdomain>.<cluster>`. Empty until both halves are assigned at bootstrap.
|
||||
func (s *Settings) Endpoint() string {
|
||||
if s.Cluster == "" || s.Subdomain == "" {
|
||||
return ""
|
||||
}
|
||||
return s.Subdomain + "." + s.Cluster
|
||||
}
|
||||
|
||||
// ToAPIResponse renders the settings as the API representation.
|
||||
// ToAPIResponse renders the settings as the API representation. The
|
||||
// timestamps are omitted while zero — a default (not yet bootstrapped) view
|
||||
// has no persisted row to date.
|
||||
func (s *Settings) ToAPIResponse() *api.AgentNetworkSettings {
|
||||
created := s.CreatedAt
|
||||
updated := s.UpdatedAt
|
||||
retention := s.AccessLogRetentionDays
|
||||
return &api.AgentNetworkSettings{
|
||||
resp := &api.AgentNetworkSettings{
|
||||
Cluster: s.Cluster,
|
||||
Subdomain: s.Subdomain,
|
||||
Endpoint: s.Endpoint(),
|
||||
@@ -62,9 +78,16 @@ func (s *Settings) ToAPIResponse() *api.AgentNetworkSettings {
|
||||
EnablePromptCollection: s.EnablePromptCollection,
|
||||
RedactPii: s.RedactPii,
|
||||
AccessLogRetentionDays: &retention,
|
||||
CreatedAt: &created,
|
||||
UpdatedAt: &updated,
|
||||
}
|
||||
if !s.CreatedAt.IsZero() {
|
||||
created := s.CreatedAt
|
||||
resp.CreatedAt = &created
|
||||
}
|
||||
if !s.UpdatedAt.IsZero() {
|
||||
updated := s.UpdatedAt
|
||||
resp.UpdatedAt = &updated
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
// FromAPIRequest applies the request onto the receiver. The mutable
|
||||
|
||||
@@ -77,9 +77,9 @@ func (a *AgentNetworkAPI) CreateProvider(ctx context.Context, request api.PostAp
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// UpdateProvider updates an Agent Network provider. Omitted optional fields
|
||||
// (api_key, models, extra_values, toggles, identity headers) keep their
|
||||
// stored values.
|
||||
// UpdateProvider updates an Agent Network provider. The request replaces the
|
||||
// provider's mutable state; only an omitted api_key keeps the stored key
|
||||
// (secrets are never required to round-trip).
|
||||
func (a *AgentNetworkAPI) UpdateProvider(ctx context.Context, providerID string, request api.PutApiAgentNetworkProvidersProviderIdJSONRequestBody) (*api.AgentNetworkProvider, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
@@ -330,13 +330,13 @@ func (a *AgentNetworkAPI) DeleteBudgetRule(ctx context.Context, ruleID string) e
|
||||
}
|
||||
|
||||
// GetSettings gets the account's Agent Network gateway settings (cluster,
|
||||
// subdomain, endpoint, collection toggles). Returns an APIError with
|
||||
// StatusCode 404 (matchable via IsNotFound) when the account has not been
|
||||
// bootstrapped yet — bootstrap via UpdateSettings with a cluster, or by
|
||||
// creating the first provider with bootstrap_cluster set. Management servers
|
||||
// prior to the 404 contract answered 200 with a JSON null body in that case;
|
||||
// that legacy shape is translated to the same 404 APIError here so callers
|
||||
// only ever branch on IsNotFound.
|
||||
// subdomain, endpoint, collection toggles). An account that has not been
|
||||
// bootstrapped yet — via UpdateSettings with a cluster, or by creating the
|
||||
// first provider with bootstrap_cluster set — reads as the defaults with an
|
||||
// empty Cluster, Subdomain and Endpoint. Management servers prior to that
|
||||
// contract answered 200 with a JSON null body instead; that legacy shape is
|
||||
// translated to an APIError matchable via IsNotFound rather than fabricating
|
||||
// defaults the server never stated.
|
||||
func (a *AgentNetworkAPI) GetSettings(ctx context.Context) (*api.AgentNetworkSettings, error) {
|
||||
resp, err := a.c.NewRequest(ctx, "GET", "/api/agent-network/settings", nil, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -404,24 +404,45 @@ func TestAgentNetwork_GetSettings_200(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestAgentNetwork_GetSettings_404(t *testing.T) {
|
||||
// TestAgentNetwork_GetSettings_UnbootstrappedDefaults pins the settings-read
|
||||
// contract: an unbootstrapped account answers 200 with the defaults and empty
|
||||
// cluster/subdomain/endpoint, which the client passes through untouched.
|
||||
func TestAgentNetwork_GetSettings_UnbootstrappedDefaults(t *testing.T) {
|
||||
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/agent-network/settings", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "agent network settings not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
retBytes, _ := json.Marshal(api.AgentNetworkSettings{
|
||||
EnableLogCollection: true,
|
||||
AccessLogRetentionDays: ptr(30),
|
||||
})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.AgentNetwork.GetSettings(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, ret.Endpoint, "empty endpoint is the not-bootstrapped signal")
|
||||
assert.True(t, ret.EnableLogCollection, "defaults must pass through")
|
||||
})
|
||||
}
|
||||
|
||||
func TestAgentNetwork_GetSettings_Err(t *testing.T) {
|
||||
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/agent-network/settings", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "no", Code: 403})
|
||||
w.WriteHeader(403)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
_, err := c.AgentNetwork.GetSettings(context.Background())
|
||||
require.Error(t, err)
|
||||
assert.True(t, rest.IsNotFound(err), "unbootstrapped settings must be matchable via IsNotFound")
|
||||
assert.Equal(t, "no", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
// TestAgentNetwork_GetSettings_LegacyNullBody pins the compatibility shim for
|
||||
// management servers that answered 200 with a JSON null body before the 404
|
||||
// contract: the client must translate that shape into the same IsNotFound
|
||||
// error instead of returning a bogus zero-valued settings object.
|
||||
// management servers that answered 200 with a JSON null body before the
|
||||
// defaults contract: the client translates that shape into an IsNotFound
|
||||
// error instead of returning a bogus zero-valued settings object or
|
||||
// fabricating defaults the server never stated.
|
||||
func TestAgentNetwork_GetSettings_LegacyNullBody(t *testing.T) {
|
||||
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/agent-network/settings", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -5224,7 +5224,7 @@ components:
|
||||
extra_values:
|
||||
type: object
|
||||
description: |
|
||||
Operator-typed values for catalog-declared extra headers (see AgentNetworkProvider.extra_values). When present on a request, the whole map replaces the stored values; when omitted the stored values are left unchanged. Empty strings drop the corresponding key.
|
||||
Operator-typed values for catalog-declared extra headers (see AgentNetworkProvider.extra_values). The request's map replaces the stored values; empty strings drop the corresponding key.
|
||||
additionalProperties:
|
||||
type: string
|
||||
example:
|
||||
@@ -5232,12 +5232,12 @@ components:
|
||||
identity_header_user_id:
|
||||
type: string
|
||||
description: |
|
||||
Wire header name for the caller's display identity. See AgentNetworkProvider.identity_header_user_id. When omitted on a request, the stored value is left unchanged; pass an empty string explicitly to clear it (which disables stamping for this dimension).
|
||||
Wire header name for the caller's display identity. See AgentNetworkProvider.identity_header_user_id. Empty or omitted disables stamping for this dimension.
|
||||
example: "x-bf-dim-netbird_user_id"
|
||||
identity_header_groups:
|
||||
type: string
|
||||
description: |
|
||||
Wire header name for the caller's groups CSV. See AgentNetworkProvider.identity_header_groups. Same omit / empty semantics as `identity_header_user_id`.
|
||||
Wire header name for the caller's groups CSV. See AgentNetworkProvider.identity_header_groups. Same semantics as `identity_header_user_id`.
|
||||
example: "x-bf-dim-netbird_groups"
|
||||
enabled:
|
||||
type: boolean
|
||||
@@ -5245,11 +5245,11 @@ components:
|
||||
example: true
|
||||
skip_tls_verification:
|
||||
type: boolean
|
||||
description: Skip upstream TLS certificate verification when the proxy dials this provider's URL. For self-hosted / internal gateways behind a private or self-signed certificate. Defaults to false. When omitted on update, the stored value is left unchanged.
|
||||
description: Skip upstream TLS certificate verification when the proxy dials this provider's URL. For self-hosted / internal gateways behind a private or self-signed certificate. Defaults to false.
|
||||
example: false
|
||||
metadata_disabled:
|
||||
type: boolean
|
||||
description: Disable identity metadata injection (the caller's user + authorizing group) for this provider. Defaults to false (metadata is injected). When omitted on update, the stored value is left unchanged.
|
||||
description: Disable identity metadata injection (the caller's user + authorizing group) for this provider. Defaults to false (metadata is injected).
|
||||
example: false
|
||||
required:
|
||||
- provider_id
|
||||
@@ -6193,19 +6193,19 @@ components:
|
||||
- cache_cost_usd
|
||||
AgentNetworkSettings:
|
||||
type: object
|
||||
description: Per-account Agent Network gateway settings. One row per account; cluster and subdomain are auto-assigned on first provider create and immutable thereafter.
|
||||
description: Per-account Agent Network gateway settings. One row per account; cluster and subdomain are assigned at bootstrap and immutable thereafter. Before bootstrap the account reads as the default values with empty cluster, subdomain and endpoint.
|
||||
properties:
|
||||
cluster:
|
||||
type: string
|
||||
description: Address of the NetBird proxy cluster fronting this account's agent-network endpoint.
|
||||
description: Address of the NetBird proxy cluster fronting this account's agent-network endpoint. Empty until the account is bootstrapped.
|
||||
example: "eu.proxy.netbird.io"
|
||||
subdomain:
|
||||
type: string
|
||||
description: Auto-generated DNS-safe label that prefixes the cluster to form the agent-network endpoint.
|
||||
description: Auto-generated DNS-safe label that prefixes the cluster to form the agent-network endpoint. Empty until the account is bootstrapped.
|
||||
example: "violet"
|
||||
endpoint:
|
||||
type: string
|
||||
description: Bare hostname agents call for this account, computed as `<subdomain>.<cluster>`.
|
||||
description: Bare hostname agents call for this account, computed as `<subdomain>.<cluster>`. Empty until the account is bootstrapped.
|
||||
example: "violet.eu.proxy.netbird.io"
|
||||
enable_log_collection:
|
||||
type: boolean
|
||||
@@ -6226,13 +6226,13 @@ components:
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Timestamp when the settings row was created.
|
||||
description: Timestamp when the settings row was created. Absent until the account is bootstrapped.
|
||||
readOnly: true
|
||||
example: "2026-04-26T10:30:00Z"
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Timestamp when the settings row was last updated.
|
||||
description: Timestamp when the settings row was last updated. Absent until the account is bootstrapped.
|
||||
readOnly: true
|
||||
example: "2026-04-26T10:30:00Z"
|
||||
required:
|
||||
@@ -6242,8 +6242,6 @@ components:
|
||||
- enable_log_collection
|
||||
- enable_prompt_collection
|
||||
- redact_pii
|
||||
- created_at
|
||||
- updated_at
|
||||
AgentNetworkSettingsRequest:
|
||||
type: object
|
||||
description: Account-level Agent Network settings update. The request replaces every mutable field. `cluster` additionally bootstraps the per-account settings row when the account does not have one yet; the subdomain is always server-assigned.
|
||||
@@ -13696,7 +13694,7 @@ paths:
|
||||
/api/agent-network/settings:
|
||||
get:
|
||||
summary: Retrieve Agent Network settings
|
||||
description: Returns the per-account Agent Network gateway settings (cluster, subdomain, endpoint). Returns 404 when the account has not been bootstrapped yet — settings are bootstrapped on first provider create (`bootstrap_cluster`) or via PUT with `cluster`.
|
||||
description: Returns the per-account Agent Network gateway settings (cluster, subdomain, endpoint). Before the account is bootstrapped — on first provider create (`bootstrap_cluster`) or via PUT with `cluster` — the response carries the default values with empty cluster, subdomain and endpoint.
|
||||
tags: [ Agent Network ]
|
||||
security:
|
||||
- BearerAuth: [ ]
|
||||
@@ -13712,8 +13710,6 @@ paths:
|
||||
"$ref": "#/components/responses/requires_authentication"
|
||||
'403':
|
||||
"$ref": "#/components/responses/forbidden"
|
||||
'404':
|
||||
"$ref": "#/components/responses/not_found"
|
||||
'500':
|
||||
"$ref": "#/components/responses/internal_error"
|
||||
put:
|
||||
|
||||
@@ -2335,16 +2335,16 @@ type AgentNetworkProviderRequest struct {
|
||||
// Enabled Whether the provider is enabled. Defaults to true on create.
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
|
||||
// ExtraValues Operator-typed values for catalog-declared extra headers (see AgentNetworkProvider.extra_values). When present on a request, the whole map replaces the stored values; when omitted the stored values are left unchanged. Empty strings drop the corresponding key.
|
||||
// ExtraValues Operator-typed values for catalog-declared extra headers (see AgentNetworkProvider.extra_values). The request's map replaces the stored values; empty strings drop the corresponding key.
|
||||
ExtraValues *map[string]string `json:"extra_values,omitempty"`
|
||||
|
||||
// IdentityHeaderGroups Wire header name for the caller's groups CSV. See AgentNetworkProvider.identity_header_groups. Same omit / empty semantics as `identity_header_user_id`.
|
||||
// IdentityHeaderGroups Wire header name for the caller's groups CSV. See AgentNetworkProvider.identity_header_groups. Same semantics as `identity_header_user_id`.
|
||||
IdentityHeaderGroups *string `json:"identity_header_groups,omitempty"`
|
||||
|
||||
// IdentityHeaderUserId Wire header name for the caller's display identity. See AgentNetworkProvider.identity_header_user_id. When omitted on a request, the stored value is left unchanged; pass an empty string explicitly to clear it (which disables stamping for this dimension).
|
||||
// IdentityHeaderUserId Wire header name for the caller's display identity. See AgentNetworkProvider.identity_header_user_id. Empty or omitted disables stamping for this dimension.
|
||||
IdentityHeaderUserId *string `json:"identity_header_user_id,omitempty"`
|
||||
|
||||
// MetadataDisabled Disable identity metadata injection (the caller's user + authorizing group) for this provider. Defaults to false (metadata is injected). When omitted on update, the stored value is left unchanged.
|
||||
// MetadataDisabled Disable identity metadata injection (the caller's user + authorizing group) for this provider. Defaults to false (metadata is injected).
|
||||
MetadataDisabled *bool `json:"metadata_disabled,omitempty"`
|
||||
|
||||
// Models Models exposed through this endpoint, with the operator's per-1k input/output prices. Empty means all catalog models are allowed at catalog prices.
|
||||
@@ -2356,22 +2356,22 @@ type AgentNetworkProviderRequest struct {
|
||||
// ProviderId Catalog identifier for the upstream AI provider (e.g. openai_api, anthropic_api, azure_openai_api, bedrock_api, vertex_ai_api, mistral_api, custom).
|
||||
ProviderId string `json:"provider_id"`
|
||||
|
||||
// SkipTlsVerification Skip upstream TLS certificate verification when the proxy dials this provider's URL. For self-hosted / internal gateways behind a private or self-signed certificate. Defaults to false. When omitted on update, the stored value is left unchanged.
|
||||
// SkipTlsVerification Skip upstream TLS certificate verification when the proxy dials this provider's URL. For self-hosted / internal gateways behind a private or self-signed certificate. Defaults to false.
|
||||
SkipTlsVerification *bool `json:"skip_tls_verification,omitempty"`
|
||||
|
||||
// UpstreamUrl Full upstream URL (with scheme) that NetBird forwards traffic to.
|
||||
UpstreamUrl string `json:"upstream_url"`
|
||||
}
|
||||
|
||||
// AgentNetworkSettings Per-account Agent Network gateway settings. One row per account; cluster and subdomain are auto-assigned on first provider create and immutable thereafter.
|
||||
// AgentNetworkSettings Per-account Agent Network gateway settings. One row per account; cluster and subdomain are assigned at bootstrap and immutable thereafter. Before bootstrap the account reads as the default values with empty cluster, subdomain and endpoint.
|
||||
type AgentNetworkSettings struct {
|
||||
// AccessLogRetentionDays Days to retain full access-log rows; older rows are swept. 0 or less means keep indefinitely. Usage records are retained independently.
|
||||
AccessLogRetentionDays *int `json:"access_log_retention_days,omitempty"`
|
||||
|
||||
// Cluster Address of the NetBird proxy cluster fronting this account's agent-network endpoint.
|
||||
// Cluster Address of the NetBird proxy cluster fronting this account's agent-network endpoint. Empty until the account is bootstrapped.
|
||||
Cluster string `json:"cluster"`
|
||||
|
||||
// CreatedAt Timestamp when the settings row was created.
|
||||
// CreatedAt Timestamp when the settings row was created. Absent until the account is bootstrapped.
|
||||
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||
|
||||
// EnableLogCollection Whether per-request access-log entries are collected for this account's agent-network traffic.
|
||||
@@ -2380,16 +2380,16 @@ type AgentNetworkSettings struct {
|
||||
// EnablePromptCollection Master switch for request/response prompt capture. Capture runs only when this is on AND a policy guardrail also enables it.
|
||||
EnablePromptCollection bool `json:"enable_prompt_collection"`
|
||||
|
||||
// Endpoint Bare hostname agents call for this account, computed as `<subdomain>.<cluster>`.
|
||||
// Endpoint Bare hostname agents call for this account, computed as `<subdomain>.<cluster>`. Empty until the account is bootstrapped.
|
||||
Endpoint string `json:"endpoint"`
|
||||
|
||||
// RedactPii Whether captured prompts have PII redacted. Effective redaction is the OR of this and any policy guardrail's redact setting.
|
||||
RedactPii bool `json:"redact_pii"`
|
||||
|
||||
// Subdomain Auto-generated DNS-safe label that prefixes the cluster to form the agent-network endpoint.
|
||||
// Subdomain Auto-generated DNS-safe label that prefixes the cluster to form the agent-network endpoint. Empty until the account is bootstrapped.
|
||||
Subdomain string `json:"subdomain"`
|
||||
|
||||
// UpdatedAt Timestamp when the settings row was last updated.
|
||||
// UpdatedAt Timestamp when the settings row was last updated. Absent until the account is bootstrapped.
|
||||
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user