From 3b55dacda108da89011910d47bd913135683214c Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 7 Feb 2025 10:22:23 +0100 Subject: [PATCH] hscontrol/db: add migration setting non existing pak on nodes to null (#2412) Signed-off-by: Kristoffer Dalby --- hscontrol/db/db.go | 32 +++++++++++++++--- hscontrol/db/db_test.go | 20 +++++++++++ .../failing-node-preauth-constraint.sqlite | Bin 0 -> 65536 bytes 3 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 hscontrol/db/testdata/failing-node-preauth-constraint.sqlite diff --git a/hscontrol/db/db.go b/hscontrol/db/db.go index 0b6329be..59adb1e9 100644 --- a/hscontrol/db/db.go +++ b/hscontrol/db/db.go @@ -512,7 +512,7 @@ COMMIT; err := tx.AutoMigrate(&types.User{}) if err != nil { - return err + return fmt.Errorf("automigrating types.User: %w", err) } return nil @@ -527,7 +527,7 @@ COMMIT; Migrate: func(tx *gorm.DB) error { err := tx.AutoMigrate(&types.User{}) if err != nil { - return err + return fmt.Errorf("automigrating types.User: %w", err) } // Set up indexes and unique constraints outside of GORM, it does not support @@ -575,7 +575,7 @@ COMMIT; err := tx.AutoMigrate(&types.Route{}) if err != nil { - return err + return fmt.Errorf("automigrating types.Route: %w", err) } return nil @@ -589,11 +589,33 @@ COMMIT; Migrate: func(tx *gorm.DB) error { err := tx.AutoMigrate(&types.PreAuthKey{}) if err != nil { - return err + return fmt.Errorf("automigrating types.PreAuthKey: %w", err) } err = tx.AutoMigrate(&types.Node{}) if err != nil { - return err + return fmt.Errorf("automigrating types.Node: %w", err) + } + + return nil + }, + Rollback: func(db *gorm.DB) error { return nil }, + }, + // Ensure there are no nodes refering to a deleted preauthkey. + { + ID: "202502070949", + Migrate: func(tx *gorm.DB) error { + if tx.Migrator().HasTable(&types.PreAuthKey{}) { + err := tx.Exec(` +UPDATE nodes +SET auth_key_id = NULL +WHERE auth_key_id IS NOT NULL +AND auth_key_id NOT IN ( + SELECT id FROM pre_auth_keys +); + `).Error + if err != nil { + return fmt.Errorf("setting auth_key to null on nodes with non-existing keys: %w", err) + } } return nil diff --git a/hscontrol/db/db_test.go b/hscontrol/db/db_test.go index 0672c252..2a828b60 100644 --- a/hscontrol/db/db_test.go +++ b/hscontrol/db/db_test.go @@ -201,6 +201,26 @@ func TestMigrationsSQLite(t *testing.T) { } }, }, + { + dbPath: "testdata/failing-node-preauth-constraint.sqlite", + wantFunc: func(t *testing.T, h *HSDatabase) { + nodes, err := Read(h.DB, func(rx *gorm.DB) (types.Nodes, error) { + return ListNodes(rx) + }) + require.NoError(t, err) + + for _, node := range nodes { + assert.Falsef(t, node.MachineKey.IsZero(), "expected non zero machinekey") + assert.Contains(t, node.MachineKey.String(), "mkey:") + assert.Falsef(t, node.NodeKey.IsZero(), "expected non zero nodekey") + assert.Contains(t, node.NodeKey.String(), "nodekey:") + assert.Falsef(t, node.DiscoKey.IsZero(), "expected non zero discokey") + assert.Contains(t, node.DiscoKey.String(), "discokey:") + assert.Nil(t, node.AuthKey) + assert.Nil(t, node.AuthKeyID) + } + }, + }, } for _, tt := range tests { diff --git a/hscontrol/db/testdata/failing-node-preauth-constraint.sqlite b/hscontrol/db/testdata/failing-node-preauth-constraint.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..911c243461e93af35070ac5fb8c0208891a175ee GIT binary patch literal 65536 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