From b3abad44bb789a5b9b2f7e55b57e205b3c778605 Mon Sep 17 00:00:00 2001 From: Mike Rostermund Date: Fri, 31 May 2024 10:33:52 +0200 Subject: [PATCH] Use parsers v2 API --- api/internal/humiographql/parsers.go | 44 +++++++++++++++ api/parsers.go | 82 ++++++++++++++++------------ cmd/humioctl/parsers.go | 1 + cmd/humioctl/parsers_get.go | 35 ++++++++++++ cmd/humioctl/parsers_install.go | 6 +- cmd/humioctl/parsers_remove.go | 2 +- 6 files changed, 130 insertions(+), 40 deletions(-) create mode 100644 api/internal/humiographql/parsers.go create mode 100644 cmd/humioctl/parsers_get.go diff --git a/api/internal/humiographql/parsers.go b/api/internal/humiographql/parsers.go new file mode 100644 index 00000000..4c3e051f --- /dev/null +++ b/api/internal/humiographql/parsers.go @@ -0,0 +1,44 @@ +package humiographql + +type ParserTestEventInput struct { + RawString string `graphql:"rawString"` +} + +type FieldHasValueInput struct { + FieldName string `graphql:"fieldName"` + ExpectedValue string `graphql:"expectedValue"` +} + +type ParserTestCaseOutputAssertionsInput struct { + FieldsNotPresent []string `graphql:"fieldsNotPresent"` + FieldsHaveValues []FieldHasValueInput `graphql:"fieldsHaveValues"` +} + +type ParserTestCaseAssertionsForOutputInput struct { + OutputEventIndex int `graphql:"outputEventIndex"` + Assertions ParserTestCaseOutputAssertionsInput `graphql:"assertions"` +} + +type ParserTestCaseInput struct { + Event ParserTestEventInput `graphql:"event"` + OutputAssertions []ParserTestCaseAssertionsForOutputInput `graphql:"outputAssertions"` +} + +type ParserTestEvent struct { + RawString string `graphql:"rawString"` +} + +type ParserTestCaseOutputAssertions struct { + FieldsNotPresent []string `graphql:"fieldsNotPresent"` + FieldsHaveValues []FieldHasValueInput `graphql:"fieldsHaveValues"` +} + +type ParserTestCaseAssertionsForOutput struct { + OutputEventIndex int `graphql:"outputEventIndex"` + Assertions ParserTestCaseOutputAssertions `graphql:"assertions"` +} + +type ParserTestCase struct { + Event ParserTestEvent `graphql:"event"` + OutputAssertions []ParserTestCaseAssertionsForOutput `graphql:"outputAssertions"` +} diff --git a/api/parsers.go b/api/parsers.go index cf82a29f..a617f2d9 100644 --- a/api/parsers.go +++ b/api/parsers.go @@ -1,19 +1,18 @@ package api -import graphql "github.com/cli/shurcooL-graphql" - -type ParserTestCase struct { - Input string - Output map[string]string -} +import ( + graphql "github.com/cli/shurcooL-graphql" + "github.com/humio/cli/api/internal/humiographql" +) type Parser struct { - ID string - Name string - Tests []string `yaml:",omitempty"` - Example string `yaml:",omitempty"` - Script string `yaml:",flow"` - TagFields []string `yaml:",omitempty"` + ID string + Name string + Tests []string `yaml:",omitempty"` + Example string `yaml:",omitempty"` + Script string `yaml:",flow"` + TagFields []string `yaml:",omitempty"` + FieldsToBeRemovedBeforeParsing []string `yaml:",omitempty"` } type Parsers struct { @@ -47,12 +46,12 @@ func (p *Parsers) List(repositoryName string) ([]ParserListItem, error) { return parsers, err } -func (p *Parsers) Remove(repositoryName string, parserName string) error { +func (p *Parsers) Delete(repositoryName string, parserName string) error { var mutation struct { - RemoveParser struct { + DeleteParser struct { // We have to make a selection, so just take __typename Typename graphql.String `graphql:"__typename"` - } `graphql:"removeParser(input: { id: $id, repositoryName: $repositoryName })"` + } `graphql:"deleteParser(input: { id: $id, repositoryName: $repositoryName })"` } parser, err := p.client.Parsers().Get(repositoryName, parserName) @@ -68,34 +67,41 @@ func (p *Parsers) Remove(repositoryName string, parserName string) error { return p.client.Mutate(&mutation, variables) } -func (p *Parsers) Add(repositoryName string, parser *Parser, force bool) error { +func (p *Parsers) Add(repositoryName string, parser *Parser, allowOverwritingExistingParser bool) error { var mutation struct { CreateParser struct { // We have to make a selection, so just take __typename Typename graphql.String `graphql:"__typename"` - } `graphql:"createParser(input: { name: $name, repositoryName: $repositoryName, testData: $testData, tagFields: $tagFields, sourceCode: $sourceCode, force: $force})"` + } `graphql:"createParserV2(input: { name: $name, repositoryName: $repositoryName, testCases: $testCases, fieldsToTag: $fieldsToTag, fieldsToBeRemovedBeforeParsing: $fieldsToBeRemovedBeforeParsing, script: $script, allowOverwritingExistingParser: $allowOverwritingExistingParser})"` } - tagFieldsGQL := make([]graphql.String, len(parser.TagFields)) - + fieldsToTagGQL := make([]graphql.String, len(parser.TagFields)) for i, field := range parser.TagFields { - tagFieldsGQL[i] = graphql.String(field) + fieldsToTagGQL[i] = graphql.String(field) } - testsGQL := make([]graphql.String, len(parser.Tests)) + fieldsToBeRemovedBeforeParsingGQL := make([]graphql.String, len(parser.FieldsToBeRemovedBeforeParsing)) + for i, field := range parser.FieldsToBeRemovedBeforeParsing { + fieldsToBeRemovedBeforeParsingGQL[i] = graphql.String(field) + } + testCasesGQL := make([]humiographql.ParserTestCaseInput, len(parser.Tests)) for i, field := range parser.Tests { - testsGQL[i] = graphql.String(field) + testCasesGQL[i] = humiographql.ParserTestCaseInput{ + Event: humiographql.ParserTestEventInput{RawString: field}, + OutputAssertions: []humiographql.ParserTestCaseAssertionsForOutputInput{}, + } } variables := map[string]interface{}{ - "name": graphql.String(parser.Name), - "sourceCode": graphql.String(parser.Script), - "repositoryName": graphql.String(repositoryName), - "testData": testsGQL, - "tagFields": tagFieldsGQL, - "force": graphql.Boolean(force), + "name": graphql.String(parser.Name), + "script": graphql.String(parser.Script), + "repositoryName": humiographql.RepoOrViewName(repositoryName), + "testCases": testCasesGQL, + "fieldsToTag": fieldsToTagGQL, + "fieldsToBeRemovedBeforeParsing": fieldsToBeRemovedBeforeParsingGQL, + "allowOverwritingExistingParser": graphql.Boolean(allowOverwritingExistingParser), } return p.client.Mutate(&mutation, variables) @@ -105,11 +111,11 @@ func (p *Parsers) Get(repositoryName string, parserName string) (*Parser, error) var query struct { Repository struct { Parser *struct { - ID string - Name string - SourceCode string - TestData []string - TagFields []string + ID string + Name string + Script string + TestCases []humiographql.ParserTestCase + FieldsToTag []string } `graphql:"parser(name: $parserName)"` } `graphql:"repository(name: $repositoryName)"` } @@ -128,12 +134,16 @@ func (p *Parsers) Get(repositoryName string, parserName string) (*Parser, error) return nil, ParserNotFound(parserName) } + tests := make([]string, len(query.Repository.Parser.TestCases)) + for i := range query.Repository.Parser.TestCases { + tests[i] = query.Repository.Parser.TestCases[i].Event.RawString + } parser := Parser{ ID: query.Repository.Parser.ID, Name: query.Repository.Parser.Name, - Tests: query.Repository.Parser.TestData, - Script: query.Repository.Parser.SourceCode, - TagFields: query.Repository.Parser.TagFields, + Tests: tests, + Script: query.Repository.Parser.Script, + TagFields: query.Repository.Parser.FieldsToTag, } return &parser, nil diff --git a/cmd/humioctl/parsers.go b/cmd/humioctl/parsers.go index 21eb1c25..827386dc 100644 --- a/cmd/humioctl/parsers.go +++ b/cmd/humioctl/parsers.go @@ -28,6 +28,7 @@ func newParsersCmd() *cobra.Command { cmd.AddCommand(newParsersListCmd()) cmd.AddCommand(newParsersRemoveCmd()) cmd.AddCommand(newParsersExportCmd()) + cmd.AddCommand(newParsersShowCmd()) return cmd } diff --git a/cmd/humioctl/parsers_get.go b/cmd/humioctl/parsers_get.go new file mode 100644 index 00000000..6aaf7870 --- /dev/null +++ b/cmd/humioctl/parsers_get.go @@ -0,0 +1,35 @@ +package main + +import ( + "github.com/humio/cli/cmd/internal/format" + "github.com/spf13/cobra" + "strings" +) + +func newParsersShowCmd() *cobra.Command { + cmd := cobra.Command{ + Use: "show ", + Short: "Show details for a parser in a repository.", + Args: cobra.ExactArgs(2), + Run: func(cmd *cobra.Command, args []string) { + repoName := args[0] + parserName := args[1] + client := NewApiClient(cmd) + + parser, err := client.Parsers().Get(repoName, parserName) + exitOnError(cmd, err, "Error fetching parser") + + details := [][]format.Value{ + {format.String("ID"), format.String(parser.ID)}, + {format.String("Name"), format.String(parser.Name)}, + {format.String("Script"), format.String(parser.Script)}, + {format.String("TagFields"), format.String(strings.Join(parser.TagFields, "\n"))}, + {format.String("TestCases"), format.String(strings.Join(parser.Tests, "\n"))}, + } + + printDetailsTable(cmd, details) + }, + } + + return &cmd +} diff --git a/cmd/humioctl/parsers_install.go b/cmd/humioctl/parsers_install.go index 654b08b8..8ba49d41 100644 --- a/cmd/humioctl/parsers_install.go +++ b/cmd/humioctl/parsers_install.go @@ -25,7 +25,7 @@ import ( ) func newParsersInstallCmd() *cobra.Command { - var force bool + var allowOverwritingExistingParser bool var filePath, url, name string cmd := cobra.Command{ @@ -70,12 +70,12 @@ Use the --force flag to update existing parsers with conflicting names. parser.Name = name } - err = client.Parsers().Add(repositoryName, &parser, force) + err = client.Parsers().Add(repositoryName, &parser, allowOverwritingExistingParser) exitOnError(cmd, err, "Error installing parser") }, } - cmd.Flags().BoolVarP(&force, "force", "f", false, "Overrides any parser with the same name. This can be used for updating parser that are already installed. (See --name)") + cmd.Flags().BoolVar(&allowOverwritingExistingParser, "allow-overwriting-existing-parser", false, "Overrides any parser with the same name. This can be used for updating parser that are already installed. (See --name)") cmd.Flags().StringVar(&filePath, "file", "", "The local file path to the parser to install.") cmd.Flags().StringVar(&url, "url", "", "A URL to fetch the parser file from.") cmd.Flags().StringVarP(&name, "name", "n", "", "Install the parser under a specific name, ignoring the `name` attribute in the parser file.") diff --git a/cmd/humioctl/parsers_remove.go b/cmd/humioctl/parsers_remove.go index 4f137e73..66122ea1 100644 --- a/cmd/humioctl/parsers_remove.go +++ b/cmd/humioctl/parsers_remove.go @@ -30,7 +30,7 @@ func newParsersRemoveCmd() *cobra.Command { parser := args[1] client := NewApiClient(cmd) - err := client.Parsers().Remove(repo, parser) + err := client.Parsers().Delete(repo, parser) exitOnError(cmd, err, "Error removing parser") fmt.Fprintf(cmd.OutOrStdout(), "Successfully removed parser %q from repository %q\n", parser, repo)