Read the foundation's ports from each node's settings, wherever a port is used (hq ADR 0100)
This commit is contained in:
@@ -233,12 +233,19 @@ func theRestOfTheMesh(ctx context.Context, inv *inventory.Inventory,
|
||||
if err != nil {
|
||||
return catalogue.World{}, err
|
||||
}
|
||||
layers, err := inv.SettingsFor(ctx, o.node.Name, m.Module)
|
||||
if err != nil {
|
||||
return catalogue.World{}, err
|
||||
}
|
||||
// A port that node was given is where its consumers reach it (novox/hq ADR
|
||||
// 0100). Unreadable given ports are that node's refusal to report, not this one's.
|
||||
if given, err := catalogue.GivenPorts(m, layers); err == nil {
|
||||
for wanted, at := range given {
|
||||
assigned[wanted] = at
|
||||
}
|
||||
}
|
||||
serves := catalogue.ServedOn(m, name, assigned)
|
||||
if len(serves) > 0 {
|
||||
layers, err := inv.SettingsFor(ctx, o.node.Name, m.Module)
|
||||
if err != nil {
|
||||
return catalogue.World{}, err
|
||||
}
|
||||
serves, err = catalogue.Settle(serves, layers)
|
||||
if err != nil {
|
||||
return catalogue.World{}, err
|
||||
@@ -364,9 +371,30 @@ func renderingFor(ctx context.Context, open *stores, node string,
|
||||
}
|
||||
}
|
||||
|
||||
// The machine ports this node was given for its modules (novox/hq ADR 0100): the foundation's
|
||||
// ports, as genesis chose them. A given port wins over anything assigned and over a manifest's
|
||||
// own long-form mapping.
|
||||
given := map[string]map[int]int{}
|
||||
for _, m := range plan.Modules {
|
||||
g, err := catalogue.GivenPorts(m, settings[m.Module])
|
||||
if err != nil {
|
||||
return catalogue.Rendering{}, inventory.Node{}, err
|
||||
}
|
||||
if g != nil {
|
||||
given[m.Module] = g
|
||||
}
|
||||
}
|
||||
|
||||
ports := map[string]map[int]int{}
|
||||
for _, m := range plan.Modules {
|
||||
for _, l := range m.Listens {
|
||||
if at, isGiven := given[m.Module][l.Port]; isGiven {
|
||||
if ports[m.Module] == nil {
|
||||
ports[m.Module] = map[int]int{}
|
||||
}
|
||||
ports[m.Module][l.Port] = at
|
||||
continue
|
||||
}
|
||||
// **Only a port the module actually publishes is the mesh's to move.** A container's
|
||||
// mapping is the thing that translates; without one the software binds what it binds,
|
||||
// and an assignment would not move the service — it would open the wrong number in the
|
||||
@@ -515,6 +543,7 @@ func renderingFor(ctx context.Context, open *stores, node string,
|
||||
Settings: settings, Generators: gens, Grants: grants, Needed: needed, Ports: ports,
|
||||
Certificate: certificate, Authority: authority, Mesh: private, Names: names,
|
||||
Suffix: overlay.Suffix(), Foundation: foundation, Kept: kept, Adopted: record.Adopted,
|
||||
Given: given,
|
||||
}, record, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -168,3 +168,60 @@ func stdoutOf(t *testing.T, run func() error) string {
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// novox/hq ADR 0100: a port a node was given for the store is where its consumers on other
|
||||
// machines are told to reach it, and a port given for the whole mesh is refused.
|
||||
func TestConsumersAreToldTheGivenPort(t *testing.T) {
|
||||
open := aMesh(t)
|
||||
ctx := t.Context()
|
||||
register(t, open, catalogue.Manifest{Module: "store", Version: "1",
|
||||
Provides: []catalogue.Offer{{Name: "database", Scope: catalogue.ScopeMesh}},
|
||||
Listens: []catalogue.Listening{{Port: 5432, From: catalogue.FromMesh}},
|
||||
Guards: []int{5432},
|
||||
Resources: []map[string]any{{"id": "server", "type": "container", "name": "mesh-store",
|
||||
"ports": []any{"5432:5432"},
|
||||
"image": "registry.example/pg@sha256:" + strings.Repeat("b", 64)}}})
|
||||
register(t, open, catalogue.Manifest{Module: "app", Version: "1", Requires: []string{"database"}})
|
||||
if _, err := assign(ctx, open, "anchor", "store"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := assign(ctx, open, "laptop", "app"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := open.inventory.SetSettings(ctx, "anchor", "store",
|
||||
map[string]any{catalogue.PortsSetting: map[string]any{"5432": 5433}}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
plan, _, err := planFor(ctx, open, "laptop")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var told any
|
||||
for _, n := range plan.Needs {
|
||||
if n.Name == "database" {
|
||||
told = n.Serves["port"]
|
||||
}
|
||||
}
|
||||
if told != 5433 {
|
||||
t.Fatalf("the consumer is told the store is on %v", told)
|
||||
}
|
||||
for _, r := range composed(t, open, "anchor").Resources {
|
||||
if r["id"] == "store.server" && !reflect.DeepEqual(r["ports"], []any{"5433:5432"}) {
|
||||
t.Fatalf("the store publishes %v", r["ports"])
|
||||
}
|
||||
}
|
||||
|
||||
if err := open.inventory.SetSettings(ctx, "", "store",
|
||||
map[string]any{catalogue.PortsSetting: map[string]any{"5432": 5434}}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
plan, settings, err := planFor(ctx, open, "anchor")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := declarationFor(ctx, open, "anchor", plan, settings); err == nil ||
|
||||
!strings.Contains(err.Error(), "per node") {
|
||||
t.Fatalf("a port given for the whole mesh was not refused: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user