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

Add confirm flag to velero plugin add #7566

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelogs/unreleased/7566-kaovilai
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add confirm flag to velero plugin add
3 changes: 2 additions & 1 deletion pkg/cmd/cli/backup/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/client"
"github.com/vmware-tanzu/velero/pkg/cmd"
"github.com/vmware-tanzu/velero/pkg/cmd/cli"
"github.com/vmware-tanzu/velero/pkg/cmd/util/confirm"
"github.com/vmware-tanzu/velero/pkg/label"
)

Expand Down Expand Up @@ -70,7 +71,7 @@ func NewDeleteCommand(f client.Factory, use string) *cobra.Command {

// Run performs the delete backup operation.
func Run(o *cli.DeleteOptions) error {
if !o.Confirm && !cli.GetConfirmation() {
if !o.Confirm && !confirm.GetConfirmation() {
// Don't do anything unless we get confirmation
return nil
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/cmd/cli/backuplocation/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/client"
"github.com/vmware-tanzu/velero/pkg/cmd"
"github.com/vmware-tanzu/velero/pkg/cmd/cli"
"github.com/vmware-tanzu/velero/pkg/cmd/util/confirm"
)

// NewDeleteCommand creates and returns a new cobra command for deleting backup-locations.
Expand Down Expand Up @@ -67,7 +68,7 @@ func NewDeleteCommand(f client.Factory, use string) *cobra.Command {

// Run performs the delete backup-location operation.
func Run(f client.Factory, o *cli.DeleteOptions) error {
if !o.Confirm && !cli.GetConfirmation() {
if !o.Confirm && !confirm.GetConfirmation() {
// Don't do anything unless we get confirmation
return nil
}
Expand Down
36 changes: 4 additions & 32 deletions pkg/cmd/cli/delete_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,27 @@
package cli

import (
"bufio"
"errors"
"fmt"
"os"
"strings"

"github.com/spf13/cobra"
"github.com/spf13/pflag"
controllerclient "sigs.k8s.io/controller-runtime/pkg/client"

"github.com/vmware-tanzu/velero/pkg/client"
"github.com/vmware-tanzu/velero/pkg/cmd/util/confirm"
)

// DeleteOptions contains parameters used for deleting a restore.
type DeleteOptions struct {
*SelectOptions
Confirm bool
confirm.ConfirmOptions
Client controllerclient.Client
Namespace string
}

func NewDeleteOptions(singularTypeName string) *DeleteOptions {
o := &DeleteOptions{}
o.ConfirmOptions = *confirm.NewConfirmOptionsWithDescription("Confirm deletion")

Check warning on line 40 in pkg/cmd/cli/delete_options.go

View check run for this annotation

Codecov / codecov/patch

pkg/cmd/cli/delete_options.go#L40

Added line #L40 was not covered by tests
o.SelectOptions = NewSelectOptions("delete", singularTypeName)
return o
}
Expand All @@ -66,36 +64,10 @@

// BindFlags binds options for this command to flags.
func (o *DeleteOptions) BindFlags(flags *pflag.FlagSet) {
flags.BoolVar(&o.Confirm, "confirm", o.Confirm, "Confirm deletion")
o.ConfirmOptions.BindFlags(flags)

Check warning on line 67 in pkg/cmd/cli/delete_options.go

View check run for this annotation

Codecov / codecov/patch

pkg/cmd/cli/delete_options.go#L67

Added line #L67 was not covered by tests
o.SelectOptions.BindFlags(flags)
}

// GetConfirmation ensures that the user confirms the action before proceeding.
func GetConfirmation() bool {
reader := bufio.NewReader(os.Stdin)

for {
fmt.Printf("Are you sure you want to continue (Y/N)? ")

confirmation, err := reader.ReadString('\n')
if err != nil {
fmt.Fprintf(os.Stderr, "error reading user input: %v\n", err)
return false
}
confirmation = strings.TrimSpace(confirmation)
if len(confirmation) != 1 {
continue
}

switch strings.ToLower(confirmation) {
case "y":
return true
case "n":
return false
}
}
}

// Xor returns true if exactly one of the provided values is true,
// or false otherwise.
func xor(val bool, vals ...bool) bool {
Expand Down
9 changes: 8 additions & 1 deletion pkg/cmd/cli/plugin/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/builder"
"github.com/vmware-tanzu/velero/pkg/client"
"github.com/vmware-tanzu/velero/pkg/cmd"
"github.com/vmware-tanzu/velero/pkg/cmd/util/confirm"
"github.com/vmware-tanzu/velero/pkg/cmd/util/flag"
)

Expand All @@ -45,12 +46,17 @@ func NewAddCommand(f client.Factory) *cobra.Command {
imagePullPolicies = []string{string(corev1api.PullAlways), string(corev1api.PullIfNotPresent), string(corev1api.PullNever)}
imagePullPolicyFlag = flag.NewEnum(string(corev1api.PullIfNotPresent), imagePullPolicies...)
)

o := confirm.NewConfirmOptionsWithDescription("Confirm add?, may cause the Velero server pod restart which will fail all ongoing jobs")
c := &cobra.Command{
Use: "add IMAGE",
Short: "Add a plugin",
Args: cobra.ExactArgs(1),
Run: func(c *cobra.Command, args []string) {
if !o.Confirm && !confirm.GetConfirmation("velero plugin add may cause the Velero server pod restart, so it is a dangerous operation",
"once Velero server restarts, all the ongoing jobs will fail.") {
// Don't do anything unless we get confirmation
return
}
kubeClient, err := f.KubeClient()
if err != nil {
cmd.CheckError(err)
Expand Down Expand Up @@ -122,6 +128,7 @@ func NewAddCommand(f client.Factory) *cobra.Command {
}

c.Flags().Var(imagePullPolicyFlag, "image-pull-policy", fmt.Sprintf("The imagePullPolicy for the plugin container. Valid values are %s.", strings.Join(imagePullPolicies, ", ")))
o.BindFlags(c.Flags())

return c
}
3 changes: 2 additions & 1 deletion pkg/cmd/cli/restore/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/client"
"github.com/vmware-tanzu/velero/pkg/cmd"
"github.com/vmware-tanzu/velero/pkg/cmd/cli"
"github.com/vmware-tanzu/velero/pkg/cmd/util/confirm"
)

// NewDeleteCommand creates and returns a new cobra command for deleting restores.
Expand Down Expand Up @@ -66,7 +67,7 @@ func NewDeleteCommand(f client.Factory, use string) *cobra.Command {

// Run performs the deletion of restore(s).
func Run(o *cli.DeleteOptions) error {
if !o.Confirm && !cli.GetConfirmation() {
if !o.Confirm && !confirm.GetConfirmation() {
return nil
}
var (
Expand Down
3 changes: 2 additions & 1 deletion pkg/cmd/cli/schedule/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/client"
"github.com/vmware-tanzu/velero/pkg/cmd"
"github.com/vmware-tanzu/velero/pkg/cmd/cli"
"github.com/vmware-tanzu/velero/pkg/cmd/util/confirm"
)

// NewDeleteCommand creates and returns a new cobra command for deleting schedules.
Expand Down Expand Up @@ -67,7 +68,7 @@ func NewDeleteCommand(f client.Factory, use string) *cobra.Command {

// Run performs the deletion of schedules.
func Run(o *cli.DeleteOptions) error {
if !o.Confirm && !cli.GetConfirmation() {
if !o.Confirm && !confirm.GetConfirmation() {
return nil
}
var (
Expand Down
4 changes: 2 additions & 2 deletions pkg/cmd/cli/uninstall/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import (
velerov2alpha1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
"github.com/vmware-tanzu/velero/pkg/client"
"github.com/vmware-tanzu/velero/pkg/cmd"
"github.com/vmware-tanzu/velero/pkg/cmd/cli"
"github.com/vmware-tanzu/velero/pkg/cmd/util/confirm"
"github.com/vmware-tanzu/velero/pkg/controller"
"github.com/vmware-tanzu/velero/pkg/install"
kubeutil "github.com/vmware-tanzu/velero/pkg/util/kube"
Expand Down Expand Up @@ -88,7 +88,7 @@ Use '--force' to skip the prompt confirming if you want to uninstall Velero.
// Confirm if not asked to force-skip confirmation
if !o.force {
fmt.Println("You are about to uninstall Velero.")
if !cli.GetConfirmation() {
if !confirm.GetConfirmation() {
// Don't do anything unless we get confirmation
return
}
Expand Down
57 changes: 57 additions & 0 deletions pkg/cmd/util/confirm/confirm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package confirm

import (
"bufio"
"fmt"
"os"
"strings"

"github.com/spf13/pflag"
)

type ConfirmOptions struct {
Confirm bool
flagDescription string
}

func NewConfirmOptions() *ConfirmOptions {
return &ConfirmOptions{flagDescription: "Confirm action"}
}

func NewConfirmOptionsWithDescription(desc string) *ConfirmOptions {
return &ConfirmOptions{flagDescription: desc}
}

// Bind confirm flags.
func (o *ConfirmOptions) BindFlags(flags *pflag.FlagSet) {
flags.BoolVar(&o.Confirm, "confirm", o.Confirm, o.flagDescription)
}

// GetConfirmation ensures that the user confirms the action before proceeding.
func GetConfirmation(prompts ...string) bool {
reader := bufio.NewReader(os.Stdin)

for {
for i := range prompts {
fmt.Println(prompts[i])
}
fmt.Printf("Are you sure you want to continue (Y/N)? ")

confirmation, err := reader.ReadString('\n')
if err != nil {
fmt.Fprintf(os.Stderr, "error reading user input: %v\n", err)
return false
}
confirmation = strings.TrimSpace(confirmation)
if len(confirmation) != 1 {
continue
}

switch strings.ToLower(confirmation) {
case "y":
return true
case "n":
return false
}
}
}
Loading