From b25738b86089eda092ad2f52e7bde874a9b8f515 Mon Sep 17 00:00:00 2001 From: Alexander Brand Date: Wed, 31 Jan 2018 08:06:12 -0500 Subject: [PATCH 1/2] kubeadm: prompt for confirmation when resetting a master Signed-off-by: Alexander Brand --- cmd/kubeadm/app/cmd/cmd.go | 4 ++-- cmd/kubeadm/app/cmd/reset.go | 28 ++++++++++++++++++++++++---- cmd/kubeadm/app/cmd/reset_test.go | 11 +++++++---- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/cmd/kubeadm/app/cmd/cmd.go b/cmd/kubeadm/app/cmd/cmd.go index a3124b31be2..b0ed29535ea 100644 --- a/cmd/kubeadm/app/cmd/cmd.go +++ b/cmd/kubeadm/app/cmd/cmd.go @@ -32,7 +32,7 @@ import ( ) // NewKubeadmCommand return cobra.Command to run kubeadm command -func NewKubeadmCommand(_ io.Reader, out, err io.Writer) *cobra.Command { +func NewKubeadmCommand(in io.Reader, out, err io.Writer) *cobra.Command { cmds := &cobra.Command{ Use: "kubeadm", Short: "kubeadm: easily bootstrap a secure Kubernetes cluster", @@ -77,7 +77,7 @@ func NewKubeadmCommand(_ io.Reader, out, err io.Writer) *cobra.Command { cmds.AddCommand(NewCmdConfig(out)) cmds.AddCommand(NewCmdInit(out)) cmds.AddCommand(NewCmdJoin(out)) - cmds.AddCommand(NewCmdReset(out)) + cmds.AddCommand(NewCmdReset(in, out)) cmds.AddCommand(NewCmdVersion(out)) cmds.AddCommand(NewCmdToken(out, err)) cmds.AddCommand(upgrade.NewCmdUpgrade(out)) diff --git a/cmd/kubeadm/app/cmd/reset.go b/cmd/kubeadm/app/cmd/reset.go index b41d2b048e5..5f914aa1251 100644 --- a/cmd/kubeadm/app/cmd/reset.go +++ b/cmd/kubeadm/app/cmd/reset.go @@ -17,6 +17,8 @@ limitations under the License. package cmd import ( + "bufio" + "errors" "fmt" "io" "os" @@ -44,11 +46,12 @@ var ( ) // NewCmdReset returns the "kubeadm reset" command -func NewCmdReset(out io.Writer) *cobra.Command { +func NewCmdReset(in io.Reader, out io.Writer) *cobra.Command { var skipPreFlight bool var certsDir string var criSocketPath string var ignorePreflightErrors []string + var forceReset bool cmd := &cobra.Command{ Use: "reset", @@ -57,7 +60,7 @@ func NewCmdReset(out io.Writer) *cobra.Command { ignorePreflightErrorsSet, err := validation.ValidateIgnorePreflightErrors(ignorePreflightErrors, skipPreFlight) kubeadmutil.CheckErr(err) - r, err := NewReset(ignorePreflightErrorsSet, certsDir, criSocketPath) + r, err := NewReset(in, ignorePreflightErrorsSet, forceReset, certsDir, criSocketPath) kubeadmutil.CheckErr(err) kubeadmutil.CheckErr(r.Run(out)) }, @@ -83,6 +86,11 @@ func NewCmdReset(out io.Writer) *cobra.Command { "The path to the CRI socket to use with crictl when cleaning up containers.", ) + cmd.PersistentFlags().BoolVar( + &forceReset, "force", false, + "Reset the node without prompting for confirmation.", + ) + return cmd } @@ -93,9 +101,21 @@ type Reset struct { } // NewReset instantiate Reset struct -func NewReset(ignorePreflightErrors sets.String, certsDir, criSocketPath string) (*Reset, error) { - glog.Infoln("[preflight] running pre-flight checks") +func NewReset(in io.Reader, ignorePreflightErrors sets.String, forceReset bool, certsDir, criSocketPath string) (*Reset, error) { + if !forceReset { + fmt.Println("[reset] WARNING: changes made to this host by 'kubeadm init' or 'kubeadm join' will be reverted.") + fmt.Print("[reset] are you sure you want to proceed? [y/N]: ") + s := bufio.NewScanner(in) + s.Scan() + if err := s.Err(); err != nil { + return nil, err + } + if s.Text() != "y" { + return nil, errors.New("Aborted reset operation") + } + } + glog.Infoln("[preflight] running pre-flight checks") if err := preflight.RunRootCheckOnly(ignorePreflightErrors); err != nil { return nil, err } diff --git a/cmd/kubeadm/app/cmd/reset_test.go b/cmd/kubeadm/app/cmd/reset_test.go index 605d0c01c35..dee7984630b 100644 --- a/cmd/kubeadm/app/cmd/reset_test.go +++ b/cmd/kubeadm/app/cmd/reset_test.go @@ -56,28 +56,31 @@ func assertDirEmpty(t *testing.T, path string) { } func TestNewReset(t *testing.T) { + var in io.Reader certsDir := kubeadmapiext.DefaultCertificatesDir criSocketPath := "/var/run/dockershim.sock" skipPreFlight := false + forceReset := true ignorePreflightErrors := []string{"all"} ignorePreflightErrorsSet, _ := validation.ValidateIgnorePreflightErrors(ignorePreflightErrors, skipPreFlight) - NewReset(ignorePreflightErrorsSet, certsDir, criSocketPath) + NewReset(in, ignorePreflightErrorsSet, forceReset, certsDir, criSocketPath) ignorePreflightErrors = []string{} ignorePreflightErrorsSet, _ = validation.ValidateIgnorePreflightErrors(ignorePreflightErrors, skipPreFlight) - NewReset(ignorePreflightErrorsSet, certsDir, criSocketPath) + NewReset(in, ignorePreflightErrorsSet, forceReset, certsDir, criSocketPath) } func TestNewCmdReset(t *testing.T) { var out io.Writer - cmd := NewCmdReset(out) + var in io.Reader + cmd := NewCmdReset(in, out) tmpDir, err := ioutil.TempDir("", "kubeadm-reset-test") if err != nil { t.Errorf("Unable to create temporary directory: %v", err) } - args := []string{"--ignore-preflight-errors=all", "--cert-dir=" + tmpDir} + args := []string{"--ignore-preflight-errors=all", "--cert-dir=" + tmpDir, "--force"} cmd.SetArgs(args) if err := cmd.Execute(); err != nil { t.Errorf("Cannot execute reset command: %v", err) From 8ea5be8d893d43ad7ec1357f81f1db2c06549a07 Mon Sep 17 00:00:00 2001 From: Alexander Brand Date: Wed, 25 Apr 2018 16:21:16 -0400 Subject: [PATCH 2/2] kubeadm: accept 'Y' and 'y' as reset confirmation Signed-off-by: Alexander Brand --- cmd/kubeadm/app/cmd/reset.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/kubeadm/app/cmd/reset.go b/cmd/kubeadm/app/cmd/reset.go index 5f914aa1251..4defa95bd80 100644 --- a/cmd/kubeadm/app/cmd/reset.go +++ b/cmd/kubeadm/app/cmd/reset.go @@ -110,7 +110,7 @@ func NewReset(in io.Reader, ignorePreflightErrors sets.String, forceReset bool, if err := s.Err(); err != nil { return nil, err } - if s.Text() != "y" { + if strings.ToLower(s.Text()) != "y" { return nil, errors.New("Aborted reset operation") } }