From 967d62c184bbdfb2bb1482404c0b30d492cbbde0 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 7 Feb 2025 10:13:51 +0100 Subject: [PATCH] hscontrol/db: add migration setting non existing pak on nodes to null 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 591c1c9217..7f4ecb32db 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 8ca773033c..079f632fe9 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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