catalogue: compose a route's name from a label and its node's domain, and resolve it in-mesh
A public route used to carry its whole hostname as a literal in the module manifest, so running the same catalogue against a different domain meant overriding that literal on every routed module, per node. The mesh was, in effect, holding a map of names to services: the one thing it should never hold, because the subdomain is the operator's choice and the domain is the node's. Compose instead. A route contribution carries a `label` (the subdomain); a node carries its `public_domain` as node-level configuration; the mesh joins `<label>.<public-domain>` and grants exactly that, interpreting neither half. Held as a node property beside the node's other node-level facts (endpoint, site, overlay address), not in a module's settings — the ADR calls it node-level, and the settings table is keyed per module. Additive, so an unmigrated catalogue keeps working: a contribution that still carries a full `name` and no `label` passes through unchanged, and the catalogue can migrate module by module. A labelled contribution on a node with no public domain composes nothing, reading downstream as a route that named no host. And propagate: each granted route name is published into internal resolution mesh-wide, mapped to the node that serves it, alongside the `<node>.internal` names every container already gets. So a container — and an internal ACME validator, which cannot complete a challenge for a name it cannot reach — resolves a routed name to the proxy that serves it. Name-agnostic throughout: the mesh propagates whatever names it was told to serve and knows nothing about what they mean. novox/hq 02-DECISIONS/0056 Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
This commit is contained in:
@@ -560,12 +560,45 @@ func (r Resolution) contributions(settings SettingsBy, grants []Grant,
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s contributing to %s: %w", m.Module, to, err)
|
||||
}
|
||||
composeName(values, r.PublicDomain)
|
||||
out[to] = append(out[to], Contribution{From: m.Module, Values: values})
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// composeName joins a contribution's label with a node's public domain, in place (novox/hq ADR
|
||||
// 0056).
|
||||
//
|
||||
// **The whole of what the mesh does with a route's name: join two given strings.** A contribution
|
||||
// carries a `label` — the subdomain its operator chose — and the node carries its public domain;
|
||||
// the granted name is `<label>.<public-domain>` and the mesh interprets neither half. It runs on
|
||||
// any contribution carrying a label, not only a route's, because the mesh does not know what a
|
||||
// provision means — a name it can compose from parts it was given is the point, whatever the
|
||||
// provision is called.
|
||||
//
|
||||
// **Additive, so an unmigrated catalogue still works.** A contribution that already carries a full
|
||||
// `name` and no `label` is left exactly as it is: the catalogue can migrate module by module while
|
||||
// the running mesh keeps serving the full names it has. And a labelled contribution on a node with
|
||||
// no public domain composes nothing — there is nothing to join it to — which reads downstream as a
|
||||
// route that named no host, the same as it would have before this existed.
|
||||
func composeName(values map[string]any, publicDomain string) {
|
||||
if values == nil || publicDomain == "" {
|
||||
return
|
||||
}
|
||||
if _, already := values["name"]; already {
|
||||
// A full name was given rather than a label. Left as-is: this is the legacy shape, and the
|
||||
// point of the label is to not have to write the full name — a contribution that wrote both
|
||||
// has said what it wants and the mesh does not second-guess it.
|
||||
return
|
||||
}
|
||||
label, ok := values["label"].(string)
|
||||
if !ok || strings.TrimSpace(label) == "" {
|
||||
return
|
||||
}
|
||||
values["name"] = strings.TrimSpace(label) + "." + publicDomain
|
||||
}
|
||||
|
||||
// receivedFile is the file a provider is given its consumers' contributions in.
|
||||
func receivedFile(requirement, path string, given []Contribution) (map[string]any, error) {
|
||||
if given == nil {
|
||||
|
||||
Reference in New Issue
Block a user