From 29be9df71245a81183729de9bb44afb5981d9d0e Mon Sep 17 00:00:00 2001 From: Marc Guasch Date: Fri, 3 Sep 2021 14:51:43 +0200 Subject: [PATCH] Add new join and sprintf functions (#27735) --- CHANGELOG.next.asciidoc | 1 + .../docs/inputs/input-httpjson.asciidoc | 2 + .../input/httpjson/internal/v2/value_tpl.go | 3 ++ .../httpjson/internal/v2/value_tpl_test.go | 40 +++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index a56130b776b..9847661fdb1 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -738,6 +738,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Move AWS module and filesets to GA. {pull}27428[27428] - update ecs.version to ECS 1.11.0. {pull}27107[27107] - Add base64 Encode functionality to httpjson input. {pull}27681[27681] +- Add `join` and `sprintf` functions to `httpjson` input. {pull}27735[27735] *Heartbeat* diff --git a/x-pack/filebeat/docs/inputs/input-httpjson.asciidoc b/x-pack/filebeat/docs/inputs/input-httpjson.asciidoc index 1e928773da2..f4a5dcf2091 100644 --- a/x-pack/filebeat/docs/inputs/input-httpjson.asciidoc +++ b/x-pack/filebeat/docs/inputs/input-httpjson.asciidoc @@ -206,6 +206,8 @@ Some built-in helper functions are provided to work with the input state inside - `hmac`: calculates the hmac signature of a list of strings concatenated together. Supports sha1 or sha256. Example `[[hmac "sha256" "secret" "string1" "string2" (formatDate (now) "RFC1123")]]` - `base64Encode`: Joins and base64 encodes all supplied strings. Example `[[base64Encode "string1" "string2"]]` - `base64EncodeNoPad`: Joins and base64 encodes all supplied strings without padding. Example `[[base64EncodeNoPad "string1" "string2"]]` +- `join`: joins a list of strings using the specified separator. Example: `[[join .body.arr ","]]` +- `sprintf`: formats according to a format specifier and returns the resulting string. Refer to https://pkg.go.dev/fmt#Sprintf[the Go docs] for usage. Example: `[[sprintf "%d:%q" 34 "quote this"]]` In addition to the provided functions, any of the native functions for https://golang.org/pkg/time/#Time[`time.Time`], https://golang.org/pkg/net/http/#Header[`http.Header`], and https://golang.org/pkg/net/url/#Values[`url.Values`] types can be used on the corresponding objects. Examples: `[[(now).Day]]`, `[[.last_response.header.Get "key"]]` diff --git a/x-pack/filebeat/input/httpjson/internal/v2/value_tpl.go b/x-pack/filebeat/input/httpjson/internal/v2/value_tpl.go index b6c74590b9d..9f91fcdccce 100644 --- a/x-pack/filebeat/input/httpjson/internal/v2/value_tpl.go +++ b/x-pack/filebeat/input/httpjson/internal/v2/value_tpl.go @@ -12,6 +12,7 @@ import ( "encoding/base64" "encoding/hex" "errors" + "fmt" "hash" "reflect" "regexp" @@ -57,6 +58,8 @@ func (t *valueTpl) Unpack(in string) error { "hmac": hmacString, "base64Encode": base64Encode, "base64EncodeNoPad": base64EncodeNoPad, + "join": strings.Join, + "sprintf": fmt.Sprintf, }). Delims(leftDelim, rightDelim). Parse(in) diff --git a/x-pack/filebeat/input/httpjson/internal/v2/value_tpl_test.go b/x-pack/filebeat/input/httpjson/internal/v2/value_tpl_test.go index 75f291b22be..4586dec7711 100644 --- a/x-pack/filebeat/input/httpjson/internal/v2/value_tpl_test.go +++ b/x-pack/filebeat/input/httpjson/internal/v2/value_tpl_test.go @@ -291,6 +291,46 @@ func TestValueTpl(t *testing.T) { expectedVal: "", expectedError: errEmptyTemplateResult.Error(), }, + { + name: "func join", + value: `[[join .last_response.body.arr ","]]`, + paramCtx: &transformContext{ + firstEvent: &common.MapStr{}, + lastEvent: &common.MapStr{}, + lastResponse: newTestResponse( + common.MapStr{ + "arr": []string{ + "foo", + "bar", + }, + }, + http.Header{}, + "", + ), + }, + paramTr: transformable{}, + expectedVal: "foo,bar", + }, + { + name: "func sprintf", + value: `[[sprintf "%q:%d" (join .last_response.body.arr ",") 1]]`, + paramCtx: &transformContext{ + firstEvent: &common.MapStr{}, + lastEvent: &common.MapStr{}, + lastResponse: newTestResponse( + common.MapStr{ + "arr": []string{ + "foo", + "bar", + }, + }, + http.Header{}, + "", + ), + }, + paramTr: transformable{}, + expectedVal: `"foo,bar":1`, + }, } for _, tc := range cases {