From 76773dfbf54ad7bb8df23ca67f35ae39c3b4ef1b Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 21 Sep 2026 20:36:19 +0200 Subject: [PATCH] Several secrets expand where the consumer is known, not on the first module to mention the provision The lab's two-secrets consumer was given one credential and no file: the expansion ran on the resolver's walk over names, on whichever module mentioned the provision first, and the per-consumer pass copied that. It expands in that pass now, and a test has two consumers of one provision, one keeping one file and one keeping two. --- internal/catalogue/resolve.go | 10 ++++++---- internal/catalogue/several_secrets_test.go | 17 ++++++++++++++--- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/internal/catalogue/resolve.go b/internal/catalogue/resolve.go index 319684b..ded00e0 100644 --- a/internal/catalogue/resolve.go +++ b/internal/catalogue/resolve.go @@ -302,7 +302,7 @@ func Resolve(catalogue map[string]Manifest, assigned []string, node Node, world if at == "" { at = "127.0.0.1" } - needs = eachLocal(needs, catalogue, Needed{ + needs = append(needs, Needed{ Name: want, From: node.Name, At: at, Serves: servedHere(catalogue, chosen, want), For: because[want]}) } else if served := servedHere(catalogue, chosen, want); len(served) > 0 { @@ -323,7 +323,7 @@ func Resolve(catalogue map[string]Manifest, assigned []string, node Node, world if at == "" { at = "127.0.0.1" } - needs = eachLocal(needs, catalogue, Needed{ + needs = append(needs, Needed{ Name: want, From: node.Name, At: at, Serves: served, For: because[want]}) } continue @@ -351,7 +351,7 @@ func Resolve(catalogue map[string]Manifest, assigned []string, node Node, world node.Name, want, p.Node, meshNetwork)) return } - needs = eachLocal(needs, catalogue, Needed{Name: want, From: p.Node, At: p.At, + needs = append(needs, Needed{Name: want, From: p.Node, At: p.At, Serves: p.Serves, For: because[want]}) } switch { @@ -847,7 +847,9 @@ func perConsumer(needs []Needed, order []string, catalogue map[string]Manifest) } copied := n copied.For = m.Module - out = append(out, copied) + // And once per file THIS module keeps the credential in, where it keeps several + // (ADR 0094) — here, where the consumer is finally known, not on the walk above. + out = eachLocal(out, catalogue, copied) wanted = true break } diff --git a/internal/catalogue/several_secrets_test.go b/internal/catalogue/several_secrets_test.go index 71acf22..11872f4 100644 --- a/internal/catalogue/several_secrets_test.go +++ b/internal/catalogue/several_secrets_test.go @@ -68,23 +68,34 @@ func vaultAndCA() map[string]Manifest { vault := Manifest{Module: "mesh-vault", Version: "1", Provides: FromAnywhere("secret"), Grants: map[string]string{"secret": "/var/lib/vault/grants"}, Receives: map[string]string{"secret": "/var/lib/vault/grants/mesh.json"}} - return shelf(vault, ca) + // A second consumer of the same provision that keeps ONE file, mentioned before the one that + // keeps two: the lab found the expansion done on the first module to mention the provision, + // and the second consumer given one credential and no file. + cache := Manifest{Module: "cache", Version: "1", Requires: []string{"secret"}, + Secrets: map[string]string{"secret": "/var/lib/cache/secret"}} + return shelf(vault, cache, ca) } func TestEachLocalNameIsANeedAFileAndAHolderOfItsOwn(t *testing.T) { - got, err := Resolve(vaultAndCA(), []string{"mesh-vault", "ca"}, workstation(), World{}) + got, err := Resolve(vaultAndCA(), []string{"mesh-vault", "cache", "ca"}, workstation(), World{}) if err != nil { t.Fatal(err) } - var locals []string + var locals, cacheLocals []string for _, n := range got.Needs { if n.Name == "secret" && n.For == "ca" { locals = append(locals, n.Local) } + if n.Name == "secret" && n.For == "cache" { + cacheLocals = append(cacheLocals, n.Local) + } } if strings.Join(locals, ",") != "root-key,root-pass" { t.Fatalf("two secrets from one provider are two needs: %v", got.Needs) } + if len(cacheLocals) != 1 || cacheLocals[0] != "" { + t.Fatalf("the one-file consumer keeps one need with no local name: %v", got.Needs) + } for i := range got.Needs { got.Needs[i].Sealed = "sealed-" + got.Needs[i].Local }