upstream

package
v1.0.219 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package upstream implements parent-proxy chaining with failover and circuit-breaker protection (ADR-0002 extraction; engine was upstream.go in package main).

Culvert can route traffic through one or more parent HTTP proxies with automatic failover. When all upstreams are down the proxy falls back to direct connections. The package owns the pool state machine (round-robin selection, health flags, per-proxy circuit breakers) and the health-check loop; package main keeps the singleton, the transport wiring (applyUpstreamProxy), and persistence via admin_settings.

Configuration (config.yaml):

upstream:
  proxies:
    - url: "http://parent1.corp.com:3128"
    - url: "http://parent2.corp.com:3128"
  health_interval: "30s"
  circuit_breaker:
    threshold: 5      # failures before opening circuit
    timeout: "60s"    # how long circuit stays open before half-open probe

Index

Constants

View Source
const (
	CredentialNone       = "none"       // no credential material
	CredentialConfigured = "configured" // sealed material, unwrappable, authority matches
	CredentialUnusable   = "unusable"   // ciphertext present, node-local key cannot unwrap it
	CredentialMismatch   = "mismatch"   // credential authority ≠ entry authority
	// CredentialRequiresReplacement (2F-D, C12) is the DISTINCT durable state
	// of an entry whose credential was OMITTED by a sanitized artifact (a
	// backup archive or an export) and has not been set again on this node:
	// no material exists (unlike unusable/mismatch) but the entry is known
	// to need one, so it is ineligible and never sent unauthenticated. Only
	// an explicit T2 replace or T3 clear resolves it.
	CredentialRequiresReplacement = "requiresReplacement"
)

Derived credential states (C4).

View Source
const (
	ProbeUnprobed  = "unprobed"
	ProbeHealthy   = "healthy"
	ProbeUnhealthy = "unhealthy"
)

Probe statuses.

View Source
const (
	ReasonNone            = "none"
	ReasonConnectFailed   = "connect_failed"
	ReasonTimeout         = "timeout"
	ReasonProxyAuthFailed = "proxy_auth_failed"
	ReasonProbeHTTPError  = "probe_http_error"
)

Probe reasons.

View Source
const (
	ProbePeriodic = "periodic"
	ProbeManual   = "manual"
)

Probe sources.

View Source
const (
	ModeNoPool           = "no_pool"
	ModeChained          = "chained"
	ModeNoEligibleParent = "no_eligible_parent"
	ModeDirectFallback   = "direct_fallback"
)

Effective modes (C11).

View Source
const (
	ManualProbeInFlight    = "probe_in_flight"
	ManualProbeRateLimited = "probe_rate_limited"
)

