package main import ( "fmt" "log" "github.com/porter-dev/porter/cmd/migrate/keyrotate" adapter "github.com/porter-dev/porter/internal/adapter" "github.com/porter-dev/porter/internal/config" lr "github.com/porter-dev/porter/internal/logger" "github.com/porter-dev/porter/internal/repository/gorm" "github.com/joeshaw/envdecode" ) func main() { fmt.Println("running migrations...") appConf := config.FromEnv() logger := lr.NewConsole(true) db, err := adapter.New(&appConf.Db) if err != nil { logger.Fatal().Err(err).Msg("") return } err = gorm.AutoMigrate(db) if err != nil { logger.Fatal().Err(err).Msg("") return } if shouldRotate, oldKeyStr, newKeyStr := shouldKeyRotate(); shouldRotate { oldKey := [32]byte{} newKey := [32]byte{} copy(oldKey[:], []byte(oldKeyStr)) copy(newKey[:], []byte(newKeyStr)) err := keyrotate.Rotate(db, &oldKey, &newKey) if err != nil { panic(err) } } } type RotateConf struct { // we add a dummy field to avoid empty struct issue with envdecode DummyField string `env:"ASDF,default=asdf"` OldEncryptionKey string `env:"OLD_ENCRYPTION_KEY"` NewEncryptionKey string `env:"NEW_ENCRYPTION_KEY"` } func shouldKeyRotate() (bool, string, string) { var c RotateConf if err := envdecode.StrictDecode(&c); err != nil { log.Fatalf("Failed to decode migration conf: %s", err) return false, "", "" } return c.OldEncryptionKey != "" && c.NewEncryptionKey != "", c.OldEncryptionKey, c.NewEncryptionKey }