hscontrol/db: add migration setting non existing pak on nodes to null (#2412)

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
Kristoffer Dalby 2025-02-07 10:22:23 +01:00 committed by Kristoffer Dalby
parent ffe2f299cb
commit 3b55dacda1
No known key found for this signature in database
3 changed files with 47 additions and 5 deletions

View file

@ -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

View file

@ -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 {

Binary file not shown.