github.com/jlmeeker/kismatic@v1.10.1-0.20180612190640-57f9005a1f1a/pkg/cli/reset.go (about)

     1  package cli
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/apprenda/kismatic/pkg/install"
    10  	"github.com/apprenda/kismatic/pkg/util"
    11  	"github.com/spf13/cobra"
    12  )
    13  
    14  type resetOpts struct {
    15  	planFilename       string
    16  	generatedAssetsDir string
    17  	verbose            bool
    18  	outputFormat       string
    19  	limit              []string
    20  	force              bool
    21  	removeAssets       bool
    22  }
    23  
    24  // NewCmdReset resets nodes
    25  func NewCmdReset(in io.Reader, out io.Writer) *cobra.Command {
    26  	opts := &resetOpts{}
    27  	cmd := &cobra.Command{
    28  		Use:   "reset",
    29  		Short: "reset any changes made to the hosts by 'apply'",
    30  		RunE: func(cmd *cobra.Command, args []string) error {
    31  			if len(args) != 0 {
    32  				return fmt.Errorf("Unexpected args: %v", args)
    33  			}
    34  			if opts.force == false {
    35  				ans, err := util.PromptForString(in, out, "Are you sure you want to reset the cluster? All data will be lost", "N", []string{"N", "y"})
    36  				if err != nil {
    37  					return fmt.Errorf("error getting user response: %v", err)
    38  				}
    39  				if strings.ToLower(ans) != "y" {
    40  					os.Exit(0)
    41  				}
    42  			}
    43  			return doReset(out, opts)
    44  		},
    45  	}
    46  
    47  	cmd.Flags().StringSliceVar(&opts.limit, "limit", []string{}, "comma-separated list of hostnames to limit the execution to a subset of nodes")
    48  	cmd.Flags().StringVar(&opts.generatedAssetsDir, "generated-assets-dir", "generated", "path to the directory where assets generated during the installation process will be stored")
    49  	cmd.Flags().BoolVar(&opts.verbose, "verbose", false, "enable verbose logging from the installation")
    50  	cmd.Flags().StringVarP(&opts.outputFormat, "output", "o", "simple", "installation output format (options \"simple\"|\"raw\")")
    51  	cmd.Flags().BoolVar(&opts.force, "force", false, `do not prompt`)
    52  	cmd.Flags().BoolVar(&opts.removeAssets, "remove-assets", false, "remove generated-assets-dir")
    53  
    54  	addPlanFileFlag(cmd.PersistentFlags(), &opts.planFilename)
    55  
    56  	return cmd
    57  }
    58  
    59  func doReset(out io.Writer, opts *resetOpts) error {
    60  	planner := &install.FilePlanner{File: opts.planFilename}
    61  	if !planner.PlanExists() {
    62  		return planFileNotFoundErr{filename: opts.planFilename}
    63  	}
    64  	plan, err := planner.Read()
    65  	if err != nil {
    66  		return fmt.Errorf("failed to read plan file: %v", err)
    67  	}
    68  	executorOpts := install.ExecutorOptions{
    69  		GeneratedAssetsDirectory: opts.generatedAssetsDir,
    70  		OutputFormat:             opts.outputFormat,
    71  		Verbose:                  opts.verbose,
    72  	}
    73  	executor, err := install.NewExecutor(out, os.Stderr, executorOpts)
    74  	if err != nil {
    75  		return err
    76  	}
    77  	if err := executor.Reset(plan, opts.limit...); err != nil {
    78  		return fmt.Errorf("error running reset: %v", err)
    79  	}
    80  
    81  	if opts.removeAssets {
    82  		util.PrintHeader(out, "Removing Assets Directory", '=')
    83  		if _, err := os.Stat(opts.generatedAssetsDir); os.IsNotExist(err) {
    84  			util.PrettyPrintSkipped(out, "Removed %q", opts.generatedAssetsDir)
    85  		} else {
    86  			err := os.RemoveAll(opts.generatedAssetsDir)
    87  			if err != nil {
    88  				return fmt.Errorf("error deleting assets directory: %v", err)
    89  			}
    90  			util.PrettyPrintOk(out, "Remove %q directory", opts.generatedAssetsDir)
    91  		}
    92  	}
    93  
    94  	return nil
    95  }