diff --git a/internal/catalogue/foundation_manifests_test.go b/internal/catalogue/foundation_manifests_test.go index 5f032c6..7832aef 100644 --- a/internal/catalogue/foundation_manifests_test.go +++ b/internal/catalogue/foundation_manifests_test.go @@ -251,27 +251,13 @@ func TestTheForgesOwnAddressFollowsThePortTheNodeGaveIt(t *testing.T) { } } -// **And the port the forge publishes the long way is the node's too** (novox/hq ADR 0100). -// -// The forge's ssh port is written `2222:22` — the machine's own daemon holds 22, so the module -// takes 2222 and says so in `listens`. A node whose predecessor served git on another number -// cannot be told to leave it there unless the setting may name the machine side of that mapping, -// which is the number the manifest itself uses everywhere else. Composed from the manifest in the -// catalogue beside this checkout, because what the mesh can move is a fact about what the module -// actually writes. -func TestTheForgesSshPortIsGivenByTheNumberTheForgeCallsIt(t *testing.T) { +// gitea's own sshd is unmodified — the module's own internal port is 22, the number in +// `listens`, the same convention every other module in the catalogue uses (its internal port, +// not an invented identity). Composed from the manifest in the catalogue beside this checkout, +// because what the mesh publishes is a fact about what the module actually writes. +func declaredGiteaSsh(t *testing.T, given map[int]int) map[string]any { + t.Helper() forge := catalogueManifest(t, "gitea") - given, err := GivenPorts(forge, []Layer{{From: "anchor", - Values: map[string]any{PortsSetting: map[string]any{"2222": float64(222)}}}}) - if err != nil { - t.Fatalf("the forge's ssh port cannot be given on a node: %v", err) - } - // Under the number the module listens on — 2222, the machine side of its mapping — which is - // the number the plan, the filter, the openings and the consumer all ask for. One entry. - if want := map[int]int{2222: 222}; !reflect.DeepEqual(given, want) { - t.Fatalf("the forge was given %v, and it names its ssh port %v", given, want) - } - resolved, err := forge.Resolve([]Built{{ Name: "runtime", Kind: ArtifactImage, Reference: "registry.example/gitea-runtime@sha256:" + strings.Repeat("a", 64), @@ -286,9 +272,13 @@ func TestTheForgesSshPortIsGivenByTheNumberTheForgeCallsIt(t *testing.T) { {Name: "secret", For: "gitea", From: "anchor", Local: "internal-token", Sealed: "sealed-token"}, {Name: "secret", For: "gitea", From: "anchor", Local: "admin", Sealed: "sealed-admin"}, }} + givenPorts := map[int]int{3000: 3000} + for k, v := range given { + givenPorts[k] = v + } out, err := r.Declaration(Rendering{ Needed: map[string]map[string]string{"gitea": {"broker": "sealed-broker"}}, - Ports: map[string]map[int]int{"gitea": {3000: 3000, 2222: 222}}, + Ports: map[string]map[int]int{"gitea": givenPorts}, Given: map[string]map[int]int{"gitea": given}, }) if err != nil { @@ -298,8 +288,48 @@ func TestTheForgesSshPortIsGivenByTheNumberTheForgeCallsIt(t *testing.T) { if server == nil { t.Fatalf("the forge's own container is not in the declaration: %v", out) } - if published := fmt.Sprint(server["ports"]); !strings.Contains(published, "222:22") || - strings.Contains(published, "2222:22") { + return server +} + +// **The forge publishes ssh at the mesh's own fixed convention by default** (novox/hq ADR 0100). +// +// `222` is the mesh's own public convention for the forge's ssh, written directly in the +// manifest's `ports` — every node the forge has run on used the same number, so it needs no +// per-node setting to reach it. +func TestTheForgesSshPortIsTheMeshsFixedConventionByDefault(t *testing.T) { + forge := catalogueManifest(t, "gitea") + // Nothing was given — no node moved this port — which is the ordinary answer: the mesh only + // reports what a setting moved, and the manifest's own `222:22` needs no move to be reached. + given, err := GivenPorts(forge, nil) + if err != nil { + t.Fatalf("the forge's ssh port cannot be given on a node: %v", err) + } + if len(given) != 0 { + t.Fatalf("nothing moved the forge's ssh port, yet it was given %v", given) + } + server := declaredGiteaSsh(t, given) + if published := fmt.Sprint(server["ports"]); !strings.Contains(published, "222:22") { + t.Fatalf("the forge is published on %v, not its own fixed convention", server["ports"]) + } +} + +// **A node whose predecessor served git on a different number can still be told to leave it +// there.** The setting names the port the module itself listens on — 22, gitea's own sshd, the +// same number `listens` uses — not the mesh's own default machine-side number, so moving it does +// not require guessing what the manifest happens to default to. +func TestANodeMayGiveTheForgesSshPortADifferentNumber(t *testing.T) { + forge := catalogueManifest(t, "gitea") + given, err := GivenPorts(forge, []Layer{{From: "anchor", + Values: map[string]any{PortsSetting: map[string]any{"22": float64(9022)}}}}) + if err != nil { + t.Fatalf("the forge's ssh port cannot be moved on a node: %v", err) + } + if want := map[int]int{22: 9022}; !reflect.DeepEqual(given, want) { + t.Fatalf("the forge was given %v, and the setting named %v", given, want) + } + server := declaredGiteaSsh(t, given) + if published := fmt.Sprint(server["ports"]); !strings.Contains(published, "9022:22") || + strings.Contains(published, "222:22") { t.Fatalf("the forge is published on %v, not the port this node gave it", server["ports"]) } } diff --git a/internal/catalogue/resolver_manifests_test.go b/internal/catalogue/resolver_manifests_test.go index 9debbc1..3336380 100644 --- a/internal/catalogue/resolver_manifests_test.go +++ b/internal/catalogue/resolver_manifests_test.go @@ -101,7 +101,10 @@ func TestTheResolverAndWhatAsksItComposeOnOneMachine(t *testing.T) { t.Fatalf("the resolver's data is the mesh's addresses, and nothing answering them was taken: %v", named(got)) } out, err := got.Declaration(Rendering{ - Names: twoMachines, Suffix: "internal", + // Names is every name the mesh serves; Machines is the subset that is a node (novox/hq + // issue 111) — the resolver's zones read only the second, and in this scenario the two + // happen to be the same map, since nothing routed is part of it. + Names: twoMachines, Machines: twoMachines, Suffix: "internal", Needed: map[string]map[string]string{"dnsmasq": {"broker": "sealed"}}, }) if err != nil {