Skip to content

Commit

Permalink
use promptui for displaying prompt
Browse files Browse the repository at this point in the history
Signed-off-by: Somtochi Onyekwere <[email protected]>
  • Loading branch information
somtochiama committed Oct 24, 2023
1 parent 605151f commit 131a8b6
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 100 deletions.
2 changes: 1 addition & 1 deletion cmd/flux/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func init() {

bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.commitMessageAppendix, "commit-message-appendix", "", "string to add to the commit messages, e.g. '[ci skip]'")

bootstrapCmd.PersistentFlags().BoolVarP(&bootstrapArgs.force, "force", "f", false, "overwrite existing Flux installation on the cluster")
bootstrapCmd.PersistentFlags().BoolVar(&bootstrapArgs.force, "force", false, "overwrite existing Flux installation on the cluster")
bootstrapCmd.PersistentFlags().MarkHidden("manifests")

rootCmd.AddCommand(bootstrapCmd)
Expand Down
6 changes: 5 additions & 1 deletion cmd/flux/bootstrap_bitbucket_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (

"github.com/fluxcd/pkg/git"
"github.com/fluxcd/pkg/git/gogit"
"github.com/manifoldco/promptui"
"github.com/spf13/cobra"

"github.com/fluxcd/flux2/v2/internal/flags"
Expand Down Expand Up @@ -130,8 +131,11 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("cluster info unavailable: %w", err)
}

err = confirmFluxInstallOverride(os.Stdin, info)
err = confirmFluxInstallOverride(info)
if err != nil {
if err == promptui.ErrAbort {
return fmt.Errorf("bootstrap cancelled")
}
return err
}
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/flux/bootstrap_git.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("cluster info unavailable: %w", err)
}

err = confirmFluxInstallOverride(os.Stdin, info)
err = confirmFluxInstallOverride(info)
if err != nil {
return err
}
Expand Down
6 changes: 5 additions & 1 deletion cmd/flux/bootstrap_github.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (

"github.com/fluxcd/pkg/git"
"github.com/fluxcd/pkg/git/gogit"
"github.com/manifoldco/promptui"
"github.com/spf13/cobra"

"github.com/fluxcd/flux2/v2/internal/flags"
Expand Down Expand Up @@ -133,8 +134,11 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("cluster info unavailable: %w", err)
}
if !bootstrapArgs.force {
err := confirmFluxInstallOverride(os.Stdin, info)
err := confirmFluxInstallOverride(info)
if err != nil {
if err == promptui.ErrAbort {
return fmt.Errorf("bootstrap cancelled")
}
return err
}
}
Expand Down
6 changes: 5 additions & 1 deletion cmd/flux/bootstrap_gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (

"github.com/fluxcd/pkg/git"
"github.com/fluxcd/pkg/git/gogit"
"github.com/manifoldco/promptui"
"github.com/spf13/cobra"

"github.com/fluxcd/flux2/v2/internal/flags"
Expand Down Expand Up @@ -151,8 +152,11 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("cluster info unavailable: %w", err)
}

err = confirmFluxInstallOverride(os.Stdin, info)
err = confirmFluxInstallOverride(info)
if err != nil {
if err == promptui.ErrAbort {
return fmt.Errorf("bootstrap cancelled")
}
return err
}
}
Expand Down
34 changes: 11 additions & 23 deletions cmd/flux/cluster_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@ limitations under the License.
package main

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

"github.com/manifoldco/promptui"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -52,10 +49,6 @@ type fluxClusterInfo struct {
version string
}

// ErrInstallCancelled is an error that indicates the user cancelled a Flux installation
// to prevent overriding an existing one.
var ErrInstallCancelled = fmt.Errorf("install cancelled")

// getFluxClusterInfo returns information on the Flux installation running on the cluster.
// If an error occurred, the returned error will be non-nil.
//
Expand Down Expand Up @@ -97,26 +90,21 @@ func getFluxClusterInfo(ctx context.Context, c client.Client) (fluxClusterInfo,
}