Manual-probe refusal codes (bounded; surfaced as the 429 body's code).

View Source
const DocumentSchema = 1

DocumentSchema is the current v2 document schema.

View Source
const KeyFileName = ".upstream_cred_key"

KeyFileName is the node-local credential key file, beside admin_settings.

View Source
const ManualProbeWindow = 10 * time.Second

ManualProbeWindow is the minimum spacing between two ACCEPTED manual probe runs (a repeat inside it is refused with 429).

View Source
const ProbeTimeout = probeTimeout

ProbeTimeout is the per-entry probe bound, exported so the admin frontend's manual-probe deadline (frontend/src/api/upstream.ts PROBE_PER_ENTRY_MS) can be pinned to it in lockstep; the engine itself reads probeTimeout.

Variables

View Source
var ErrCredentialMismatch = errors.New("upstream credential: bound to a different entry or authority")

ErrCredentialMismatch is the bounded reason a sealed credential does not belong to the (entry, authority) it is attached to.

View Source
var ErrKeyMissing = errors.New("upstream credential key: not found")

ErrKeyMissing reports that no key file exists.

View Source
var FallbackAlertHook func(detail string)

FallbackAlertHook is a TEST-ONLY seam: when non-nil it receives the direct-fallback transition instead of the asynchronous production alert.

View Source
var ProbeTransport func(authority *url.URL) http.RoundTripper

ProbeTransport is a TEST-ONLY seam: when non-nil it supplies the round-tripper the health probe uses for a given parent (identified by its CREDENTIAL-FREE authority URL — the seam never sees a password), so a test can inject a deterministic probe outcome without a network. Production leaves it nil.

Functions

func ClassifyProbe added in v1.0.218

func ClassifyProbe(resp *http.Response, err error) (status, reason string)

ClassifyProbe maps a probe outcome to (status, reason). It is the ONE classifier: dial/TLS error → connect_failed, deadline → timeout, HTTP 407 → proxy_auth_failed, 2xx/3xx → healthy, any other status → probe_http_error.

func FormatSummary

func FormatSummary(entries []Entry) string

FormatSummary returns a log-friendly summary like "2 proxies (parent1:3128, parent2:3128)".

func IsULID added in v1.0.218

func IsULID(id string) bool

IsULID reports whether id parses as a ULID (managed identity).

func NewManagedID added in v1.0.218

func NewManagedID() string

NewManagedID mints a server-generated ULID (collision-checked by the caller against every managed and YAML id).

func RunHealthCheckLoop

func RunHealthCheckLoop(ctx context.Context, pool *Pool, interval time.Duration)

RunHealthCheckLoop runs pool.HealthCheck at the given interval until ctx is cancelled, stopping the underlying ticker on exit. Returns immediately for a nil pool or a non-positive interval. P1.3 / S4.UpstreamHealth.

func ValidateEffective added in v1.0.218

func ValidateEffective(yaml, managed []ManagedEntry) error

ValidateEffective checks the complete effective pool (YAML-owned + managed): every entry normalizes, identities are unique across both sets, and the canonical authorities are unique across YAML/YAML, managed/managed and YAML/managed. Errors are typed so callers report bounded reasons only.

Types

type Attribution added in v1.0.156

type Attribution struct {
	// contains filtered or unexported fields
}

Attribution records which pool proxy the transport selected for one request. Create with WithAttribution; ProxyFunc fills it during RoundTrip.

func WithAttribution added in v1.0.156

func WithAttribution(ctx context.Context) (context.Context, *Attribution)

WithAttribution returns a child context carrying a fresh attribution slot, plus the slot itself.

func (*Attribution) Record added in v1.0.156

func (a *Attribution) Record(err error)

Record feeds a completed request's outcome into the selected proxy's circuit breaker. Nil-safe on both the receiver and the slot's proxy.

A context.Canceled error is deliberately NOT charged to the proxy (our client went away). Timeouts DO count. The error is never rendered — only its bounded reason class (a transport error can embed the proxy URL).

type CircuitBreaker

type CircuitBreaker struct {
	// contains filtered or unexported fields
}

CircuitBreaker tracks consecutive failures for an upstream proxy.

func (*CircuitBreaker) Allow

func (cb *CircuitBreaker) Allow() bool

Allow returns true if the circuit permits a request.

func (*CircuitBreaker) Failures added in v1.0.48

func (cb *CircuitBreaker) Failures() int64

Failures returns the current consecutive-failure count. Exported for admin API / diagnostics surfacing; not used on the request path.

func (*CircuitBreaker) OpenedAt added in v1.0.48

func (cb *CircuitBreaker) OpenedAt() time.Time

OpenedAt returns when the circuit last tripped open (zero Time if it has never opened, or has since been reset by RecordSuccess). Exported for admin API / diagnostics surfacing; not used on the request path.

func (*CircuitBreaker) Params

func (cb *CircuitBreaker) Params() (threshold int, timeout time.Duration)

Params returns the breaker's configured threshold and timeout. Exported for the main-side persistence-contract tests (SetProxies must inherit Configure's params) and for diagnostics; not used on the request path.

