2023-07-24 04:30:53 -04:00
/ *
Copyright ( c ) Edgeless Systems GmbH
SPDX - License - Identifier : AGPL - 3.0 - only
* /
package cmd
import (
2023-08-04 07:53:51 -04:00
"context"
2023-07-24 04:30:53 -04:00
"fmt"
2023-08-04 07:53:51 -04:00
"io"
2023-07-24 04:30:53 -04:00
"github.com/edgelesssys/constellation/v2/cli/internal/upgrade"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/spf13/cobra"
)
// tfMigrationClient is a client for planning and applying Terraform migrations.
type tfMigrationClient struct {
log debugLog
}
// planMigration checks for Terraform migrations and asks for confirmation if there are any. The user input is returned as confirmedDiff.
// adapted from migrateTerraform().
2023-08-04 07:53:51 -04:00
func ( u * tfMigrationClient ) planMigration ( cmd * cobra . Command , file file . Handler , migrateCmd tfMigrationCmd ) ( hasDiff bool , err error ) {
2023-07-24 04:30:53 -04:00
u . log . Debugf ( "Planning %s" , migrateCmd . String ( ) )
if err := migrateCmd . CheckTerraformMigrations ( file ) ; err != nil {
return false , fmt . Errorf ( "checking workspace: %w" , err )
}
hasDiff , err = migrateCmd . Plan ( cmd . Context ( ) , file , cmd . OutOrStdout ( ) )
if err != nil {
return hasDiff , fmt . Errorf ( "planning terraform migrations: %w" , err )
}
return hasDiff , nil
}
// applyMigration plans and then applies the Terraform migration. The user is asked for confirmation if there are any changes.
// adapted from migrateTerraform().
2023-08-04 07:53:51 -04:00
func ( u * tfMigrationClient ) applyMigration ( cmd * cobra . Command , upgradeWorkspace string , file file . Handler , migrateCmd tfMigrationCmd , yesFlag bool ) error {
2023-07-24 04:30:53 -04:00
hasDiff , err := u . planMigration ( cmd , file , migrateCmd )
if err != nil {
2023-07-31 04:53:05 -04:00
return err
2023-07-24 04:30:53 -04:00
}
if hasDiff {
// If there are any Terraform migrations to apply, ask for confirmation
2023-08-11 08:35:25 -04:00
fmt . Fprintf ( cmd . OutOrStdout ( ) , "The %s upgrade requires a migration by applying an updated Terraform template. Please manually review the suggested changes.\n" , migrateCmd . String ( ) )
2023-07-26 11:29:03 -04:00
if ! yesFlag {
2023-07-24 04:30:53 -04:00
ok , err := askToConfirm ( cmd , fmt . Sprintf ( "Do you want to apply the %s?" , migrateCmd . String ( ) ) )
if err != nil {
return fmt . Errorf ( "asking for confirmation: %w" , err )
}
if ! ok {
cmd . Println ( "Aborting upgrade." )
2023-08-04 07:53:51 -04:00
if err := upgrade . CleanUpTerraformMigrations ( upgradeWorkspace , migrateCmd . UpgradeID ( ) , file ) ; err != nil {
2023-07-24 04:30:53 -04:00
return fmt . Errorf ( "cleaning up workspace: %w" , err )
}
return fmt . Errorf ( "aborted by user" )
}
}
u . log . Debugf ( "Applying Terraform %s migrations" , migrateCmd . String ( ) )
err := migrateCmd . Apply ( cmd . Context ( ) , file )
if err != nil {
return fmt . Errorf ( "applying terraform migrations: %w" , err )
}
} else {
u . log . Debugf ( "No Terraform diff detected" )
}
return nil
}
2023-08-04 07:53:51 -04:00
// tfMigrationCmd is an interface for all terraform upgrade / migration commands.
type tfMigrationCmd interface {
CheckTerraformMigrations ( file file . Handler ) error
Plan ( ctx context . Context , file file . Handler , outWriter io . Writer ) ( bool , error )
Apply ( ctx context . Context , fileHandler file . Handler ) error
String ( ) string
UpgradeID ( ) string
}