Review found a chain through the command verb: set the operator's key to one the caller holds, rotate secrets so they are sealed to it too, read the sealed copies, open them. Whoever may call a verb includes agents (hq ADR 0266), so command now runs an allow list of reading forms, and operator, identity, token, broker, api, licence and every secret command but rotate are refused through any verb.
119 lines
5.1 KiB
Go
119 lines
5.1 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/novox/mesh-controller/internal/inventory"
|
|
)
|
|
|
|
// **Every verb that repairs by hand takes a required why** (novox/hq to-be 45 §7): refused before
|
|
// anything is done, through the seat, through `command`, and at a shell where nothing automated runs
|
|
// the verb.
|
|
func TestARepairByHandWithoutAReasonIsRefused(t *testing.T) {
|
|
for _, c := range []struct {
|
|
verb string
|
|
args map[string]any
|
|
}{
|
|
{"push", map[string]any{"node": "anchor"}},
|
|
{"push", map[string]any{}},
|
|
{"plans", map[string]any{"close": "plan-1"}},
|
|
{"plans", map[string]any{"stop": "plan-1"}},
|
|
{"hand-act", map[string]any{"what": "restarted the proxy", "cause": "proxy-stuck"}},
|
|
} {
|
|
argv, err := argvFor(c.verb, c.args)
|
|
if c.verb == "plans" && err == nil {
|
|
// The seat composes the command line; the command refuses it, before opening anything.
|
|
err = plansCommand(context.Background(), argv[1:])
|
|
}
|
|
if err == nil || !strings.Contains(err.Error(), "why") {
|
|
t.Errorf("%s %v was not refused for want of why: %v %v", c.verb, c.args, argv, err)
|
|
}
|
|
}
|
|
for _, args := range [][]string{{"EVENTS", "controller"}} {
|
|
if err := consumerReset(context.Background(), args); err == nil || !strings.Contains(err.Error(), "--why") {
|
|
t.Errorf("consumer-reset without why: %v", err)
|
|
}
|
|
}
|
|
if err := handActCommand(context.Background(), []string{"record", "restarted the proxy", "--cause", "x"}); err == nil ||
|
|
!strings.Contains(err.Error(), "--why") {
|
|
t.Errorf("hand-act record without why: %v", err)
|
|
}
|
|
if err := handActCommand(context.Background(), []string{"record", "restarted the proxy", "--why", "it hung"}); err == nil ||
|
|
!strings.Contains(err.Error(), "--cause") {
|
|
t.Errorf("hand-act record without a cause: %v", err)
|
|
}
|
|
}
|
|
|
|
// With a reason, the seat passes it to the command, and a verb that only reads is not held to one.
|
|
func TestARepairByHandCarriesItsReason(t *testing.T) {
|
|
for _, c := range []struct {
|
|
verb string
|
|
args map[string]any
|
|
want string
|
|
}{
|
|
{"push", map[string]any{"node": "anchor", "why": "stuck", "cause": "sent-not-reported"},
|
|
"push anchor --wait 0 --why stuck --cause sent-not-reported"},
|
|
{"plans", map[string]any{"close": "plan-1", "why": "the report will not come"},
|
|
"plans close plan-1 --why the report will not come"},
|
|
{"plans", map[string]any{"retry": "plan-1"}, "plans retry plan-1"},
|
|
{"hand-act", map[string]any{"what": "restarted", "why": "hung", "cause": "proxy", "condition": "machine.a.silent"},
|
|
"hand-act record restarted --why hung --cause proxy --condition machine.a.silent"},
|
|
{"command", map[string]any{"command": "plans plan-1"}, "plans plan-1"},
|
|
} {
|
|
argv, err := argvFor(c.verb, c.args)
|
|
if err != nil || strings.Join(argv, " ") != c.want {
|
|
t.Errorf("%s %v: %v %v, want %q", c.verb, c.args, argv, err, c.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// The summary of durations says, per kind and subject, what a bound would be set from.
|
|
func TestDurationsAreSummarisedPerSubject(t *testing.T) {
|
|
var ds []inventory.Duration
|
|
for i := 1; i <= 10; i++ {
|
|
ds = append(ds, inventory.Duration{Kind: inventory.DurationApply, Subject: "anchor",
|
|
Took: time.Duration(i) * time.Second})
|
|
}
|
|
ds = append(ds, inventory.Duration{Kind: inventory.DurationHeartbeatGap, Subject: "anchor", Took: time.Minute})
|
|
got := summarise(ds)
|
|
if len(got) != 2 || got[0].Kind != inventory.DurationApply || got[0].Count != 10 ||
|
|
got[0].Max != "10s" || got[0].Median != "5s" || got[0].P90 != "9s" {
|
|
t.Fatalf("%+v", got)
|
|
}
|
|
if !strings.Contains(got[1].Suggests, "3m0s") {
|
|
t.Fatalf("a minute between words suggests %q", got[1].Suggests)
|
|
}
|
|
}
|
|
|
|
// **A drill has its own verb** — `hand-act drill`, the seat's `drill` — and `hand-act record` refuses
|
|
// the cause, so a repair cannot pass for a drill by the word it gives.
|
|
func TestADrillIsRecordedThroughItsOwnVerb(t *testing.T) {
|
|
err := handActCommand(context.Background(), []string{"record", "stopped searxng", "--why", "a test", "--cause", "drill"})
|
|
if err == nil || !strings.Contains(err.Error(), "hand-act drill") {
|
|
t.Errorf("hand-act record --cause drill was not sent to the drill verb: %v", err)
|
|
}
|
|
if err := handActCommand(context.Background(), []string{"drill", "stopped searxng"}); err == nil ||
|
|
!strings.Contains(err.Error(), "--why") {
|
|
t.Errorf("a drill without what it tests: %v", err)
|
|
}
|
|
if err := handActCommand(context.Background(), []string{"drill", "--why", "a test"}); err == nil ||
|
|
!strings.Contains(err.Error(), "hand-act drill <what") {
|
|
t.Errorf("a drill without what was done: %v", err)
|
|
}
|
|
argv, err := argvFor("drill", map[string]any{"what": "stopped searxng", "why": "ADR 0240 phase A",
|
|
"condition": "machine.ace.module.searxng.unhealthy"})
|
|
if want := "hand-act drill stopped searxng --why ADR 0240 phase A --condition machine.ace.module.searxng.unhealthy"; err != nil ||
|
|
strings.Join(argv, " ") != want {
|
|
t.Errorf("the seat's drill: %v %v, want %q", argv, err, want)
|
|
}
|
|
if _, err := argvFor("drill", map[string]any{"what": "stopped searxng"}); err == nil {
|
|
t.Error("the seat's drill without why was not refused")
|
|
}
|
|
if repairingCommand([]string{"hand-act", "drill", "x"}) != "hand-act drill" {
|
|
t.Error("a drill through `command` is not held to why")
|
|
}
|
|
}
|