diff --git a/cmd/humioctl/actions_export.go b/cmd/humioctl/actions_export.go index d2686d3..962150a 100644 --- a/cmd/humioctl/actions_export.go +++ b/cmd/humioctl/actions_export.go @@ -15,6 +15,7 @@ package main import ( + "github.com/humio/cli/api" "os" "github.com/spf13/cobra" @@ -53,3 +54,42 @@ func newActionsExportCmd() *cobra.Command { return &cmd } + +func newActionsExportAllCmd() *cobra.Command { + var outputDirectory string + + cmd := cobra.Command{ + Use: "export-all ", + Short: "Export all actions", + Long: `Export all actions to yaml files with naming .yaml. All non-alphanumeric characters will be replaced with underscore.`, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + view := args[0] + client := NewApiClient(cmd) + + var actions []api.Action + actions, err := client.Actions().List(view) + exitOnError(cmd, err, "Error fetching actions") + + for _, action := range actions { + yamlData, err := yaml.Marshal(&action) + exitOnError(cmd, err, "Failed to serialize the action") + actionFilename := sanitizeTriggerName(action.Name) + ".yaml" + + var outFilePath string + if outputDirectory != "" { + outFilePath = outputDirectory + "/" + actionFilename + } else { + outFilePath = actionFilename + } + + err = os.WriteFile(outFilePath, yamlData, 0600) + exitOnError(cmd, err, "Error saving the action to file") + } + }, + } + + cmd.Flags().StringVarP(&outputDirectory, "outputDirectory", "d", "", "The file path where the actions should be written. Defaults to current directory.") + + return &cmd +} diff --git a/cmd/humioctl/aggregate_alerts.go b/cmd/humioctl/aggregate_alerts.go index f5d69c1..f9318f3 100644 --- a/cmd/humioctl/aggregate_alerts.go +++ b/cmd/humioctl/aggregate_alerts.go @@ -27,6 +27,7 @@ func newAggregateAlertsCmd() *cobra.Command { cmd.AddCommand(newAggregateAlertsListCmd()) cmd.AddCommand(newAggregateAlertsInstallCmd()) cmd.AddCommand(newAggregateAlertsExportCmd()) + cmd.AddCommand(newAggregateAlertsExportAllCmd()) cmd.AddCommand(newAggregateAlertsRemoveCmd()) cmd.AddCommand(newAggregateAlertsShowCmd()) diff --git a/cmd/humioctl/aggregate_alerts_export.go b/cmd/humioctl/aggregate_alerts_export.go index 14e4315..cf2db49 100644 --- a/cmd/humioctl/aggregate_alerts_export.go +++ b/cmd/humioctl/aggregate_alerts_export.go @@ -65,3 +65,42 @@ func newAggregateAlertsExportCmd() *cobra.Command { return &cmd } + +func newAggregateAlertsExportAllCmd() *cobra.Command { + var outputDirectory string + + cmd := cobra.Command{ + Use: "export-all ", + Short: "Export all aggregate alerts", + Long: `Export all aggregate alerts to yaml files with naming .yaml. All non-alphanumeric characters will be replaced with underscore.`, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + view := args[0] + client := NewApiClient(cmd) + + var aggregateAlerts []*api.AggregateAlert + aggregateAlerts, err := client.AggregateAlerts().List(view) + exitOnError(cmd, err, "Error fetching aggregate alerts") + + for _, aggregateAlert := range aggregateAlerts { + yamlData, err := yaml.Marshal(&aggregateAlert) + exitOnError(cmd, err, "Failed to serialize the aggregate alert") + alertFilename := sanitizeTriggerName(aggregateAlert.Name) + ".yaml" + + var outFilePath string + if outputDirectory != "" { + outFilePath = outputDirectory + "/" + alertFilename + } else { + outFilePath = alertFilename + } + + err = os.WriteFile(outFilePath, yamlData, 0600) + exitOnError(cmd, err, "Error saving the aggregate alert to file") + } + }, + } + + cmd.Flags().StringVarP(&outputDirectory, "outputDirectory", "d", "", "The file path where the aggregate alerts should be written. Defaults to current directory.") + + return &cmd +} diff --git a/cmd/humioctl/alerts.go b/cmd/humioctl/alerts.go index ec364d2..aec35e8 100644 --- a/cmd/humioctl/alerts.go +++ b/cmd/humioctl/alerts.go @@ -27,6 +27,7 @@ func newAlertsCmd() *cobra.Command { cmd.AddCommand(newAlertsListCmd()) cmd.AddCommand(newAlertsInstallCmd()) cmd.AddCommand(newAlertsExportCmd()) + cmd.AddCommand(newAlertsExportAllCmd()) cmd.AddCommand(newAlertsRemoveCmd()) cmd.AddCommand(newAlertsShowCmd()) diff --git a/cmd/humioctl/alerts_export.go b/cmd/humioctl/alerts_export.go index bf5781b..0ebc8bc 100644 --- a/cmd/humioctl/alerts_export.go +++ b/cmd/humioctl/alerts_export.go @@ -15,10 +15,10 @@ package main import ( - "os" - + "github.com/humio/cli/api" "github.com/spf13/cobra" "gopkg.in/yaml.v2" + "os" ) func newAlertsExportCmd() *cobra.Command { @@ -53,3 +53,42 @@ func newAlertsExportCmd() *cobra.Command { return &cmd } + +func newAlertsExportAllCmd() *cobra.Command { + var outputDirectory string + + cmd := cobra.Command{ + Use: "export-all ", + Short: "Export all alerts", + Long: `Export all alerts to yaml files with naming .yaml. All non-alphanumeric characters will be replaced with underscore.`, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + view := args[0] + client := NewApiClient(cmd) + + var alerts []api.Alert + alerts, err := client.Alerts().List(view) + exitOnError(cmd, err, "Error fetching alerts") + + for _, alert := range alerts { + yamlData, err := yaml.Marshal(&alert) + exitOnError(cmd, err, "Failed to serialize the alert") + alertFilename := sanitizeTriggerName(alert.Name) + ".yaml" + + var outFilePath string + if outputDirectory != "" { + outFilePath = outputDirectory + "/" + alertFilename + } else { + outFilePath = alertFilename + } + + err = os.WriteFile(outFilePath, yamlData, 0600) + exitOnError(cmd, err, "Error saving the alert to file") + } + }, + } + + cmd.Flags().StringVarP(&outputDirectory, "outputDirectory", "d", "", "The file path where the alerts should be written. Defaults to current directory.") + + return &cmd +} diff --git a/cmd/humioctl/filter_alerts.go b/cmd/humioctl/filter_alerts.go index f0500dc..8ef5962 100644 --- a/cmd/humioctl/filter_alerts.go +++ b/cmd/humioctl/filter_alerts.go @@ -27,6 +27,7 @@ func newFilterAlertsCmd() *cobra.Command { cmd.AddCommand(newFilterAlertsListCmd()) cmd.AddCommand(newFilterAlertsInstallCmd()) cmd.AddCommand(newFilterAlertsExportCmd()) + cmd.AddCommand(newFilterAlertsExportAllCmd()) cmd.AddCommand(newFilterAlertsRemoveCmd()) cmd.AddCommand(newFilterAlertsShowCmd()) diff --git a/cmd/humioctl/filter_alerts_export.go b/cmd/humioctl/filter_alerts_export.go index d83c1a5..e759e5c 100644 --- a/cmd/humioctl/filter_alerts_export.go +++ b/cmd/humioctl/filter_alerts_export.go @@ -65,3 +65,42 @@ func newFilterAlertsExportCmd() *cobra.Command { return &cmd } + +func newFilterAlertsExportAllCmd() *cobra.Command { + var outputDirectory string + + cmd := cobra.Command{ + Use: "export-all ", + Short: "Export all filter alerts", + Long: `Export all filter alerts to yaml files with naming .yaml. All non-alphanumeric characters will be replaced with underscore.`, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + view := args[0] + client := NewApiClient(cmd) + + var filterAlerts []api.FilterAlert + filterAlerts, err := client.FilterAlerts().List(view) + exitOnError(cmd, err, "Error fetching filter alerts") + + for _, filterAlert := range filterAlerts { + yamlData, err := yaml.Marshal(&filterAlert) + exitOnError(cmd, err, "Failed to serialize the filter alert") + filterAlertFilename := sanitizeTriggerName(filterAlert.Name) + ".yaml" + + var outFilePath string + if outputDirectory != "" { + outFilePath = outputDirectory + "/" + filterAlertFilename + } else { + outFilePath = filterAlertFilename + } + + err = os.WriteFile(outFilePath, yamlData, 0600) + exitOnError(cmd, err, "Error saving the filter alert to file") + } + }, + } + + cmd.Flags().StringVarP(&outputDirectory, "outputDirectory", "d", "", "The file path where the filter alerts should be written. Defaults to current directory.") + + return &cmd +} diff --git a/cmd/humioctl/scheduled_searches.go b/cmd/humioctl/scheduled_searches.go index 3486870..aafd57b 100644 --- a/cmd/humioctl/scheduled_searches.go +++ b/cmd/humioctl/scheduled_searches.go @@ -27,6 +27,7 @@ func newScheduledSearchesCmd() *cobra.Command { cmd.AddCommand(newScheduledSearchesListCmd()) cmd.AddCommand(newScheduledSearchesInstallCmd()) cmd.AddCommand(newScheduledSearchesExportCmd()) + cmd.AddCommand(newScheduledSearchesExportAllCmd()) cmd.AddCommand(newScheduledSearchesRemoveCmd()) cmd.AddCommand(newScheduledSearchesShowCmd()) diff --git a/cmd/humioctl/scheduled_searches_export.go b/cmd/humioctl/scheduled_searches_export.go index 9dcee50..92978df 100644 --- a/cmd/humioctl/scheduled_searches_export.go +++ b/cmd/humioctl/scheduled_searches_export.go @@ -65,3 +65,42 @@ func newScheduledSearchesExportCmd() *cobra.Command { return &cmd } + +func newScheduledSearchesExportAllCmd() *cobra.Command { + var outputDirectory string + + cmd := cobra.Command{ + Use: "export-all ", + Short: "Export all scheduled searches", + Long: `Export all scheduled searches to yaml files with naming .yaml.`, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + view := args[0] + client := NewApiClient(cmd) + + var scheduledSearches []api.ScheduledSearch + scheduledSearches, err := client.ScheduledSearches().List(view) + exitOnError(cmd, err, "Error fetching scheduled searches") + + for _, scheduledSearch := range scheduledSearches { + yamlData, err := yaml.Marshal(&scheduledSearch) + exitOnError(cmd, err, "Failed to serialize the scheduled search") + scheduledSearchFilename := sanitizeTriggerName(scheduledSearch.Name) + ".yaml" + + var outFilePath string + if outputDirectory != "" { + outFilePath = outputDirectory + "/" + scheduledSearchFilename + } else { + outFilePath = scheduledSearchFilename + } + + err = os.WriteFile(outFilePath, yamlData, 0600) + exitOnError(cmd, err, "Error saving the scheduled search to file") + } + }, + } + + cmd.Flags().StringVarP(&outputDirectory, "outputDirectory", "d", "", "The file path where the scheduled searches should be written. Defaults to current directory.") + + return &cmd +} diff --git a/cmd/humioctl/util.go b/cmd/humioctl/util.go index 319bf48..843a3b9 100644 --- a/cmd/humioctl/util.go +++ b/cmd/humioctl/util.go @@ -3,14 +3,14 @@ package main import ( "errors" "fmt" + "github.com/humio/cli/cmd/internal/format" + "github.com/spf13/cobra" "io" "net/http" "net/url" "os" + "regexp" "strconv" - - "github.com/humio/cli/cmd/internal/format" - "github.com/spf13/cobra" ) // GoReleaser will override these when building: https://goreleaser.com/customization/build/ @@ -158,3 +158,8 @@ func getBytesFromURL(url string) ([]byte, error) { }() return io.ReadAll(response.Body) } + +// Replaces all non-alphanumeric characters with underscore +func sanitizeTriggerName(name string) string { + return regexp.MustCompile(`[^a-zA-Z0-9]`).ReplaceAllString(name, "_") +}