Files
mesh-controller/internal/inventory/secret_move_test.go
T

122 lines
4.5 KiB
Go

package inventory
import (
"context"
"testing"
"github.com/novox/mesh-controller/internal/catalogue"
)
// The move reads every row sealed to a machine as the store holds it (design 57's V3, issue 676): its modules' own
// secrets and each pair credential it is an end of, sealed to it, under the vault's name for the row, with its
// origin and generation; a row sealed to a key the machine no longer has is said as not current; what moved is kept
// once, for both ends of a pair; and the move's start and the copy of the asks are recorded once.
func TestTheMoveReadsEveryRowSealedToAMachineAsItIs(t *testing.T) {
inv := fresh(t)
ctx := context.Background()
opens := map[string]func(string) ([]byte, bool){}
for _, n := range []string{"consumer", "provider"} {
node, err := inv.AddNode(ctx, n)
if err != nil {
t.Fatal(err)
}
key, open := aSealingKey(t)
opens[n] = open
if err := inv.RecordSealingKey(ctx, node.ID, key); err != nil {
t.Fatal(err)
}
}
if err := inv.RegisterModule(ctx, catalogue.Manifest{Module: "gitea", Version: "1",
Requires: []string{"postgres-database"}, Secrets: map[string]string{"postgres-database": "/run/pg"}},
Source{}); err != nil {
t.Fatal(err)
}
if err := inv.RegisterModule(ctx, catalogue.Manifest{Module: "postgres", Version: "1"}, Source{}); err != nil {
t.Fatal(err)
}
if _, err := inv.SecretForModule(ctx, "provider", "postgres", "superuser"); err != nil {
t.Fatal(err)
}
if _, err := inv.SecretFor(ctx, "postgres-database", "consumer", "gitea", "provider", ""); err != nil {
t.Fatal(err)
}
provider, err := inv.SecretsToMoveFrom(ctx, "provider")
if err != nil {
t.Fatal(err)
}
consumer, err := inv.SecretsToMoveFrom(ctx, "consumer")
if err != nil {
t.Fatal(err)
}
if len(provider) != 2 || len(consumer) != 1 {
t.Fatalf("the provider has %d rows, the consumer %d: %+v %+v", len(provider), len(consumer), provider, consumer)
}
own := provider[0]
if own.Secret != "own/provider/postgres/superuser" || !own.Own() || own.Origin != "made" || !own.Current ||
own.Moved != nil || own.MadeAt.IsZero() {
t.Errorf("the own secret: %+v", own)
}
pair := provider[1]
if pair.Secret != "pair/provider/postgres-database/consumer/gitea" || pair.Own() || pair.Provider != "provider" ||
pair.Consumer != "consumer" || pair.ConsumerModule != "gitea" || !pair.Current {
t.Errorf("the pair from the provider's end: %+v", pair)
}
// Each end is handed what was sealed to it, and it opens there to the same value.
atProvider, ok1 := opens["provider"](pair.Sealed)
atConsumer, ok2 := opens["consumer"](consumer[0].Sealed)
if !ok1 || !ok2 || string(atProvider) != string(atConsumer) {
t.Fatal("the two ends of the pair were not each handed what was sealed to them")
}
if _, ok := opens["provider"](own.Sealed); !ok {
t.Fatal("the own secret does not open with its machine's key")
}
// Moved by one end, the row is moved for both, and the first record stands.
if err := inv.RecordSecretMoved(ctx, consumer[0], 1); err != nil {
t.Fatal(err)
}
if err := inv.RecordSecretMoved(ctx, pair, 2); err != nil {
t.Fatal(err)
}
provider, _ = inv.SecretsToMoveFrom(ctx, "provider")
if m := provider[1].Moved; m == nil || m.Node != "consumer" || m.Generation != 1 || m.Digest != consumer[0].Digest || m.Digest != provider[1].Digest {
t.Errorf("the pair as moved: %+v", m)
}
if provider[0].Moved != nil {
t.Error("the own secret reads as moved")
}
// A machine that rejoined has a key its old rows were not sealed to.
node, _ := inv.NodeByName(ctx, "provider")
key, _ := aSealingKey(t)
if err := inv.RecordSealingKey(ctx, node.ID, key); err != nil {
t.Fatal(err)
}
provider, _ = inv.SecretsToMoveFrom(ctx, "provider")
if provider[0].Current {
t.Error("a row sealed to the machine's earlier key reads as current")
}
if _, started, _ := inv.SecretMoveStarted(ctx); started {
t.Fatal("the move reads as started before it was")
}
first, err := inv.StartSecretMove(ctx, "jochen")
if err != nil || first.StartedBy != "jochen" || first.AsksMovedAt != nil {
t.Fatalf("started %+v, %v", first, err)
}
again, _ := inv.StartSecretMove(ctx, "someone else")
if again.StartedBy != "jochen" || !again.StartedAt.Equal(first.StartedAt) {
t.Errorf("a second start replaced the first: %+v", again)
}
if err := inv.RecordAsksMoved(ctx); err != nil {
t.Fatal(err)
}
if m, _, _ := inv.SecretMoveStarted(ctx); m.AsksMovedAt == nil {
t.Error("the copy of the asks was not recorded")
}
if _, err := inv.SecretsToMoveFrom(ctx, "nowhere"); err == nil {
t.Error("a machine the mesh does not know was read")
}
}