From e5243cd7532a971e9beef21f21468ecc614dbd78 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 1 Sep 2026 03:10:43 +0200 Subject: [PATCH] Ask every consumer for usable configuration, not just the one in hand MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The keycloak check was written while keycloak was the module being worked on, which is how a check ends up proving one thing about one file. It now runs over every example that requires something, and asks the two questions that matter for all of them: that no ${bound:...} reached the machine as a value, and that anything named PASSWORD is still a hole only the host can fill. The first is the one worth having. A placeholder written through is read as a value by whatever parses the file — a connection to a host called "${bound:postgres-database:at}" — and the failure names neither the module nor the mesh. Modules whose requirements nothing in the examples answers are logged and passed over, because that is a fact about the example set rather than about them. --- examples/modules/modules_test.go | 129 ++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 43 deletions(-) diff --git a/examples/modules/modules_test.go b/examples/modules/modules_test.go index e91c687..c91bcfa 100644 --- a/examples/modules/modules_test.go +++ b/examples/modules/modules_test.go @@ -360,62 +360,105 @@ func secretsUsedForTest(content string) []string { return used } -// The real manifests, resolved together, produce a connection a program could use. +// Every module that requires something produces configuration a program could use. // // **Parsing is not working, and this file has now learned that twice.** These modules parsed and -// resolved for a day while their credentials went into files nothing could read; they would have -// parsed and resolved just as happily with a connection string that named no user. What has to be -// true is that the bytes reaching the machine are usable, so that is what this asks. -func TestKeycloakGetsAConnectionAProgramCouldUse(t *testing.T) { +// resolved for a day while their credentials went into files nothing could read; they would parse +// and resolve just as happily with a connection string naming no user, or with a placeholder +// written through as a hostname. What has to be true is that the bytes reaching the machine are +// usable, so that is what this asks — of every consumer, not of the one that was being worked on. +func TestEveryConsumerGetsConfigurationAProgramCouldUse(t *testing.T) { + found, err := filepath.Glob("*.json") + if err != nil { + t.Fatal(err) + } shelf := map[string]catalogue.Manifest{} - for _, name := range []string{"postgres.json", "keycloak.json"} { + for _, name := range found { m := read(t, name) shelf[m.Module] = m } - resolved, err := catalogue.Resolve(shelf, []string{"keycloak"}, + + var checked int + for _, m := range shelf { + if len(m.Requires) == 0 { + continue + } + out := declareOnItsOwn(t, shelf, m) + if out == nil { + continue + } + checked++ + for _, r := range out { + content, ok := r["content"].(string) + if !ok { + continue + } + // A placeholder written through is read as a value by whatever parses the file — a + // connection to a host literally called "${bound:postgres-database:at}", failing + // somewhere that names neither the module nor the mesh. + if strings.Contains(content, "${bound:") { + t.Errorf("%s: %v reached the machine with a placeholder in it:\n%s", + m.Module, r["id"], content) + } + // The password is the one that must survive: only the host may fill it, and only on + // the machine. If it is gone, something composed it here. + for _, line := range strings.Split(content, "\n") { + if strings.Contains(line, "PASSWORD") || strings.Contains(line, "PASSWD") { + if !strings.Contains(line, "${secret:") { + t.Errorf("%s: %v carries %q, which is not a hole the host fills", + m.Module, r["id"], line) + } + } + } + } + } + if checked == 0 { + t.Fatal("no example requires anything, so this test proves nothing") + } +} + +// declareOnItsOwn resolves one consumer against a mesh that answers everything it requires, and +// returns what would reach the machine. Nil when its requirements cannot be answered from the +// examples, which is not this test's business to complain about. +func declareOnItsOwn(t *testing.T, shelf map[string]catalogue.Manifest, + m catalogue.Manifest) []map[string]any { + t.Helper() + + // Everything it requires, answered from somewhere else in the mesh, with whatever the + // providing example says it serves. + offered := map[string][]catalogue.Provider{} + for _, want := range m.Requires { + serves := map[string]any{} + for _, other := range shelf { + if s, said := other.Serves[want]; said { + serves = s + } + } + offered[want] = []catalogue.Provider{ + {Node: "anchor", At: "anchor.internal", Serves: serves}} + } + resolved, err := catalogue.Resolve(shelf, []string{m.Module}, catalogue.Node{Name: "workstation", At: "workstation.internal", Capabilities: map[string]bool{"container-runtime": true}}, - catalogue.World{Offered: map[string][]catalogue.Provider{ - "postgres-database": {{Node: "anchor", At: "anchor.internal", - Serves: map[string]any{"port": float64(5432)}}}, - }}) + catalogue.World{Offered: offered}) if err != nil { - t.Fatalf("the real manifests do not resolve: %v", err) + t.Logf("%s does not resolve on its own: %v", m.Module, err) + return nil } for i := range resolved.Needs { resolved.Needs[i].Sealed = "sealed" } - out, err := resolved.Declaration(catalogue.Rendering{ - Needed: map[string]map[string]string{"keycloak": {"admin": "sealed-admin"}}, - }) + own := map[string]map[string]string{} + for name := range m.OwnSecrets { + if own[m.Module] == nil { + own[m.Module] = map[string]string{} + } + own[m.Module][name] = "sealed" + } + out, err := resolved.Declaration(catalogue.Rendering{Needed: own}) if err != nil { - t.Fatalf("the real manifests do not declare: %v", err) - } - - var env string - for _, r := range out { - if r["path"] == "/var/lib/keycloak/database.env" { - env, _ = r["content"].(string) - } - } - if env == "" { - t.Fatal("keycloak was given no database configuration at all") - } - // Every part of a connection, and nothing left unfilled. A leftover ${...} would be read as - // a value by whatever parses this. - for _, wanted := range []string{ - "KC_DB_URL=jdbc:postgresql://anchor.internal:5432/keycloak", - "KC_DB_USERNAME=mesh_workstation_keycloak", - } { - if !strings.Contains(env, wanted) { - t.Errorf("the connection is missing %q:\n%s", wanted, env) - } - } - if strings.Contains(env, "${bound:") { - t.Errorf("a placeholder reached the machine as a value:\n%s", env) - } - // The password is the one hole that stays, because only the host may fill it. - if !strings.Contains(env, "KC_DB_PASSWORD=${secret:postgres-database}") { - t.Errorf("the password is not left for the host to fill:\n%s", env) + t.Errorf("%s resolves and does not declare: %v", m.Module, err) + return nil } + return out }