Files
mesh-controller/cmd/mesh-controller/vault_handed_test.go
T

84 lines
3.2 KiB
Go

package main
import (
"strings"
"testing"
"time"
"github.com/novox/mesh-controller/internal/broker"
"github.com/novox/mesh-controller/internal/catalogue"
"github.com/novox/mesh-controller/internal/inventory"
"github.com/novox/mesh-controller/internal/link"
)
// A machine's send makes and seals none of the secrets of a module handed to the provisioner there (novox/hq ADR
// 0349 §7, §11, design 57 V4, issue 647): its client asks the vault for them. A module not moved, on the same
// machine, has its secret made and sealed as before.
func aClientModule() catalogue.Manifest {
return catalogue.Manifest{Module: "mesh-provisioner-client", Version: "1",
Claims: []catalogue.Claim{{Name: broker.NodeProvisionerSeat, Scope: catalogue.ScopeNode}},
OwnSecrets: catalogue.OwnSecrets{broker.ProvisionerSecret: {Path: "/var/lib/mesh-provisioner-client/broker"}},
Resources: []map[string]any{{"id": "client", "type": "process", "name": "mesh-provisioner-client",
"run": []any{"./mesh-provisioner-client"}, "user": "mesh-provisioner-client"}}}
}
func aBot(module string, moved bool) catalogue.Manifest {
m := catalogue.Manifest{Module: module, Version: "1",
OwnSecrets: catalogue.OwnSecrets{"token": {Path: "/var/lib/" + module + "/token"}},
Resources: []map[string]any{{"id": "conf", "type": "file", "path": "/etc/" + module + "/bot.conf",
"content": "token = ${secret:token}\n"}}}
if moved {
m.Moved = true
m.Handed = &catalogue.Handed{Source: "https://templates.example/" + module + ".tar.gz",
Digest: "sha256:" + strings.Repeat("e", 64),
Templates: map[string]string{"conf": "bot.conf"}}
}
return m
}
func TestTheSendSealsNoSecretOfAModuleHandedThere(t *testing.T) {
open := aMesh(t)
ctx := t.Context()
inv := open.inventory
client := aClientModule()
for _, m := range []catalogue.Manifest{client, aBot("moved-bot", true), aBot("kept-bot", false)} {
register(t, open, m)
if _, err := assign(ctx, open, "laptop", m.Module); err != nil {
t.Fatal(err)
}
}
if err := issueProvisionerClient(ctx, inv, client, "laptop", broker.Broker{Fingerprint: "ab"}, "10.0.0.1:4222"); err != nil {
t.Fatal(err)
}
if _, err := inv.RecordHealth(ctx, inventory.NodeHealth{Node: "laptop", Contract: link.HandedContract,
SaidAt: time.Now()}); err != nil {
t.Fatal(err)
}
sent := sentTo(t, open, "laptop")
var moved, kept map[string]any
for _, r := range sent {
switch r["id"] {
case "moved-bot.needs-token":
moved = r
case "kept-bot.needs-token":
kept = r
}
}
if moved == nil || moved["sealed"] != nil || moved["owner-at-runtime"] != "owned" {
t.Fatalf("the handed module's secret file is sent as %v: placed, with no value", moved)
}
if kept == nil || kept["sealed"] == nil {
t.Fatalf("the module not moved has its secret sent as %v: sealed, as before", kept)
}
if _, held, err := inv.ModuleSecretIfIssued(ctx, "laptop", "moved-bot", "token"); err != nil || held {
t.Fatalf("the send made the handed module's secret in the controller's store (held %v, %v)", held, err)
}
for _, r := range sent {
if r["id"] == "moved-bot.conf" && (r["content"] != nil || r["sealed"] != nil) {
t.Fatalf("the handed module's templated file carries text or a value: %v", r)
}
}
}