From 25a674350c819180c477217f87dd387105eb9468 Mon Sep 17 00:00:00 2001 From: Mike Rostermund Date: Wed, 1 Nov 2023 11:11:44 +0100 Subject: [PATCH] Mike/view connection types (#141) * api accepts slice of connection strings * also modify Views.Create() * also update `views create` * views: Expose ViewConnectionInput type directly in the Create/Update API and update humioctl to use it --------- Co-authored-by: Brian Derr --- api/views.go | 28 ++++------------------------ cmd/humioctl/views_create.go | 31 ++++++++++++++++++++++++++----- cmd/humioctl/views_update.go | 34 +++++++++++++++++++++++++++------- 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/api/views.go b/api/views.go index 11f2e00..966be27 100644 --- a/api/views.go +++ b/api/views.go @@ -90,7 +90,7 @@ type ViewConnectionInput struct { Filter graphql.String `json:"filter"` } -func (c *Views) Create(name, description string, connections map[string]string) error { +func (c *Views) Create(name, description string, connections []ViewConnectionInput) error { var mutation struct { CreateView struct { Name string @@ -98,20 +98,10 @@ func (c *Views) Create(name, description string, connections map[string]string) } `graphql:"createView(name: $name, description: $description, connections: $connections)"` } - var viewConnections []ViewConnectionInput - for k, v := range connections { - viewConnections = append( - viewConnections, - ViewConnectionInput{ - RepositoryName: graphql.String(k), - Filter: graphql.String(v), - }) - } - variables := map[string]interface{}{ "name": graphql.String(name), "description": graphql.String(description), - "connections": viewConnections, + "connections": connections, } return c.client.Mutate(&mutation, variables) @@ -132,26 +122,16 @@ func (c *Views) Delete(name, reason string) error { return c.client.Mutate(&mutation, variables) } -func (c *Views) UpdateConnections(name string, connections map[string]string) error { +func (c *Views) UpdateConnections(name string, connections []ViewConnectionInput) error { var mutation struct { View struct { Name string } `graphql:"updateView(viewName: $viewName, connections: $connections)"` } - var viewConnections []ViewConnectionInput - for k, v := range connections { - viewConnections = append( - viewConnections, - ViewConnectionInput{ - RepositoryName: graphql.String(k), - Filter: graphql.String(v), - }) - } - variables := map[string]interface{}{ "viewName": graphql.String(name), - "connections": viewConnections, + "connections": connections, } return c.client.Mutate(&mutation, variables) diff --git a/cmd/humioctl/views_create.go b/cmd/humioctl/views_create.go index d89ec79..59aaa2b 100644 --- a/cmd/humioctl/views_create.go +++ b/cmd/humioctl/views_create.go @@ -16,12 +16,16 @@ package main import ( "fmt" + graphql "github.com/cli/shurcooL-graphql" + "github.com/humio/cli/api" + "strings" "github.com/spf13/cobra" ) func newViewsCreateCmd() *cobra.Command { - connections := make(map[string]string) + connsFlag := []string{} + connections := []api.ViewConnectionInput{} description := "" cmd := &cobra.Command{ @@ -33,20 +37,37 @@ The "description" flag is a string, and the "connections" flag is a comma-separa where the key is the repository name and the value being the filter applied to the queries in that repository. If you want to query all events you can specify a wildcard as the filter. -Here's an example that updates a view named "important-view" to search all data in the two repositories, +Here's an example that creates a view named "important-view" to search all data in the two repositories, namely "repo1" and "repo2": - $ humioctl views update important-view --connection "repo1=*,repo2=*" --description "very important view" + $ humioctl views create important-view --connection "repo1=*" --connection "repo2=*" --description "very important view" `, Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { viewName := args[0] client := NewApiClient(cmd) - if len(connections) == 0 { + if len(connsFlag) == 0 { exitOnError(cmd, fmt.Errorf("you must specify at least view connection"), "Error creating view") } + for _, v := range connsFlag { + parts := strings.SplitN(v, "=", 2) + if len(parts) != 2 { + exitOnError(cmd, fmt.Errorf("all connections must follow the format: ="), "Error updating view connections") + } + + repo := parts[0] + filter := parts[1] + + connections = append( + connections, + api.ViewConnectionInput{ + RepositoryName: graphql.String(repo), + Filter: graphql.String(filter), + }) + } + err := client.Views().Create(viewName, description, connections) exitOnError(cmd, err, "Error creating view") @@ -54,7 +75,7 @@ namely "repo1" and "repo2": }, } - cmd.Flags().StringToStringVar(&connections, "connection", connections, "Sets a repository connection with the chosen filter.") + cmd.Flags().StringArrayVar(&connsFlag, "connection", connsFlag, "Sets a repository connection with the chosen filter in format: =") cmd.Flags().StringVar(&description, "description", description, "Sets an optional description") return cmd diff --git a/cmd/humioctl/views_update.go b/cmd/humioctl/views_update.go index 0993346..fc2fbac 100644 --- a/cmd/humioctl/views_update.go +++ b/cmd/humioctl/views_update.go @@ -16,12 +16,17 @@ package main import ( "fmt" + "strings" + "github.com/humio/cli/api" + + graphql "github.com/cli/shurcooL-graphql" "github.com/spf13/cobra" ) func newViewsUpdateCmd() *cobra.Command { - connections := make(map[string]string) + connsFlag := []string{} + connections := []api.ViewConnectionInput{} description := "" cmd := cobra.Command{ @@ -29,25 +34,40 @@ func newViewsUpdateCmd() *cobra.Command { Short: "Updates the settings of a view", Long: `Updates the settings of a view with the provided arguments. -The "description" flag is a string, and the "connections" flag is a comma-separated list of key-value pairs -where the key is the repository name and the value being the filter applied to the queries in that repository. +The "description" flag can be specified multiple times for adding multiple connections to the view. If you want to query all events you can specify a wildcard as the filter. Here's an example that updates a view named "important-view" to search all data in the two repositories, namely "repo1" and "repo2": - $ humioctl views update important-view --connection "repo1=*,repo2=*" --description "very important view" + $ humioctl views update important-view --connection "repo1=*" --connection="repo2=*" --description "very important view" `, Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { viewName := args[0] client := NewApiClient(cmd) - if len(connections) == 0 && description == "" { + if len(connsFlag) == 0 && description == "" { exitOnError(cmd, fmt.Errorf("you must specify at least one flag"), "Nothing specified to update") } - if len(connections) > 0 { + if len(connsFlag) > 0 { + for _, v := range connsFlag { + parts := strings.SplitN(v, "=", 2) + if len(parts) != 2 { + exitOnError(cmd, fmt.Errorf("all connections must follow the format: ="), "Error updating view connections") + } + + repo := parts[0] + filter := parts[1] + + connections = append( + connections, + api.ViewConnectionInput{ + RepositoryName: graphql.String(repo), + Filter: graphql.String(filter), + }) + } err := client.Views().UpdateConnections(viewName, connections) exitOnError(cmd, err, "Error updating view connections") } @@ -61,7 +81,7 @@ namely "repo1" and "repo2": }, } - cmd.Flags().StringToStringVar(&connections, "connection", connections, "Sets a repository connection with the chosen filter.") + cmd.Flags().StringArrayVar(&connsFlag, "connection", connsFlag, "Sets a repository connection with the chosen filter in format: =") cmd.Flags().StringVar(&description, "description", description, "Sets the view description.") return &cmd