Documentation
¶
Overview ¶
Package clusterdiscovery resolves the trusted entire-core URLs that a given entire-server cluster will accept JWTs from, by hitting the cluster's /.well-known/entire-cluster.json endpoint. Used on the cold-boot path where contexts.json doesn't yet bind a cluster to a context, so we can tell the user *which* core(s) to log into instead of leaving them to guess --base-url.
Index ¶
Constants ¶
const Path = "/.well-known/entire-cluster.json"
Path mirrors server/cluster_discovery.go: the cluster advertises which entire-core URLs it accepts as JWT issuers.
Variables ¶
var ( // ErrUnreachable wraps any transport-level failure dialing the // cluster (DNS, connection refused, TLS handshake, timeout). The // host might be a typo or a real-but-down cluster — the client // can't tell, and operators get the same nudge for both. ErrUnreachable = errors.New("cluster unreachable") // ErrNoIssuers means the cluster responded HTTP 503 — up but with // an empty trusted-issuers configuration. Operator misconfig, // not a client problem. ErrNoIssuers = errors.New("cluster does not advertise any trusted login servers") // ErrNoCoreURLs means the cluster responded HTTP 200 but the JSON // carried an empty (or absent) core_urls list. Distinct from // ErrNoIssuers because the operator fix is different — the // response shape is wrong, rather than the 503 surface being // served. ErrNoCoreURLs = errors.New("cluster advertises no trusted core URLs") )
Sentinel errors returned by Discover so callers can branch on the failure mode (and surface different operator messages) without stringly-typing the diagnosis.
Functions ¶
func RenderLoginHint ¶
RenderLoginHint formats a fatal-ready message describing which entire-core URLs an operator can log into to gain credentials for clusterHost. The output is stable (one indented URL per line) so callers can pattern-match in tests.
func ResolveContextForCluster ¶
func ResolveContextForCluster(ctx context.Context, configDir, cacheDir, clusterHost string, httpClient *http.Client, debugf DebugFunc) (*contexts.Context, error)
ResolveContextForCluster picks the local login context to authenticate git operations against clusterHost.
It separates two concerns that used to be conflated in a single cluster→context binding:
Which control plane(s) front the cluster — an objective infra fact. Discovered from the cluster's /.well-known/entire-cluster.json and cached in cluster_cores.json (see discovery.ClusterCoresCache) with a long TTL, since a cluster's home core is near-static. On a cache miss or expiry we re-fetch; if the re-fetch fails we fall back to the stale cached cores rather than break the op.
Which of the user's accounts to use — recomputed every call from the live contexts, never persisted. So a user with several accounts is never silently pinned to one identity.
Account selection (selectContext):
- If the active context (current_context) is issued by one of the cluster's cores, use it. This is the explicit lever: `entire auth use <name>` chooses the identity for every cluster that context's core fronts.
- Otherwise gather every local context eligible for the cluster (its CoreURL is among the advertised cores): - exactly one → use it (the common single-account case); - none → error with the login hint listing the cluster's cores; - more than one → error asking the user to pick with `entire auth use`, rather than silently guessing an account.
We never fall back to an active context whose core does NOT front the cluster: the cluster would reject the exchanged token as "unknown cluster_host", and silently authenticating a staging identity against a prod cluster (or vice versa) is exactly the confusion the /.well-known lookup exists to prevent.
debugf is optional; nil suppresses debug output.
Types ¶
type DebugFunc ¶
DebugFunc is the shape of the optional debug-log callback callers pass in. It mirrors fmt.Printf-style formatting so each caller can plug in its own env-var-gated logger (e.g. the [git-remote-entire] / [entiredb] prefixed debugfs gated by ENTIRE_DEBUG). Pass nil to suppress debug output.
type Response ¶
type Response struct {
CoreURLs []string `json:"core_urls"`
}
Response is the parsed shape of /.well-known/entire-cluster.json. New fields may be added by the server; unknown ones are ignored.
func Discover ¶
func Discover(ctx context.Context, clusterHost string, c *http.Client, debugf DebugFunc) (*Response, error)
Discover fetches and parses the cluster's /.well-known/entire-cluster.json. On success returns the parsed body with a non-empty CoreURLs list. On failure returns one of the sentinel errors above (wrapped with context) or a wrapped decode error for malformed JSON. Network failures are wrapped under ErrUnreachable so the caller can render the "looks unreachable" nudge without string-matching.
debugf is optional; nil suppresses debug output.