func (*CircuitBreaker) RecordFailure

func (cb *CircuitBreaker) RecordFailure() bool

RecordFailure increments the failure count and opens the circuit if the threshold is reached. It returns true exactly when this call transitioned the circuit into the open state (closed/half-open → open), so callers can log/alert once per trip instead of once per failure. Failures recorded while already open refresh openedAt (extending the open window) and return false.

func (*CircuitBreaker) RecordSuccess

func (cb *CircuitBreaker) RecordSuccess()

RecordSuccess resets the failure count and closes the circuit.

func (*CircuitBreaker) State

func (cb *CircuitBreaker) State() string

State returns the current circuit state name.

type Config

type Config struct {
	Proxies        []Entry `yaml:"proxies" json:"proxies"`
	HealthInterval string  `yaml:"health_interval" json:"healthInterval"` // Go duration
	CircuitBreaker struct {
		Threshold int    `yaml:"threshold" json:"threshold"` // failures before open
		Timeout   string `yaml:"timeout" json:"timeout"`     // Go duration
	} `yaml:"circuit_breaker" json:"circuitBreaker"`
}

Config is the "upstream" section of config.yaml.

type Document added in v1.0.218

type Document struct {
	Schema   int            `json:"schema"`
	Revision int64          `json:"revision"`
	Entries  []ManagedEntry `json:"entries"`
}

Document is the durable v2 representation of the MANAGED entries (upstream_proxies_v2). YAML-owned entries are not part of it.

func (Document) Clone added in v1.0.218

func (d Document) Clone() Document

Clone deep-copies the document.

type DuplicateAuthorityError added in v1.0.218

type DuplicateAuthorityError struct{ Count int }

DuplicateAuthorityError reports duplicate canonical authorities in the complete effective pool. It carries a COUNT only (never an authority, username or credential).

func (*DuplicateAuthorityError) Error added in v1.0.218

func (e *DuplicateAuthorityError) Error() string

type Effective added in v1.0.218

type Effective struct {
	Mode          string `json:"mode"`
	Entries       int    `json:"entries"`
	Eligible      int    `json:"eligible"`
	FallbackTotal int64  `json:"fallbackTotal"`
	// Since is the RFC3339 instant the current mode was first observed.
	Since string `json:"since"`
}

Effective is the backend-derived data-plane truth.

type Entry

type Entry struct {
	URL string `yaml:"url" json:"url"`
}

Entry is one parent proxy from config.yaml (credential-free URL).

type Health added in v1.0.218

type Health struct {
	Status      string `json:"status"`
	Reason      string `json:"reason"`
	LastProbeAt string `json:"lastProbeAt,omitempty"`
	Source      string `json:"source,omitempty"`
}

Health is the contracted per-entry health shape on the read model.

func HealthOf added in v1.0.218

func HealthOf(st ProbeState) Health

HealthOf projects a probe state onto the contracted health shape.

type InvalidEntryError added in v1.0.218

type InvalidEntryError struct {
	Index  int
	ID     string
	Reason string
}

InvalidEntryError names the offending entry by index/id, never by URL.

func (*InvalidEntryError) Error added in v1.0.218

func (e *InvalidEntryError) Error() string

type Keyring added in v1.0.218

type Keyring struct {
	// contains filtered or unexported fields
}

Keyring holds the loaded node-local key.

func OpenKey added in v1.0.218

func OpenKey(dir string, create bool) (*Keyring, error)

OpenKey loads the key from dir. create=false is the READ path: a missing key is ErrKeyMissing and nothing is written. create=true mints a fresh key ONLY when none exists (the caller has proven no ciphertext exists).

func (*Keyring) KeyID added in v1.0.218

func (k *Keyring) KeyID() string

KeyID is the public identifier of the loaded key (first 16 hex of its SHA-256), recorded on every sealed credential.

func (*Keyring) Seal added in v1.0.218

