Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missing confirmation for reset #1251

Merged
33 changes: 4 additions & 29 deletions pkg/cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,16 @@ limitations under the License.
package cmd

import (
"bufio"
"fmt"
"os"
"path/filepath"
"reflect"
"strings"

"github.com/MakeNowJust/heredoc/v2"
"github.com/Masterminds/semver/v3"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"golang.org/x/term"

"k8c.io/kubeone/pkg/credentials"
"k8c.io/kubeone/pkg/state"
Expand Down Expand Up @@ -312,7 +309,7 @@ func runApplyInstall(s *state.State, opts *applyOpts) error { // Print the expec
}

fmt.Println()
confirm, err := confirmApply(opts.AutoApprove)
confirm, err := confirmCommand(opts.AutoApprove)
if err != nil {
return err
}
Expand Down Expand Up @@ -416,7 +413,7 @@ func runApplyUpgradeIfNeeded(s *state.State, opts *applyOpts) error {
}

fmt.Println()
confirm, err := confirmApply(opts.AutoApprove)
confirm, err := confirmCommand(opts.AutoApprove)
if err != nil {
return err
}
Expand Down Expand Up @@ -448,7 +445,7 @@ func runApplyRotateKey(s *state.State, opts *applyOpts) error {
}

fmt.Println()
confirm, err := confirmApply(opts.AutoApprove)
confirm, err := confirmCommand(opts.AutoApprove)
if err != nil {
return err
}
Expand All @@ -460,28 +457,6 @@ func runApplyRotateKey(s *state.State, opts *applyOpts) error {
return errors.Wrap(tasksToRun.Run(s), "failed to reconcile the cluster")
}

func confirmApply(autoApprove bool) (bool, error) {
if autoApprove {
return true, nil
}

if !term.IsTerminal(int(os.Stdin.Fd())) || !term.IsTerminal(int(os.Stdout.Fd())) {
return false, errors.New("not running in the terminal")
}

reader := bufio.NewReader(os.Stdin)
fmt.Print("Do you want to proceed (yes/no): ")

confirmation, err := reader.ReadString('\n')
if err != nil {
return false, err
}

fmt.Println()

return strings.Trim(confirmation, "\n") == "yes", nil
}

func printHostInformation(host state.Host) {
containerdCR := host.ContainerRuntimeContainerd
dockerCR := host.ContainerRuntimeDocker
Expand Down Expand Up @@ -518,7 +493,7 @@ func componentStatusReport(component state.ComponentStatus) {

func boolStr(b bool) string {
if b {
return "yes"
return yes
}
return "no"
}
Expand Down
37 changes: 37 additions & 0 deletions pkg/cmd/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ limitations under the License.
package cmd

import (
"fmt"

"github.com/MakeNowJust/heredoc/v2"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"

"k8c.io/kubeone/pkg/kubeconfig"
"k8c.io/kubeone/pkg/state"
"k8c.io/kubeone/pkg/tasks"

"github.com/kubermatic/machine-controller/pkg/machines/v1alpha1"
)

type resetOpts struct {
Expand Down Expand Up @@ -100,5 +105,37 @@ func runReset(opts *resetOpts) error {

s.Logger.Warnln("this command will require an explicit confirmation starting with the next minor release (v1.3)")

fmt.Println("The following nodes will be reset. The Kubernetes cluster running on those nodes will be permanently destroyed ")
for _, node := range s.Cluster.ControlPlane.Hosts {
fmt.Printf("\t- reset control plane node %q (%s)\n", node.Hostname, node.PrivateAddress)
}
for _, node := range s.Cluster.StaticWorkers.Hosts {
fmt.Printf("\t- reset static worker nodes %q (%s)\n", node.Hostname, node.PrivateAddress)
}

err = kubeconfig.BuildKubernetesClientset(s)
if err == nil {
// Gather information about machine-controller managed nodes
machines := v1alpha1.MachineList{}
if err = s.DynamicClient.List(s.Context, &machines); err != nil {
s.Logger.Warnln("Failed to list Machines. Worker nodes will not be deleted. If there are worker nodes in the cluster, you might have to delete them manually.")
}
for _, machine := range machines.Items {
fmt.Printf("\t- reset machine-controller managed machines %q\n", machine.Name)
}
} else {
s.Logger.Warnln("Failed to list Machines. Worker nodes will not be deleted. If there are worker nodes in the cluster, you might have to delete them manually.")
}

confirm, err := confirmCommand(opts.AutoApprove)
if err != nil {
return err
}

if !confirm {
s.Logger.Println("Operation canceled.")
return nil
}

return errors.Wrap(tasks.WithReset(nil).Run(s), "failed to reset the cluster")
}
28 changes: 28 additions & 0 deletions pkg/cmd/shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,25 @@ limitations under the License.
package cmd

import (
"bufio"
"context"
"fmt"
"os"
"reflect"
"strings"

"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
"golang.org/x/term"

kubeoneapi "k8c.io/kubeone/pkg/apis/kubeone"
"k8c.io/kubeone/pkg/apis/kubeone/config"
"k8c.io/kubeone/pkg/state"
)

const yes = "yes"

type globalOptions struct {
ManifestFile string `longflag:"manifest" shortflag:"m"`
TerraformState string `longflag:"tfjson" shortflag:"t"`
Expand Down Expand Up @@ -127,3 +133,25 @@ func loadClusterConfig(filename, terraformOutputPath, credentialsFilePath string

return a, nil
}

func confirmCommand(autoApprove bool) (bool, error) {
if autoApprove {
return true, nil
}

if !term.IsTerminal(int(os.Stdin.Fd())) || !term.IsTerminal(int(os.Stdout.Fd())) {
return false, errors.New("not running in the terminal")
}

reader := bufio.NewReader(os.Stdin)
fmt.Print("Do you want to proceed (yes/no): ")

confirmation, err := reader.ReadString('\n')
if err != nil {
return false, err
}

fmt.Println()

return strings.Trim(confirmation, "\n") == yes, nil
}