diff --git a/internal/inventory/adoption.go b/internal/inventory/adoption.go index feae77c..1edd697 100644 --- a/internal/inventory/adoption.go +++ b/internal/inventory/adoption.go @@ -118,7 +118,7 @@ func (i *Inventory) Converge(ctx context.Context, nodeName string) ([]string, er } if _, err := tx.Exec(ctx, `update node set adopted = false, adopted_since = null, converged_at = now(), - held = null, reachable = null + held = null, reachable = null, firewall = null, adoption_reported = null where id = $1`, node.ID); err != nil { return nil, err diff --git a/internal/inventory/adoption_test.go b/internal/inventory/adoption_test.go index 9e505a7..a0443f5 100644 --- a/internal/inventory/adoption_test.go +++ b/internal/inventory/adoption_test.go @@ -132,3 +132,30 @@ func TestATakenModuleOutlivesItsAssignmentAndReturningToAdopted(t *testing.T) { t.Fatalf("returning to adopted lost what was taken: %v", taken) } } + +// Converging clears the whole of a node's account of itself: what it held, what was reachable, the +// firewall it found and when it said so. Keeping any of it would have `node show` report an +// adopted machine's account of a converged one. +func TestConvergingClearsTheAccountTheNodeGave(t *testing.T) { + inv := fresh(t) + ctx := t.Context() + made, err := inv.AddNodeAs(ctx, "anchor", true) + if err != nil { + t.Fatal(err) + } + if err := inv.RecordAdoption(ctx, made.ID, + []Held{{ID: "notes.conf", Module: "notes", Kind: "file", Target: "/etc/notes.conf"}}, + "ufw", []Reach{{Protocol: "tcp", Address: "0.0.0.0", Port: 22, By: "sshd"}}); err != nil { + t.Fatal(err) + } + if _, err := inv.Converge(ctx, "anchor"); err != nil { + t.Fatal(err) + } + said, err := inv.AdoptionOf(ctx, "anchor") + if err != nil { + t.Fatal(err) + } + if len(said.Held) != 0 || len(said.Reachable) != 0 || said.Firewall != "" || !said.At.IsZero() { + t.Fatalf("converging kept the adopted machine's account: %+v", said) + } +}