func (k *Keyring) Seal(plaintext, entryID, authorityHash, setAt, setBy string) (*Sealed, error)

Seal encrypts plaintext for exactly one (entryID, authorityHash) pair: both are AEAD additional data AND recorded on the Sealed record, so the ciphertext can never be re-attached to another entry or authority.

func (*Keyring) Unseal added in v1.0.218

func (k *Keyring) Unseal(s *Sealed, entryID, authorityHash string) (string, error)

Unseal decrypts a sealed credential for exactly the given entry ID and authority hash. Any failure is reported as a bounded error (never the ciphertext).

type ManagedEntry added in v1.0.218

type ManagedEntry struct {
	ID         string  `json:"id"`
	Scheme     string  `json:"scheme"`
	Host       string  `json:"host"`
	Port       int     `json:"port"`
	Username   string  `json:"username,omitempty"`
	Revision   int64   `json:"revision"`
	Source     Source  `json:"source"`
	Credential *Sealed `json:"credential,omitempty"`
	// RequiresReplacement is the durable marker behind the
	// CredentialRequiresReplacement state (2F-D, C12): set by the backup
	// sanitizer (a restored entry that used to hold a credential) and by an
	// import whose export declared a credential that could not be
	// inherited; meaningful only while Credential is nil; cleared by a T2
	// replace or a T3 clear. Ignored by the frozen predecessor (lenient
	// decoder) and never carried by the credential-free legacy list.
	RequiresReplacement bool   `json:"requiresReplacement,omitempty"`
	CreatedAt           string `json:"createdAt,omitempty"`
	UpdatedAt           string `json:"updatedAt,omitempty"`
	// contains filtered or unexported fields
}

ManagedEntry is one parent proxy (managed or YAML-owned).

func YAMLEntries added in v1.0.218

func YAMLEntries(entries []Entry) ([]ManagedEntry, error)

YAMLEntries converts YAML-seeded legacy URLs into read-only YAML-owned entries. An inline password in a YAML URL is RETAINED in memory only (yamlSecret — never persisted, returned or audited); an unparseable URL is an InvalidEntryError.

func (*ManagedEntry) Authority added in v1.0.218

func (e *ManagedEntry) Authority() string

Authority is the entry's canonical, credential-free authority.

func (*ManagedEntry) AuthorityHash added in v1.0.218

func (e *ManagedEntry) AuthorityHash() string

AuthorityHash is the entry's canonical authority hash.

func (*ManagedEntry) DisplayURL added in v1.0.218

func (e *ManagedEntry) DisplayURL() string

DisplayURL is the API/legacy-GET form: `scheme://host:port` with NO userinfo at all (the username is a separate field).

func (*ManagedEntry) HasInlineSecret added in v1.0.218

func (e *ManagedEntry) HasInlineSecret() bool

HasInlineSecret reports whether a YAML entry carries an in-memory inline credential (never the secret itself).

func (*ManagedEntry) LegacyURL added in v1.0.218

func (e *ManagedEntry) LegacyURL() string

LegacyURL is the credential-free `scheme://[username@]host:port` form persisted in the downgrade-compatible legacy list (admin_settings upstream_proxies) so a pre-v2 binary still sees the username.

func (*ManagedEntry) Spec added in v1.0.218

func (e *ManagedEntry) Spec() Spec

Spec returns the entry's authority inputs.

type Pool

type Pool struct {
	// contains filtered or unexported fields
}

Pool manages the effective set of parent proxies (YAML-owned + managed) with failover. The zero value is a usable empty pool.

func (*Pool) BeginManualProbe added in v1.0.218

func (p *Pool) BeginManualProbe(now time.Time) (ok bool, code string, retryAfter time.Duration)

BeginManualProbe admits or refuses a manual probe run at instant now. When refused, code names the reason and retryAfter bounds the wait. An admitted run MUST be closed with EndManualProbe.

func (*Pool) CBParams

