From 9e8588345ccb1ba4d18281f8a816207c1446e060 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 15 Feb 2023 09:49:13 -0600 Subject: [PATCH] Allow specifying output file name. (#148) * Allow specifying output file name for Eck-diagnostics output file. Signed-off-by: Michael Montgomery --- cmd/main.go | 55 +++++++++++++++++++++++++++++--- internal/diag.go | 13 ++------ internal/filters/filters_test.go | 1 - 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 5a033e7..cee4081 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -8,6 +8,7 @@ import ( "fmt" "log" "os" + "path/filepath" "time" "github.com/elastic/eck-diagnostics/internal" @@ -15,6 +16,11 @@ import ( "github.com/spf13/cobra" ) +const ( + operatorNamespaces = "operator-namespaces" + resourcesNamespaces = "resources-namespaces" +) + var ( filters []string diagParams = internal.Params{} @@ -25,7 +31,7 @@ func main() { Use: "eck-diagnostics", Short: "ECK support diagnostics tool", Long: "Dump ECK and Kubernetes data for support and troubleshooting purposes.", - PreRunE: parseFilters, + PreRunE: preRunOperations, Version: internal.Version(), RunE: func(cmd *cobra.Command, args []string) error { return internal.Run(diagParams) @@ -34,16 +40,17 @@ func main() { cmd.Flags().StringVar(&diagParams.DiagnosticImage, "diagnostic-image", internal.DiagnosticImage, "Diagnostic image to be used for stack diagnostics, see run-stack-diagnostics") cmd.Flags().BoolVar(&diagParams.RunStackDiagnostics, "run-stack-diagnostics", true, "Run diagnostics on deployed Elasticsearch clusters and Kibana instances, requires deploying diagnostic Pods into the cluster") cmd.Flags().BoolVar(&diagParams.RunAgentDiagnostics, "run-agent-diagnostics", false, "Run diagnostics on deployed Elastic Agents. Warning: credentials will not be redacted and appear as plain text in the archive") - cmd.Flags().StringSliceVarP(&diagParams.OperatorNamespaces, "operator-namespaces", "o", []string{"elastic-system"}, "Comma-separated list of namespace(s) in which operator(s) are running") - cmd.Flags().StringSliceVarP(&diagParams.ResourcesNamespaces, "resources-namespaces", "r", nil, "Comma-separated list of namespace(s) in which resources are managed") + cmd.Flags().StringSliceVarP(&diagParams.OperatorNamespaces, operatorNamespaces, "o", []string{"elastic-system"}, "Comma-separated list of namespace(s) in which operator(s) are running") + cmd.Flags().StringSliceVarP(&diagParams.ResourcesNamespaces, resourcesNamespaces, "r", nil, "Comma-separated list of namespace(s) in which resources are managed") cmd.Flags().StringSliceVarP(&filters, "filters", "f", nil, fmt.Sprintf(`Comma-separated list of filters in format "type=name". ex: elasticsearch=my-cluster (Supported types %v)`, internal_filters.ValidTypes)) cmd.Flags().StringVar(&diagParams.ECKVersion, "eck-version", "", "ECK version in use, will try to autodetect if not specified") cmd.Flags().StringVar(&diagParams.OutputDir, "output-directory", "", "Path where to output diagnostic results") + cmd.Flags().StringVarP(&diagParams.OutputName, "output-name", "n", fmt.Sprintf("eck-diagnostics-%s.zip", time.Now().Format("2006-01-02T15-04-05")), "Name of the output diagnostics file") cmd.Flags().StringVar(&diagParams.Kubeconfig, "kubeconfig", "", "optional path to kube config, defaults to $HOME/.kube/config") cmd.Flags().BoolVar(&diagParams.Verbose, "verbose", false, "Verbose mode") cmd.Flags().DurationVar(&diagParams.StackDiagnosticsTimeout, "stack-diagnostics-timeout", 5*time.Minute, "Maximum time to wait for Elaticsearch and Kibana diagnostics to complete") - if err := cmd.MarkFlagRequired("resources-namespaces"); err != nil { + if err := cmd.MarkFlagRequired(resourcesNamespaces); err != nil { exitWithError(err) } @@ -53,6 +60,46 @@ func main() { } } +func preRunOperations(cmd *cobra.Command, args []string) error { + if err := validation(cmd, args); err != nil { + return err + } + return parseFilters(cmd, args) +} + +func validation(_ *cobra.Command, _ []string) error { + if diagParams.OutputName == "" { + return fmt.Errorf("output-name cannot be empty") + } + if filepath.Ext(diagParams.OutputName) != ".zip" { + return fmt.Errorf("output-name extension must end in '.zip'") + } + + type validations struct { + namespaces []string + name string + } + for _, v := range []validations{ + { + namespaces: diagParams.OperatorNamespaces, + name: operatorNamespaces, + }, { + namespaces: diagParams.ResourcesNamespaces, + name: resourcesNamespaces, + }, + } { + if len(v.namespaces) == 0 { + return fmt.Errorf("%s is a required parameter", v.name) + } + for _, ns := range v.namespaces { + if ns == "" { + return fmt.Errorf("%s cannot be an empty string", v.name) + } + } + } + return nil +} + func parseFilters(_ *cobra.Command, _ []string) error { filters, err := internal_filters.New(filters) if err != nil { diff --git a/internal/diag.go b/internal/diag.go index 3a13f18..f8ad651 100644 --- a/internal/diag.go +++ b/internal/diag.go @@ -7,7 +7,6 @@ package internal import ( "bytes" "context" - "fmt" "io" "os" "os/signal" @@ -35,6 +34,7 @@ type Params struct { OperatorNamespaces []string ResourcesNamespaces []string OutputDir string + OutputName string RunStackDiagnostics bool RunAgentDiagnostics bool Verbose bool @@ -77,7 +77,7 @@ func Run(params Params) error { return err } - zipFileName := diagnosticFilename(params.OutputDir) + zipFileName := filepath.Join(params.OutputDir, params.OutputName) zipFile, err := archive.NewZipFile(zipFileName, about().Version, logger) if err != nil { return err @@ -266,12 +266,3 @@ func getResources(f func(string, string, filters.Filters, io.Writer) error, ns s } return m } - -// diagnosticFilename calculates a file name to be used for the diagnostic archive based on the current time. -func diagnosticFilename(dir string) string { - file := fmt.Sprintf("eck-diagnostic-%s.zip", time.Now().Format("2006-01-02T15-04-05")) - if dir != "" { - file = filepath.Join(dir, file) - } - return file -} diff --git a/internal/filters/filters_test.go b/internal/filters/filters_test.go index 4591cd3..9a16145 100644 --- a/internal/filters/filters_test.go +++ b/internal/filters/filters_test.go @@ -170,7 +170,6 @@ func TestNew(t *testing.T) { if !reflect.DeepEqual(got, tt.want) { t.Errorf("New() = diff: %s", cmp.Diff(got, tt.want)) } - }) } }