github.com/grafana/tanka@v0.26.1-0.20240506093700-c22cfc35c21a/pkg/tanka/prune.go (about)

     1  package tanka
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  
     7  	"github.com/fatih/color"
     8  
     9  	"github.com/grafana/tanka/pkg/kubernetes"
    10  	"github.com/grafana/tanka/pkg/term"
    11  )
    12  
    13  // PruneOpts specify additional properties for the Prune action
    14  type PruneOpts struct {
    15  	ApplyBaseOpts
    16  }
    17  
    18  // Prune deletes all resources from the cluster, that are no longer present in
    19  // Jsonnet. It uses the `tanka.dev/environment` label to identify those.
    20  func Prune(baseDir string, opts PruneOpts) error {
    21  	// parse jsonnet, init k8s client
    22  	p, err := Load(baseDir, opts.Opts)
    23  	if err != nil {
    24  		return err
    25  	}
    26  	kube, err := p.Connect()
    27  	if err != nil {
    28  		return err
    29  	}
    30  	defer kube.Close()
    31  
    32  	// find orphaned resources
    33  	orphaned, err := kube.Orphaned(p.Resources)
    34  	if err != nil {
    35  		return err
    36  	}
    37  
    38  	if len(orphaned) == 0 {
    39  		fmt.Fprintln(os.Stderr, "Nothing found to prune.")
    40  		return nil
    41  	}
    42  
    43  	// print diff
    44  	diff, err := kubernetes.StaticDiffer(false)(orphaned)
    45  	if err != nil {
    46  		// static diff can't fail normally, so unlike in apply, this is fatal
    47  		// here
    48  		return err
    49  	}
    50  	fmt.Print(term.Colordiff(*diff).String())
    51  
    52  	// print namespace removal warning
    53  	namespaces := []string{}
    54  	for _, obj := range orphaned {
    55  		if obj.Kind() == "Namespace" {
    56  			namespaces = append(namespaces, obj.Metadata().Name())
    57  		}
    58  	}
    59  	if len(namespaces) > 0 {
    60  		warning := color.New(color.FgHiYellow, color.Bold).FprintfFunc()
    61  		warning(color.Error, "WARNING: This will delete following namespaces and all resources in them:\n")
    62  		for _, ns := range namespaces {
    63  			fmt.Fprintf(os.Stderr, " - %s\n", ns)
    64  		}
    65  		fmt.Fprintln(os.Stderr, "")
    66  	}
    67  
    68  	// prompt for confirm
    69  	if opts.AutoApprove != AutoApproveAlways {
    70  		if err := confirmPrompt("Pruning from", p.Env.Spec.Namespace, kube.Info()); err != nil {
    71  			return err
    72  		}
    73  	}
    74  
    75  	// delete resources
    76  	return kube.Delete(orphaned, kubernetes.DeleteOpts{
    77  		Force:  opts.Force,
    78  		DryRun: opts.DryRun,
    79  	})
    80  }