func (p *Pool) CBParams() (threshold int, timeout time.Duration)

CBParams returns the circuit-breaker parameters remembered from the last Configure.

func (*Pool) Configure

func (p *Pool) Configure(entries []Entry, cbThreshold int, cbTimeout time.Duration) error

Configure sets the YAML-owned entries and the circuit-breaker parameters (startup / YAML-reload path). Managed entries are untouched. An invalid or duplicate YAML set fails closed: the previous effective pool stays.

func (*Pool) DirectFallback added in v1.0.156

func (p *Pool) DirectFallback() (active bool, total int64)

DirectFallback reports whether the pool is currently failing open to direct egress and how many requests have done so since startup.

func (*Pool) Document added in v1.0.218

func (p *Pool) Document() Document

Document returns a deep copy of the managed document.

func (*Pool) Effective added in v1.0.218

func (p *Pool) Effective() Effective

Effective computes the backend-derived mode: no_pool (empty), chained (≥1 eligible), no_eligible_parent (0 eligible, no request fell back yet), direct_fallback (0 eligible and a request fell back).

func (*Pool) EffectiveEntries added in v1.0.218

func (p *Pool) EffectiveEntries() []ManagedEntry

EffectiveEntries returns copies of every effective entry (YAML first).

func (*Pool) Enabled

func (p *Pool) Enabled() bool

Enabled returns true if any parent proxy is in the effective pool.

func (*Pool) EndManualProbe added in v1.0.218

func (p *Pool) EndManualProbe()

EndManualProbe releases the single-flight slot of an admitted run.

func (*Pool) Entries

func (p *Pool) Entries() []Entry

Entries returns the effective pool as credential-FREE legacy entries (YAML first). It never carries a password.

func (*Pool) HealthCheck

func (p *Pool) HealthCheck(source string) ProbeSummary

HealthCheck probes every credential-eligible parent with the shared classifier and stores the bounded outcome. Credential-ineligible entries (unusable, mismatch, requiresReplacement) are not probed and keep their state. Every probe is bounded by probeTimeout (5 s per entry). The count-only summary is what a manual run audits.

func (*Pool) Key added in v1.0.218

func (p *Pool) Key() (key *Keyring, reason string)

Key returns the loaded key (nil when unavailable) and the bounded reason.

func (*Pool) LegacyManagedEntries added in v1.0.218

func (p *Pool) LegacyManagedEntries() []Entry

LegacyManagedEntries returns the MANAGED entries as credential-free legacy URLs (the downgrade-compatible representation persisted beside the v2 document).

func (*Pool) List

func (p *Pool) List() []Status

List returns the effective pool statuses for the UI/API. URLs are credential-free authorities.

func (*Pool) ManualProbeInFlight added in v1.0.218

func (p *Pool) ManualProbeInFlight() bool

