github.com/pluralsh/plural-cli@v0.9.5/pkg/wkspace/actions.go (about)

     1  package wkspace
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  	"time"
     9  
    10  	"go.mercari.io/hcledit"
    11  	"helm.sh/helm/v3/pkg/action"
    12  
    13  	"github.com/pluralsh/plural-cli/pkg/executor"
    14  	"github.com/pluralsh/plural-cli/pkg/helm"
    15  	"github.com/pluralsh/plural-cli/pkg/kubernetes"
    16  	"github.com/pluralsh/plural-cli/pkg/utils"
    17  	"github.com/pluralsh/plural-cli/pkg/utils/git"
    18  	"github.com/pluralsh/plural-cli/pkg/utils/pathing"
    19  )
    20  
    21  type checker func(s string) bool
    22  
    23  var alwaysErr checker = func(s string) bool { return false }
    24  
    25  func (c checker) execSuppressed(command string, args ...string) (err error) {
    26  	for retry := 2; retry >= 0; retry-- {
    27  		utils.Highlight("%s %s ~> ", command, strings.Join(args, " "))
    28  		cmd, out := executor.SuppressedCommand(command, args...)
    29  		err = executor.RunCommand(cmd, out)
    30  		if err == nil || c(out.Format()) {
    31  			break
    32  		}
    33  		fmt.Printf("retrying command, number of retries remaining: %d\n", retry)
    34  	}
    35  
    36  	return
    37  }
    38  
    39  func (w *Workspace) DestroyHelm() error {
    40  	// ensure current kubeconfig is correct before destroying stuff
    41  	if err := w.Provider.KubeConfig(); err != nil {
    42  		return err
    43  	}
    44  
    45  	name := w.Installation.Repository.Name
    46  	namespace := w.Config.Namespace(name)
    47  	var err error
    48  	for retry := 2; retry >= 0; retry-- {
    49  		err = uninstallHelm(name, namespace)
    50  		if err == nil {
    51  			break
    52  		}
    53  		fmt.Printf("retrying command, number of retries remaining: %d\n", retry)
    54  	}
    55  
    56  	return err
    57  
    58  }
    59  
    60  func (w *Workspace) Bounce() error {
    61  	return w.ToMinimal().BounceHelm(false, nil, nil, nil)
    62  }
    63  
    64  func (w *Workspace) HelmDiff() error {
    65  	return w.ToMinimal().DiffHelm()
    66  }
    67  
    68  func (w *Workspace) Destroy() error {
    69  	if err := w.DestroyHelm(); err != nil {
    70  		return err
    71  	}
    72  
    73  	if err := w.DestroyTerraform(); err != nil {
    74  		return err
    75  	}
    76  
    77  	return w.Reset()
    78  }
    79  
    80  func (w *Workspace) Reset() error {
    81  	repo := w.Installation.Repository
    82  	repoRoot, err := git.Root()
    83  	if err != nil {
    84  		return err
    85  	}
    86  
    87  	deployFile := pathing.SanitizeFilepath(filepath.Join(repoRoot, repo.Name, "deploy.hcl"))
    88  	editor, err := hcledit.ReadFile(deployFile)
    89  	if err != nil {
    90  		return err
    91  	}
    92  	if err := editor.Update("step.*.sha", ""); err != nil {
    93  		return err
    94  	}
    95  	if err := editor.OverWriteFile(); err != nil {
    96  		return err
    97  	}
    98  
    99  	return nil
   100  }
   101  
   102  func (w *Workspace) DestroyTerraform() error {
   103  	repo := w.Installation.Repository
   104  	repoRoot, err := git.Root()
   105  	if err != nil {
   106  		return err
   107  	}
   108  	path, err := filepath.Abs(pathing.SanitizeFilepath(filepath.Join(repoRoot, repo.Name, "terraform")))
   109  	if err != nil {
   110  		return err
   111  	}
   112  
   113  	time.AfterFunc(1*time.Minute, func() {
   114  		kube, err := kubernetes.Kubernetes()
   115  		if err != nil {
   116  			fmt.Printf("Could not set up k8s client due to %s\n", err)
   117  			return
   118  		}
   119  
   120  		ns := w.Config.Namespace(repo.Name)
   121  		if err := kube.FinalizeNamespace(ns); err != nil {
   122  			return
   123  		}
   124  	})
   125  
   126  	if err := os.Chdir(path); err != nil {
   127  		return err
   128  	}
   129  	if err := alwaysErr.execSuppressed("terraform", "init", "-upgrade"); err != nil {
   130  		return err
   131  	}
   132  
   133  	return alwaysErr.execSuppressed("terraform", "destroy", "-auto-approve")
   134  }
   135  
   136  func uninstallHelm(name, namespace string) error {
   137  	exists, err := isReleaseAvailable(name, namespace)
   138  	if err != nil {
   139  		return err
   140  	}
   141  	if exists {
   142  		actionConfig, err := helm.GetActionConfig(namespace)
   143  		if err != nil {
   144  			return err
   145  		}
   146  		client := action.NewUninstall(actionConfig)
   147  
   148  		_, err = client.Run(name)
   149  		if err != nil {
   150  			return err
   151  		}
   152  	}
   153  	return nil
   154  }
   155  
   156  func isReleaseAvailable(name, namespace string) (bool, error) {
   157  	actionConfig, err := helm.GetActionConfig(namespace)
   158  	if err != nil {
   159  		return false, err
   160  	}
   161  	client := action.NewList(actionConfig)
   162  	resp, err := client.Run()
   163  	if err != nil {
   164  		return false, err
   165  	}
   166  	for _, rel := range resp {
   167  		if rel.Name == name {
   168  			return true, nil
   169  		}
   170  	}
   171  	return false, nil
   172  }