// confirmFluxInstallOverride displays a prompt to the user so that they can confirm before overriding
// a Flux installation. It reads a response from the io.Reader and returns nil if the installation should continue,
// ErrInstallCancelled if the user doesn't confirm, or an error encountered.
func confirmFluxInstallOverride(reader io.Reader, info fluxClusterInfo) error {
var overridePrompt = `Flux %[1]s has been installed on this cluster with %[2]s!
Are you sure you want to proceed with overriding the %[2]s installation? Y/N: `

// a Flux installation. It returns nil if the installation should continue,
// promptui.ErrAbort if the user doesn't confirm, or an error encountered.
func confirmFluxInstallOverride(info fluxClusterInfo) error {
// no need to display prompt if flux is not installed or installation is
// managed by Flux
if !info.installed || info.managedBy == "" || info.managedBy == "flux" {
return nil
}

fmt.Fprintf(os.Stdout, fmt.Sprintf(overridePrompt, info.version, info.managedBy))
ans, err := bufio.NewReader(reader).ReadString('\n')
if err != nil {
return fmt.Errorf("could not read from stdin: %w", err)
}
ans = strings.TrimRight(ans, "\r\n")
if ans == "Y" {
return nil
display := fmt.Sprintf("Flux %[1]s has been installed on this cluster with %s", info.version, info.managedBy)
fmt.Fprintln(rootCmd.ErrOrStderr(), display)
prompt := promptui.Prompt{
Label: fmt.Sprintf("Are you sure you want to override the %s installation? Y/N", info.managedBy),
IsConfirm: true,
}
return ErrInstallCancelled
_, err := prompt.Run()
return err
}
70 changes: 0 additions & 70 deletions cmd/flux/cluster_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"context"
"fmt"
"os"
"strings"
"testing"

. "github.com/onsi/gomega"
Expand Down Expand Up @@ -132,72 +131,3 @@ func Test_getFluxClusterInfo(t *testing.T) {
})
}
}

func Test_confirmFluxInstallOverride(t *testing.T) {

tests := []struct {
name string
input string
info fluxClusterInfo
wantErr error
}{
{
name: "Flux not installed",
wantErr: nil,
},
{
name: "Installation managed by flux - empty manager",
info: fluxClusterInfo{
installed: true,
},
},
{
name: "Installation managed by different manager - confirm override",
input: "Y\n",
info: fluxClusterInfo{
version: "v2.1.0",
installed: true,
managedBy: "helm",
},
},
{
name: "Installation managed by different manager - deny override",
input: "no\n",
info: fluxClusterInfo{
version: "v2.1.0",
managedBy: "helm",
installed: true,
},
wantErr: ErrInstallCancelled,
},
{
name: "Installation managed by different manager - unspecified input",
input: "no\n",
info: fluxClusterInfo{
version: "v2.1.0",
managedBy: "helm",
installed: true,
},
wantErr: ErrInstallCancelled,
},
}

// suppress output to stdout during tests
stdout := os.Stdout
os.Stdout, _ = os.Open(os.DevNull)
t.Cleanup(func() {
os.Stdout = stdout
})
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
err := confirmFluxInstallOverride(strings.NewReader(tt.input), tt.info)
if tt.wantErr == nil {
g.Expect(err).To(BeNil())
} else {
g.Expect(err).To(Not(BeNil()))
g.Expect(err).To(BeEquivalentTo(tt.wantErr))
}
})
}
}
8 changes: 6 additions & 2 deletions cmd/flux/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"path/filepath"
"time"

"github.com/manifoldco/promptui"
"github.com/spf13/cobra"

"github.com/fluxcd/flux2/v2/internal/flags"
Expand Down Expand Up @@ -99,7 +100,7 @@ func init() {
installCmd.Flags().StringVar(&installArgs.clusterDomain, "cluster-domain", rootArgs.defaults.ClusterDomain, "internal cluster domain")
installCmd.Flags().StringSliceVar(&installArgs.tolerationKeys, "toleration-keys", nil,
"list of toleration keys used to schedule the components pods onto nodes with matching taints")
installCmd.Flags().BoolVarP(&installArgs.force, "force", "f", false, "overwrite existing Flux installation on the cluster")
installCmd.Flags().BoolVar(&installArgs.force, "force", false, "overwrite existing Flux installation on the cluster")
installCmd.Flags().MarkHidden("manifests")

rootCmd.AddCommand(installCmd)
Expand Down Expand Up @@ -201,8 +202,11 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
}

if !installArgs.force {
err := confirmFluxInstallOverride(os.Stdin, info)
err := confirmFluxInstallOverride(info)
if err != nil {
if err == promptui.ErrAbort {
return fmt.Errorf("bootstrap cancelled")
}
return err
}
}
Expand Down

0 comments on commit 131a8b6

Please sign in to comment.