Take the catalogue's composition rules into the node-engine
ADR 0593 §7: the composer with its refusals leaves mesh-sdk, so mesh-sdk carries no composition rule. The catalogue functions only the node-engine's composition reaches (Resolve, Resolution's Compose, Declaration, DataItems, LeftOut, Rules and the rest, the settings, placeholder and template refusals, the rendering helpers) are copied with their tests into internal/compose/resolution; a method of a mesh-sdk shape becomes a function taking it first. The composition calls its own copies, and the captured catalogue its tests read lives here now, shared by mesh-compose's tests. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
package resolution
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
mcat "git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
)
|
||||
|
||||
// A module that keeps the operator-sealed secrets is handed the export as a file, at 0600, and a
|
||||
// module that does not keep them is handed nothing — the export goes to the vault and nowhere else.
|
||||
func TestOnlyAModuleThatKeepsGetsTheExport(t *testing.T) {
|
||||
vault := mcat.Manifest{Module: "mesh-vault", Version: "1", Provides: mcat.FromAnywhere("secret"),
|
||||
Keeps: "/var/lib/mesh-vault/root"}
|
||||
other := mcat.Manifest{Module: "zsh", Version: "1", Provides: mcat.Offers("shell")}
|
||||
got, err := Resolve(shelf(vault, other), []string{"mesh-vault", "zsh"}, mcat.Node{Name: "anchor", At: "10.0.0.1", Capabilities: map[string]bool{}}, mcat.World{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
kept := &mcat.KeptExport{Export: 1, OperatorKey: "OPERATOR", Fingerprint: "sha256:abcd",
|
||||
Kept: []mcat.Kept{{Node: "anchor", Module: "postgres", Name: "superuser", Origin: "accepted", Sealed: "CIPHERTEXT", Key: "OPERATOR"}}}
|
||||
out, err := Declaration(got, mcat.Rendering{Kept: kept})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var files int
|
||||
for _, r := range out {
|
||||
if r["path"] != "/var/lib/mesh-vault/root/export.json" {
|
||||
continue
|
||||
}
|
||||
files++
|
||||
if r["mode"] != "0600" {
|
||||
t.Errorf("the export is written at mode %v, and it is the mesh's root secrets, sealed or not", r["mode"])
|
||||
}
|
||||
content, _ := r["content"].(string)
|
||||
for _, want := range []string{`"operator-key": "OPERATOR"`, `"sealed": "CIPHERTEXT"`, `"module": "postgres"`} {
|
||||
if !strings.Contains(content, want) {
|
||||
t.Errorf("the export lacks %s:\n%s", want, content)
|
||||
}
|
||||
}
|
||||
if id, _ := r["id"].(string); !strings.Contains(id, "mesh-vault") {
|
||||
t.Errorf("the export's resource id %q does not carry its module", id)
|
||||
}
|
||||
}
|
||||
if files != 1 {
|
||||
t.Fatalf("%d export files; one module keeps them", files)
|
||||
}
|
||||
|
||||
// No operator key yet: the vault is declared without the file, not with an empty one.
|
||||
out, err = Declaration(got, mcat.Rendering{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, r := range out {
|
||||
if r["path"] == "/var/lib/mesh-vault/root/export.json" {
|
||||
t.Fatal("an export was written with nothing to export")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user