Skip to content

Commit

Permalink
Add confirm flag to velero plugin add
Browse files Browse the repository at this point in the history
Signed-off-by: Tiger Kaovilai <[email protected]>
  • Loading branch information
kaovilai committed Mar 25, 2024
1 parent f1f7f04 commit 3c24365
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 39 deletions.
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 @@ limitations under the License.
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 @@ func (o *DeleteOptions) Validate(c *cobra.Command, f client.Factory, args []stri

// 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
}
}
}

0 comments on commit 3c24365

Please sign in to comment.