84 lines
3.2 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|