ManualProbeInFlight reports whether an admitted manual probe run is executing. The read model exposes it so a client whose POST answer outran its deadline can resolve the run against the appliance (no run in flight + the entries' health advanced) instead of sizing a deadline from a possibly stale entry count (PR-C15 R7-B).

func (*Pool) Next

func (p *Pool) Next() *Proxy

Next returns the next ELIGIBLE upstream proxy using round-robin selection (C11). Returns nil if none is eligible (caller falls back to direct).

func (*Pool) ProbeConfig added in v1.0.218

func (p *Pool) ProbeConfig() (configured bool, interval time.Duration)

ProbeConfig reports whether a periodic probe loop is configured and its interval.

func (*Pool) ProxyFunc

func (p *Pool) ProxyFunc() func(*http.Request) (*url.URL, error)

ProxyFunc returns an http.Transport-compatible proxy selector. When an eligible parent exists, it returns that parent's authenticated URL (built here and nowhere else); it returns nil (direct connection) otherwise.

If the request context carries an Attribution slot (WithAttribution), the selected proxy is recorded there so the caller can feed the request's outcome back into that proxy's circuit breaker (CHAOS-11).

func (*Pool) Restore added in v1.0.218

func (p *Pool) Restore(st PoolState)

Restore resets the pool to a captured state and rebuilds the effective pool from it (probe/breaker state starts fresh).

func (*Pool) SetDocument added in v1.0.218

func (p *Pool) SetDocument(doc Document) error

SetDocument publishes a new MANAGED document after validating the whole effective pool (YAML + managed): duplicate authorities or invalid entries are refused with a typed error and the running pool stays unchanged.

func (*Pool) SetKey added in v1.0.218

func (p *Pool) SetKey(k *Keyring, reason string)

SetKey installs the node-local credential key (nil with a bounded reason when it is unavailable) and re-derives every credential state.

func (*Pool) SetProbeInterval added in v1.0.218

func (p *Pool) SetProbeInterval(d time.Duration)

SetProbeInterval records the periodic probe cadence (0 = none) for the read model's top-level probe block.

func (*Pool) SetProxies

func (p *Pool) SetProxies(entries []Entry) error

SetProxies is the LEGACY credential-free replacement of the managed set from URLs (import / compatibility paths). A URL carrying a password is refused; YAML-owned authorities are skipped (YAML owns them).

func (*Pool) Snapshot added in v1.0.218

func (p *Pool) Snapshot() PoolState

Snapshot captures the pool's configuration (not its probe/breaker state).

func (*Pool) YAMLEntries added in v1.0.218

func (p *Pool) YAMLEntries() []ManagedEntry

YAMLEntries returns copies of the YAML-owned entries.

type PoolState added in v1.0.218

type PoolState struct {
	YAML        []ManagedEntry
	Doc         Document
	Key         *Keyring
	KeyErr      string
	CBThreshold int
	CBTimeout   time.Duration
}

PoolState is a full Pool snapshot for test hermeticity (pair Snapshot with Restore around a test that mutates the process-global pool).

type ProbeState added in v1.0.218

type ProbeState struct {
	Status    string `json:"status"`
	Reason    string `json:"reason"`
	CheckedAt string `json:"checkedAt,omitempty"`
	// Source distinguishes a periodic health-loop verdict from an operator
	// triggered manual check (empty while unprobed).
	Source string `json:"source,omitempty"`
}

ProbeState is an entry's last probe outcome.

type ProbeSummary added in v1.0.218

type ProbeSummary struct {
	Probed    int `json:"probed"`
	Healthy   int `json:"healthy"`
	Unhealthy int `json:"unhealthy"`
	Skipped   int `json:"skipped"` // credential-ineligible, not probed
}

ProbeSummary is the bounded, count-only outcome of one HealthCheck run (what the manual-probe audit line carries — never an authority, URL or transport error).

type Proxy

type Proxy struct {
	// Entry, URL and credState are IMMUTABLE after publication: rebuildLocked
	// constructs a fresh Proxy per entry on every publication and never
	// writes a published one, so a selected proxy is a complete, coherent
	// generation for the whole in-flight operation (request, probe,
	// attribution) that holds it.
	Entry ManagedEntry
	// URL is the credential-FREE authority URL (display, legacy status). The
	// authenticated URL is built only by authenticatedURL, per selection.
	URL *url.URL
	// CB is shared by pointer across generations of the same (id, authority)
	// — the breaker carries its own mutex, so continuity is race-safe.
	CB *CircuitBreaker
	// contains filtered or unexported fields
}

Proxy represents one parent proxy in the chain: its entry (never a credential-bearing URL), probe state and circuit breaker.

func (*Proxy) CredentialState added in v1.0.218

func (up *Proxy) CredentialState() string

CredentialState returns the derived credential state.

func (*Proxy) Probe added in v1.0.218

func (up *Proxy) Probe() ProbeState

Probe returns the entry's last probe outcome.

type Sealed added in v1.0.218

type Sealed struct {
	// EntryID is the immutable entry the credential was sealed FOR; it is
	// bound cryptographically (AAD) and structurally, so ciphertext moved
	// onto another entry — even one with the same authority — is mismatch.
	EntryID       string `json:"entryId"`
	AuthorityHash string `json:"authorityHash"`
	Ciphertext    string `json:"ciphertext"` // base64(nonce || AES-GCM(pw, aad=entryID||0||authorityHash))
	KeyID         string `json:"keyId"`
	SetAt         string `json:"setAt"`
	SetBy         string `json:"setBy,omitempty"`
}

Sealed is a credential at rest: ciphertext under the node-local key, bound to the entry id AND the authority it was set for. It never carries plaintext.

type Source added in v1.0.218

type Source string

Source says who owns an entry.

const (
	SourceManaged Source = "managed"
	SourceYAML    Source = "yaml"
)

Entry sources.

type Spec added in v1.0.218

type Spec struct {
	Scheme   string
	Host     string
	Port     int
	Username string
}

Spec is the client-facing shape of an entry's authority inputs.

func Normalize added in v1.0.218

func Normalize(in Spec) (Spec, error)

Normalize validates and canonicalizes an authority specification: scheme lower-cased and restricted to http/https (the approved C4 grammar), host lower-cased, trailing-dot stripped and IDNA-encoded (bracketed IPv6 literals accepted), effective port defaulted per scheme, username free of ':' / '@' / '/'.

func SpecFromURL added in v1.0.218

func SpecFromURL(raw string) (spec Spec, password string, hasPassword bool, err error)

SpecFromURL parses a legacy `scheme://[user[:pass]@]host[:port]` URL into a normalized Spec plus the plaintext password it carried (empty when none). Path, query and fragment are refused unless empty or "/".

func (Spec) Authority added in v1.0.218

func (s Spec) Authority() string

Authority is the canonical `scheme://username@host:port` (username part omitted when empty). It never carries a password.

func (Spec) AuthorityHash added in v1.0.218

func (s Spec) AuthorityHash() string

AuthorityHash is the hex SHA-256 of the canonical authority.

func (Spec) YAMLID added in v1.0.218

func (s Spec) YAMLID() string

YAMLID is the deterministic identity of a YAML-owned entry: "yaml-" + base32(SHA-256(authority)[0:16]) (128 bits).

type Status

type Status struct {
	ID        string `json:"id"`
	URL       string `json:"url"` // legacy field: scheme://host:port, NO userinfo (username is its own field)
	Authority string `json:"authority"`
	Scheme    string `json:"scheme"`
	Host      string `json:"host"`
	Port      int    `json:"port"`
	Username  string `json:"username,omitempty"`
	Source    string `json:"source"`
	Revision  int64  `json:"revision"`
	// CredentialState is derived (C4): none | configured | unusable | mismatch.
	CredentialState string     `json:"credentialState"`
	Probe           ProbeState `json:"probe"`   // compatibility alias of health
	Health          Health     `json:"health"`  // contracted health truth (status/reason/lastProbeAt/source)
	Healthy         bool       `json:"healthy"` // legacy: probe == healthy
	Eligible        bool       `json:"eligible"`
	Circuit         string     `json:"circuit"`
	// Failures is the current consecutive-failure count tracked by the
	// circuit breaker (resets to 0 on RecordSuccess).
	Failures int64 `json:"failures"`
	// OpenedAtMs is when the circuit last tripped open, as Unix
	// milliseconds; 0 when the circuit is closed.
	OpenedAtMs int64 `json:"openedAtMs,omitempty"`
	// RetryAfterMs is the remaining time (ms) until the breaker allows a
	// half-open probe; 0 when the circuit is not open.
	RetryAfterMs int64 `json:"retryAfterMs,omitempty"`
}

Status is returned by the admin API (credential-free).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL