The node-engine's witness ping is granted by the tool runner's name its manifest gives, any service's instance on its own node while none says so, never a name in mesh-grants (ADR 0601 §4; review round 1, finding 4)
This commit is contained in:
@@ -91,6 +91,32 @@ func TestTheCopiedComposerComposesAsTheControllers(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
golden(t, "user-lists.json", append(raw, '\n'))
|
||||
// ADR 0601 §4: the node-engine's witness pings the tool runner by the name its manifest gives it, and with none saying so
|
||||
// any service's instance on its own node, never a name written here.
|
||||
t.Run("the witness pings the tool runner by its manifest", func(t *testing.T) {
|
||||
for runner, want := range map[string]string{"runner-x": "$SRV.PING.runner-x.a", "": "$SRV.PING.*.a"} {
|
||||
placed := []Declared{{Module: "web"}}
|
||||
if runner != "" {
|
||||
placed = append(placed, Declared{Module: runner, ToolRunner: true})
|
||||
}
|
||||
users, err := Users(Records{Nodes: []string{"a"}, Assigned: map[string][]Declared{"a": placed}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
nodes := 0
|
||||
for _, u := range users {
|
||||
if u.Kind == KindNode {
|
||||
nodes++
|
||||
}
|
||||
if u.Kind == KindNode && (u.Runner != runner || !slices.Contains(WitnessSubjects(u), want)) {
|
||||
t.Errorf("runner %q: the node principal %+v witnesses %v, want %s", runner, u, WitnessSubjects(u), want)
|
||||
}
|
||||
}
|
||||
if nodes == 0 {
|
||||
t.Errorf("runner %q: no node principal composed", runner)
|
||||
}
|
||||
}
|
||||
})
|
||||
// An asker on a seat pulled by kind hears what that seat's workers gave up on, and no other stream's dead letters
|
||||
// (novox/hq issue 734: a check ask given up during a bus reload left its try running for ever).
|
||||
t.Run("an asker reads its seat's dead letters", func(t *testing.T) {
|
||||
|
||||
@@ -208,6 +208,9 @@ type Principal struct {
|
||||
// `<module>.<tool>` (novox/hq ADR 0240, to-be 48 §3): asked of the instance on its own machine and
|
||||
// nowhere else.
|
||||
Checks []string
|
||||
// Runner is, for a node, the module placed there whose manifest says it is the tool runner (`tool-runner`): the
|
||||
// service the node-engine's witness pings (WitnessSubjects). Empty when none says so.
|
||||
Runner string
|
||||
// MovesIntoTheVault is a machine principal whose node-engine may ask the vault's `move-in` in its own name (design
|
||||
// 57's V3, issue 676): set while the vault's holder serves it, so the engine can hand in the values sealed to its
|
||||
// machine, which nothing else can open.
|
||||
@@ -1603,7 +1606,7 @@ func discovering() []string {
|
||||
// WitnessSubjects are the subjects a machine's node-engine publishes to witness the core builds it
|
||||
// places (novox/hq ADR 0236): its own node tools' PING. The answers come to the machine's own inbox.
|
||||
func WitnessSubjects(p Principal) []string {
|
||||
return append([]string{pingSubject(p.Node)}, CheckSubjects(p)...)
|
||||
return append([]string{pingSubject(p.Runner, p.Node)}, CheckSubjects(p)...)
|
||||
}
|
||||
|
||||
// CheckSubjects are the tools a machine's node-engine asks as declared health checks (novox/hq ADR 0240,
|
||||
@@ -1627,10 +1630,15 @@ func CheckSubjects(p Principal) []string {
|
||||
return out
|
||||
}
|
||||
|
||||
// pingSubject is a node-engine's witness's ping of its own node's tools (novox/hq ADR 0236).
|
||||
func pingSubject(node string) string { return "$SRV.PING." + nodeToolsService + "." + node }
|
||||
|
||||
const nodeToolsService = "node-tools"
|
||||
// pingSubject is a node-engine's witness's ping of its own node's tool runner (novox/hq ADR 0236), named as the runner's
|
||||
// manifest says it is (ADR 0601 §4), never by a name here. With no manifest on the node saying so yet (an older build's,
|
||||
// the runner kept as it runs), any service's instance on this node: the ping of its own node alone, whatever it is called.
|
||||
func pingSubject(runner, node string) string {
|
||||
if runner == "" {
|
||||
runner = "*"
|
||||
}
|
||||
return "$SRV.PING." + runner + "." + node
|
||||
}
|
||||
|
||||
// VaultOwnCall is the subject a machine principal's node-engine asks the vault's `own` on, in its own name.
|
||||
func VaultOwnCall(p Principal) string {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -175,17 +175,20 @@ func Users(r Records) ([]Principal, error) {
|
||||
grants := -1
|
||||
for _, node := range sortedCopy(r.Nodes) {
|
||||
var checks []string
|
||||
bus := false
|
||||
bus, runner := false, ""
|
||||
for _, d := range r.Assigned[node] {
|
||||
if d.SnapshotsTheBus {
|
||||
bus = true
|
||||
}
|
||||
if d.ToolRunner {
|
||||
runner = d.Module // the node-engine's witness pings it by the name its manifest gives (ADR 0601 §4)
|
||||
}
|
||||
checks = append(checks, d.Checks...)
|
||||
}
|
||||
// **One user per login the node has** (novox/hq ADR 0583 §1): the one in use, and while it rotates the other too,
|
||||
// each with the node's permissions.
|
||||
for _, login := range nodeLoginsOf(r, node) {
|
||||
out = append(out, Principal{Kind: KindNode, Node: node, Login: login, Checks: checks,
|
||||
out = append(out, Principal{Kind: KindNode, Node: node, Login: login, Checks: checks, Runner: runner,
|
||||
MovesIntoTheVault: servesMoveIn(r), StatesItsKeyToTheVault: servesVerb(r, VaultNodeKey),
|
||||
AsksItsOwnSecrets: servesVerb(r, VaultOwn), AsksTheVaultToSign: servesVerb(r, VaultSign), Uses: asksSeatOf(r),
|
||||
FollowsGrantsUserList: bus, ServedReads: servedOn(served, node), RotatesItsLogin: servesVerb(r, VaultRotateNode)})
|
||||
|
||||
Reference in New Issue
Block a user