|
|
@@ -0,0 +1,67 @@
|
|
|
+package v2
|
|
|
+
|
|
|
+import (
|
|
|
+ "context"
|
|
|
+ "fmt"
|
|
|
+
|
|
|
+ "github.com/fatih/color"
|
|
|
+ porterv1 "github.com/porter-dev/api-contracts/generated/go/porter/v1"
|
|
|
+ api "github.com/porter-dev/porter/api/client"
|
|
|
+ "github.com/porter-dev/porter/cli/cmd/config"
|
|
|
+ "github.com/porter-dev/porter/internal/models"
|
|
|
+ "github.com/porter-dev/porter/internal/porter_app"
|
|
|
+)
|
|
|
+
|
|
|
+// RollbackInput is the input for the Rollback function
|
|
|
+type RollbackInput struct {
|
|
|
+ // CLIConfig is the CLI configuration
|
|
|
+ CLIConfig config.CLIConfig
|
|
|
+ // Client is the Porter API client
|
|
|
+ Client api.Client
|
|
|
+ // AppName is the name of the app to rollback
|
|
|
+ AppName string
|
|
|
+}
|
|
|
+
|
|
|
+// Rollback deploys the previous successful revision of an app
|
|
|
+func Rollback(ctx context.Context, inp RollbackInput) error {
|
|
|
+ targetResp, err := inp.Client.DefaultDeploymentTarget(ctx, inp.CLIConfig.Project, inp.CLIConfig.Cluster)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("error calling default deployment target endpoint: %w", err)
|
|
|
+ }
|
|
|
+ deploymentTargetID := targetResp.DeploymentTargetID
|
|
|
+
|
|
|
+ listResp, err := inp.Client.ListAppRevisions(ctx, inp.CLIConfig.Project, inp.CLIConfig.Cluster, inp.AppName, deploymentTargetID)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("error calling current app revision endpoint: %w", err)
|
|
|
+ }
|
|
|
+ if len(listResp.AppRevisions) <= 1 {
|
|
|
+ return fmt.Errorf("no previous successful revisions found for app %s", inp.AppName)
|
|
|
+ }
|
|
|
+
|
|
|
+ revisions := listResp.AppRevisions
|
|
|
+ var rollbackTarget porter_app.Revision
|
|
|
+
|
|
|
+ for _, rev := range revisions[1:] {
|
|
|
+ if rev.RevisionNumber != 0 && rev.Status == models.AppRevisionStatus_Deployed {
|
|
|
+ rollbackTarget = rev
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if rollbackTarget.ID == "" {
|
|
|
+ return fmt.Errorf("no previous successful revisions found for app %s", inp.AppName)
|
|
|
+ }
|
|
|
+
|
|
|
+ color.New(color.FgGreen).Printf("Rolling back to revision %d...\n", rollbackTarget.RevisionNumber) // nolint:errcheck,gosec
|
|
|
+
|
|
|
+ applyResp, err := inp.Client.ApplyPorterApp(ctx, inp.CLIConfig.Project, inp.CLIConfig.Cluster, rollbackTarget.B64AppProto, deploymentTargetID, "", false)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("error calling apply endpoint: %w", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ if applyResp.CLIAction != porterv1.EnumCLIAction_ENUM_CLI_ACTION_NONE {
|
|
|
+ return fmt.Errorf("unexpected CLI action: %s", applyResp.CLIAction)
|
|
|
+ }
|
|
|
+
|
|
|
+ color.New(color.FgGreen).Printf("Successfully rolled back to revision %d\n", rollbackTarget.RevisionNumber) // nolint:errcheck,gosec
|
|
|
+ return nil
|
|
|
+}
|