diff --git a/cmd/dashboard.go b/cmd/dashboard.go index 4ad7d091..d3758b6b 100644 --- a/cmd/dashboard.go +++ b/cmd/dashboard.go @@ -4,12 +4,17 @@ import ( "fmt" "github.com/esnet/gdg/internal/apphelpers" "github.com/esnet/gdg/internal/service" + "github.com/esnet/gdg/internal/tools" "github.com/jedib0t/go-pretty/v6/table" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "strings" ) +var ( + skipConfirmAction bool +) + func parseDashboardGlobalFlags(cmd *cobra.Command) []string { folderFilter, _ := cmd.Flags().GetString("folder") dashboardFilter, _ := cmd.Flags().GetString("dashboard") @@ -56,6 +61,13 @@ var uploadDashboard = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { filter := service.NewDashboardFilter(parseDashboardGlobalFlags(cmd)...) + + if !skipConfirmAction { + tools.GetUserConfirmation(fmt.Sprintf("WARNING: this will delete all dashboards from the monitored folders: '%s' "+ + "(or all folders if ignore_dashboard_filters is set to true) and upload your local copy. Do you wish to "+ + "continue (y/n) ", strings.Join(apphelpers.GetCtxDefaultGrafanaConfig().GetMonitoredFolders(), ", "), + ), "", true) + } grafanaSvc.ExportDashboards(filter) tableObj.AppendHeader(table.Row{"Title", "id", "folder", "UID"}) @@ -120,6 +132,7 @@ var listDashboards = &cobra.Command{ func init() { rootCmd.AddCommand(dashboard) + dashboard.PersistentFlags().BoolVarP(&skipConfirmAction, "skip-confirmation", "", false, "when set to true, bypass confirmation prompts") dashboard.PersistentFlags().StringP("dashboard", "d", "", "filter by dashboard slug") dashboard.PersistentFlags().StringP("folder", "f", "", "Filter by Folder Name (Quotes in names not supported)") dashboard.PersistentFlags().StringSliceP("tags", "t", []string{}, "Filter by Tags (does not apply on upload)") diff --git a/internal/tools/prompt_helpers.go b/internal/tools/prompt_helpers.go new file mode 100644 index 00000000..6c8d756f --- /dev/null +++ b/internal/tools/prompt_helpers.go @@ -0,0 +1,42 @@ +package tools + +import ( + "bufio" + "fmt" + log "github.com/sirupsen/logrus" + "golang.org/x/exp/slices" + "os" + "strings" +) + +var validResponse = []rune{'y', 'n'} + +// GetUserConfirmation prompts user to confirm operation +// msg Message to prompt the user with +// validate returns true/false on success or terminates the process +// msg: prompt to display to the user asking for a response. +// error: error message to display if app should terminate +// terminate: when set to true will terminate the app user response is not valid. +func GetUserConfirmation(msg, error string, terminate bool) bool { + if error == "" { + error = "Goodbye" + } + for { + fmt.Printf(msg) + r := bufio.NewReader(os.Stdin) + ans, _ := r.ReadString('\n') + ans = strings.ToLower(ans) + if !slices.Contains(validResponse, rune(ans[0])) { + log.Error("Invalid response, please try again. Only [yes/no] are supported") + continue + } + //Validate Response + if ans[0] != 'y' && terminate { + log.Fatal(error) + } else if ans[0] != 'y' { + return false + } + return true + } + +}