2018-06-24 16:40:48 +03:00
package commands
import (
2018-07-09 16:47:38 +03:00
"fmt"
2021-03-08 14:59:35 +03:00
"github.com/hasura/graphql-engine/cli/internal/metadatautil"
2021-04-01 15:58:24 +03:00
"github.com/hasura/graphql-engine/cli/internal/hasura"
2021-02-17 07:20:19 +03:00
"github.com/hasura/graphql-engine/cli/internal/scripts"
2018-06-24 16:40:48 +03:00
"github.com/hasura/graphql-engine/cli"
2018-07-09 16:47:38 +03:00
"github.com/hasura/graphql-engine/cli/migrate"
mig "github.com/hasura/graphql-engine/cli/migrate/cmd"
2021-04-01 15:58:24 +03:00
"github.com/hasura/graphql-engine/cli/util"
2018-06-24 16:40:48 +03:00
"github.com/spf13/cobra"
2020-02-24 19:14:46 +03:00
"github.com/spf13/viper"
2019-02-14 12:37:47 +03:00
// Initialize migration drivers
_ "github.com/hasura/graphql-engine/cli/migrate/database/hasuradb"
_ "github.com/hasura/graphql-engine/cli/migrate/source/file"
2018-06-24 16:40:48 +03:00
)
2019-02-14 12:37:47 +03:00
// NewMigrateCmd returns the migrate command
2018-06-24 16:40:48 +03:00
func NewMigrateCmd ( ec * cli . ExecutionContext ) * cobra . Command {
2020-02-24 19:14:46 +03:00
v := viper . New ( )
2018-06-24 16:40:48 +03:00
migrateCmd := & cobra . Command {
Use : "migrate" ,
Short : "Manage migrations on the database" ,
SilenceUsage : true ,
2020-02-24 19:14:46 +03:00
PersistentPreRunE : func ( cmd * cobra . Command , args [ ] string ) error {
2020-03-26 06:08:54 +03:00
cmd . Root ( ) . PersistentPreRun ( cmd , args )
2020-03-03 10:06:59 +03:00
ec . Viper = v
2020-02-24 19:14:46 +03:00
err := ec . Prepare ( )
if err != nil {
return err
}
2021-01-18 20:11:05 +03:00
if err := ec . Validate ( ) ; err != nil {
return err
}
return nil
2020-02-24 19:14:46 +03:00
} ,
2018-06-24 16:40:48 +03:00
}
2020-02-24 19:14:46 +03:00
2020-04-08 14:55:42 +03:00
f := migrateCmd . PersistentFlags ( )
2021-03-09 09:43:41 +03:00
f . StringVar ( & ec . Source . Name , "database-name" , "" , "database on which operation should be applied" )
2020-04-08 14:55:42 +03:00
2021-03-15 18:40:52 +03:00
f . String ( "endpoint" , "" , "http(s) endpoint for Hasura GraphQL engine" )
f . String ( "admin-secret" , "" , "admin secret for Hasura GraphQL engine" )
f . String ( "access-key" , "" , "access key for Hasura GraphQL engine" )
2020-04-08 14:55:42 +03:00
f . MarkDeprecated ( "access-key" , "use --admin-secret instead" )
2020-04-28 14:59:57 +03:00
f . Bool ( "insecure-skip-tls-verify" , false , "skip TLS verification and disable cert checking (default: false)" )
f . String ( "certificate-authority" , "" , "path to a cert file for the certificate authority" )
2020-04-08 14:55:42 +03:00
util . BindPFlag ( v , "endpoint" , f . Lookup ( "endpoint" ) )
util . BindPFlag ( v , "admin_secret" , f . Lookup ( "admin-secret" ) )
util . BindPFlag ( v , "access_key" , f . Lookup ( "access-key" ) )
2020-04-28 14:59:57 +03:00
util . BindPFlag ( v , "insecure_skip_tls_verify" , f . Lookup ( "insecure-skip-tls-verify" ) )
util . BindPFlag ( v , "certificate_authority" , f . Lookup ( "certificate-authority" ) )
2020-04-08 14:55:42 +03:00
2021-05-17 18:19:15 +03:00
f . BoolVar ( & ec . DisableAutoStateMigration , "disable-auto-state-migration" , false , "after a config v3 update, disable automatically moving state from hdb_catalog.schema_migrations to catalog state" )
f . MarkHidden ( "disable-auto-state-migration" )
2021-01-18 20:11:05 +03:00
migrateCmd . AddCommand (
newMigrateApplyCmd ( ec ) ,
newMigrateStatusCmd ( ec ) ,
newMigrateCreateCmd ( ec ) ,
newMigrateSquashCmd ( ec ) ,
)
2018-06-24 16:40:48 +03:00
return migrateCmd
}
2018-07-09 16:47:38 +03:00
2019-02-14 12:37:47 +03:00
// ExecuteMigration runs the actual migration
2018-08-21 21:37:47 +03:00
func ExecuteMigration ( cmd string , t * migrate . Migrate , stepOrVersion int64 ) error {
2018-07-09 16:47:38 +03:00
var err error
switch cmd {
case "up" :
err = mig . UpCmd ( t , stepOrVersion )
case "down" :
err = mig . DownCmd ( t , stepOrVersion )
2020-02-03 10:03:32 +03:00
case "gotoVersion" :
err = mig . GotoVersionCmd ( t , stepOrVersion )
2018-07-09 16:47:38 +03:00
case "version" :
var direction string
if stepOrVersion >= 0 {
direction = "up"
} else {
direction = "down"
stepOrVersion = - ( stepOrVersion )
}
err = mig . GotoCmd ( t , uint64 ( stepOrVersion ) , direction )
default :
2021-01-18 20:11:05 +03:00
err = fmt . Errorf ( "invalid command" )
2018-07-09 16:47:38 +03:00
}
return err
}
func executeStatus ( t * migrate . Migrate ) ( * migrate . Status , error ) {
status , err := t . GetStatus ( )
if err != nil {
return nil , err
}
return status , nil
}
2021-04-01 15:58:24 +03:00
func validateConfigV3Flags ( cmd * cobra . Command , ec * cli . ExecutionContext ) error {
if ec . Config . Version >= cli . V3 {
if ! cmd . Flags ( ) . Changed ( "database-name" ) {
return errDatabaseNameNotSet { "--database-name flag is required" }
} else {
// if database-name flag is set
// find out the database kind by making a API call to server
// and update ec to include the database name and kind
sourceKind , err := metadatautil . GetSourceKind ( ec . APIClient . V1Metadata . ExportMetadata , ec . Source . Name )
if err != nil {
return fmt . Errorf ( "determining database kind of %s: %w" , ec . Source . Name , err )
}
if sourceKind == nil {
return fmt . Errorf ( "error determining database kind for %s, check if database exists on hasura" , ec . Source . Name )
}
ec . Source . Kind = * sourceKind
2021-04-19 10:05:21 +03:00
if ! migrate . IsMigrationsSupported ( * sourceKind ) {
return fmt . Errorf ( "migrations on source %s of kind %s is not supported" , ec . Source . Name , * sourceKind )
}
2021-04-01 15:58:24 +03:00
}
} else {
// for project using config older than v3, use PG source kind
ec . Source . Kind = hasura . SourceKindPG
if err := scripts . CheckIfUpdateToConfigV3IsRequired ( ec ) ; err != nil {
return err
}
}
return nil
}
type errDatabaseNameNotSet struct {
message string
}
func ( e errDatabaseNameNotSet ) Error ( ) string {
return e . message
}