Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic serverless support for elasticsearch, beats index management #36587

Merged
merged 13 commits into from
Sep 20, 2023
Merged
24 changes: 12 additions & 12 deletions NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12712,11 +12712,11 @@ SOFTWARE

--------------------------------------------------------------------------------
Dependency : github.com/elastic/elastic-agent-libs
Version: v0.3.13
Version: v0.3.15-0.20230913212237-dbdaf18c898b
Licence type (autodetected): Apache-2.0
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/github.com/elastic/[email protected].13/LICENSE:
Contents of probable licence file $GOMODCACHE/github.com/elastic/[email protected].15-0.20230913212237-dbdaf18c898b/LICENSE:

Apache License
Version 2.0, January 2004
Expand Down Expand Up @@ -24620,11 +24620,11 @@ Contents of probable licence file $GOMODCACHE/go.mongodb.org/[email protected]

--------------------------------------------------------------------------------
Dependency : go.uber.org/atomic
Version: v1.10.0
Version: v1.11.0
Licence type (autodetected): MIT
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/go.uber.org/atomic@v1.10.0/LICENSE.txt:
Contents of probable licence file $GOMODCACHE/go.uber.org/atomic@v1.11.0/LICENSE.txt:

Copyright (c) 2016 Uber Technologies, Inc.

Expand All @@ -24649,11 +24649,11 @@ THE SOFTWARE.

--------------------------------------------------------------------------------
Dependency : go.uber.org/multierr
Version: v1.10.0
Version: v1.11.0
Licence type (autodetected): MIT
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/go.uber.org/multierr@v1.10.0/LICENSE.txt:
Contents of probable licence file $GOMODCACHE/go.uber.org/multierr@v1.11.0/LICENSE.txt:

Copyright (c) 2017-2021 Uber Technologies, Inc.

Expand All @@ -24678,11 +24678,11 @@ THE SOFTWARE.

--------------------------------------------------------------------------------
Dependency : go.uber.org/zap
Version: v1.24.0
Version: v1.25.0
Licence type (autodetected): MIT
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/go.uber.org/zap@v1.24.0/LICENSE.txt:
Contents of probable licence file $GOMODCACHE/go.uber.org/zap@v1.25.0/LICENSE.txt:

Copyright (c) 2016-2017 Uber Technologies, Inc.

Expand Down Expand Up @@ -34072,11 +34072,11 @@ Contents of probable licence file $GOMODCACHE/github.com/aws/aws-sdk-go-v2/servi

--------------------------------------------------------------------------------
Dependency : github.com/benbjohnson/clock
Version: v1.1.0
Version: v1.3.0
Licence type (autodetected): MIT
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/github.com/benbjohnson/clock@v1.1.0/LICENSE:
Contents of probable licence file $GOMODCACHE/github.com/benbjohnson/clock@v1.3.0/LICENSE:

The MIT License (MIT)

Expand Down Expand Up @@ -49952,11 +49952,11 @@ Contents of probable licence file $GOMODCACHE/[email protected]/LICENSE:

--------------------------------------------------------------------------------
Dependency : go.uber.org/goleak
Version: v1.1.12
Version: v1.2.0
Licence type (autodetected): MIT
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/go.uber.org/goleak@v1.1.12/LICENSE:
Contents of probable licence file $GOMODCACHE/go.uber.org/goleak@v1.2.0/LICENSE:

The MIT License (MIT)

Expand Down
9 changes: 5 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ require (
go.elastic.co/ecszap v1.0.1
go.elastic.co/go-licence-detector v0.6.0
go.etcd.io/bbolt v1.3.6
go.uber.org/atomic v1.10.0
go.uber.org/multierr v1.10.0
go.uber.org/zap v1.24.0
go.uber.org/atomic v1.11.0
go.uber.org/multierr v1.11.0
go.uber.org/zap v1.25.0
golang.org/x/crypto v0.12.0
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616
golang.org/x/mod v0.9.0
Expand Down Expand Up @@ -202,7 +202,7 @@ require (
github.com/awslabs/kinesis-aggregation/go/v2 v2.0.0-20220623125934-28468a6701b5
github.com/elastic/bayeux v1.0.5
github.com/elastic/elastic-agent-autodiscover v0.6.2
github.com/elastic/elastic-agent-libs v0.3.13
github.com/elastic/elastic-agent-libs v0.3.15-0.20230913212237-dbdaf18c898b
github.com/elastic/elastic-agent-shipper-client v0.5.1-0.20230228231646-f04347b666f3
github.com/elastic/elastic-agent-system-metrics v0.6.1
github.com/elastic/go-elasticsearch/v8 v8.9.0
Expand Down Expand Up @@ -402,6 +402,7 @@ replace (
github.com/snowflakedb/gosnowflake => github.com/snowflakedb/gosnowflake v1.6.19
github.com/tonistiigi/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c
k8s.io/kubernetes v1.13.0 => k8s.io/kubernetes v1.24.15

)

// Exclude this version because the version has an invalid checksum.
Expand Down
20 changes: 10 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,8 @@ github.com/awslabs/goformation/v4 v4.1.0 h1:JRxIW0IjhYpYDrIZOTJGMu2azXKI+OK5dP56
github.com/awslabs/goformation/v4 v4.1.0/go.mod h1:MBDN7u1lMNDoehbFuO4uPvgwPeolTMA2TzX1yO6KlxI=
github.com/awslabs/kinesis-aggregation/go/v2 v2.0.0-20220623125934-28468a6701b5 h1:lxW5Q6K2IisyF5tlr6Ts0W4POGWQZco05MJjFmoeIHs=
github.com/awslabs/kinesis-aggregation/go/v2 v2.0.0-20220623125934-28468a6701b5/go.mod h1:0Qr1uMHFmHsIYMcG4T7BJ9yrJtWadhOmpABCX69dwuc=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/benbjohnson/immutable v0.2.1/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI=
github.com/benbjohnson/tmpl v1.0.0/go.mod h1:igT620JFIi44B6awvU9IsDhR77IXWtFigTLil/RPdps=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
Expand Down Expand Up @@ -653,8 +653,8 @@ github.com/elastic/elastic-agent-autodiscover v0.6.2 h1:7P3cbMBWXjbzA80rxitQjc+P
github.com/elastic/elastic-agent-autodiscover v0.6.2/go.mod h1:yXYKFAG+Py+TcE4CCR8EAbJiYb+6Dz9sCDoWgOveqtU=
github.com/elastic/elastic-agent-client/v7 v7.3.0 h1:LugKtBXK7bp4SFL/uQqGU/f4Ppx12Jk5a36voGabLa0=
github.com/elastic/elastic-agent-client/v7 v7.3.0/go.mod h1:9/amG2K2y2oqx39zURcc+hnqcX+nyJ1cZrLgzsgo5c0=
github.com/elastic/elastic-agent-libs v0.3.13 h1:qFiBWeBfjsBId+i31rggyW2ZjzA9qBRz7wIiy+rkcvc=
github.com/elastic/elastic-agent-libs v0.3.13/go.mod h1:mpSfrigixx8x+uMxWKl4LtdlrKIhZbA4yT2eIeIazUQ=
github.com/elastic/elastic-agent-libs v0.3.15-0.20230913212237-dbdaf18c898b h1:a2iuOokwld+D7VhyFymVtsPoqxZ8fkkOCOOjeYU9CDM=
github.com/elastic/elastic-agent-libs v0.3.15-0.20230913212237-dbdaf18c898b/go.mod h1:mpSfrigixx8x+uMxWKl4LtdlrKIhZbA4yT2eIeIazUQ=
github.com/elastic/elastic-agent-shipper-client v0.5.1-0.20230228231646-f04347b666f3 h1:sb+25XJn/JcC9/VL8HX4r4QXSUq4uTNzGS2kxOE7u1U=
github.com/elastic/elastic-agent-shipper-client v0.5.1-0.20230228231646-f04347b666f3/go.mod h1:rWarFM7qYxJKsi9WcV6ONcFjH/NA3niDNpTxO+8/GVI=
github.com/elastic/elastic-agent-system-metrics v0.6.1 h1:LCN1lvQTkdUuU/rKlpKyVMDU/G/I8/iZWCaW6K+mo4o=
Expand Down Expand Up @@ -1947,29 +1947,29 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.8.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180505025534-4ec37c66abab/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
Expand Down
13 changes: 13 additions & 0 deletions libbeat/cmd/instance/beat.go
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,19 @@ func (b *Beat) Setup(settings Settings, bt beat.Creator, setup SetupSettings) er
return err
}

// other components know to skip ILM setup under serverless, this logic block just helps us print an error message
// in instances where ILM has been explicitly enabled
var ilmCfg struct {
Ilm *config.C `config:"setup.ilm"`
}
err = b.RawConfig.Unpack(&ilmCfg)
if err != nil {
return fmt.Errorf("error unpacking ILM config: %w", err)
}
if ilmCfg.Ilm.Enabled() && esClient.IsServerless() {
fmt.Println("WARNING: ILM is not supported under serverless")
fearful-symmetry marked this conversation as resolved.
Show resolved Hide resolved
}

loadTemplate, loadILM := idxmgmt.LoadModeUnset, idxmgmt.LoadModeUnset
if setup.IndexManagement || setup.Template {
loadTemplate = idxmgmt.LoadModeOverwrite
Expand Down
30 changes: 10 additions & 20 deletions libbeat/dashboards/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
package dashboards

import (
"bytes"
"fmt"
"net/http"
"strings"

"github.com/elastic/elastic-agent-libs/kibana"
Expand All @@ -38,32 +38,22 @@ func Get(client *kibana.Client, id string) ([]byte, error) {
return nil, fmt.Errorf("Kibana version must be at least " + MinimumRequiredVersionSavedObjects.String())
}

// add a special header for serverless, where saved_objects is "hidden"
headers := http.Header{}
if serverless, _ := client.KibanaIsServerless(); serverless {
headers.Add("x-elastic-internal-origin", "libbeat")
}

body := fmt.Sprintf(`{"objects": [{"type": "dashboard", "id": "%s" }], "includeReferencesDeep": true, "excludeExportDetails": true}`, id)
statusCode, response, err := client.Request("POST", "/api/saved_objects/_export", nil, nil, strings.NewReader(body))
statusCode, response, err := client.Request("POST", "/api/saved_objects/_export", nil, headers, strings.NewReader(body))
if err != nil || statusCode >= 300 {
return nil, fmt.Errorf("error exporting dashboard: %+v, code: %d", err, statusCode)
return nil, fmt.Errorf("error exporting dashboard: %w, code: %d", err, statusCode)
}

result, err := RemoveIndexPattern(response)
if err != nil {
return nil, fmt.Errorf("error removing index pattern: %+v", err)
return nil, fmt.Errorf("error removing index pattern: %w", err)
}

return result, nil
}

// truncateString returns a truncated string if the length is greater than 250
// runes. If the string is truncated "... (truncated)" is appended. Newlines are
// replaced by spaces in the returned string.
//
// This function is useful for logging raw HTTP responses with errors when those
// responses can be very large (such as an HTML page with CSS content).
func truncateString(b []byte) string {
const maxLength = 250
runes := bytes.Runes(b)
if len(runes) > maxLength {
runes = append(runes[:maxLength], []rune("... (truncated)")...)
}

return strings.Replace(string(runes), "\n", " ", -1)
}
32 changes: 17 additions & 15 deletions libbeat/dashboards/kibana_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ var (
// developers migrate their dashboards we are more lenient.
minimumRequiredVersionSavedObjects = version.MustNew("7.14.0")

// the base path of the saved objects API
// On serverless, you must add an x-elastic-internal-header to reach this API
importAPI = "/api/saved_objects/_import"
)

Expand All @@ -58,14 +60,13 @@ type KibanaLoader struct {

// NewKibanaLoader creates a new loader to load Kibana files
func NewKibanaLoader(ctx context.Context, cfg *config.C, dashboardsConfig *Config, hostname string, msgOutputter MessageOutputter, beatname string) (*KibanaLoader, error) {

if cfg == nil || !cfg.Enabled() {
return nil, fmt.Errorf("Kibana is not configured or enabled")
return nil, fmt.Errorf("kibana is not configured or enabled")
fearful-symmetry marked this conversation as resolved.
Show resolved Hide resolved
}

client, err := getKibanaClient(ctx, cfg, dashboardsConfig.Retry, 0, beatname)
if err != nil {
return nil, fmt.Errorf("Error creating Kibana client: %v", err)
return nil, fmt.Errorf("Error creating Kibana client: %w", err)
}

loader := KibanaLoader{
Expand Down Expand Up @@ -95,7 +96,7 @@ func getKibanaClient(ctx context.Context, cfg *config.C, retryCfg *Retry, retryA
return getKibanaClient(ctx, cfg, retryCfg, retryAttempt+1, beatname)
}
}
return nil, fmt.Errorf("Error creating Kibana client: %v", err)
return nil, fmt.Errorf("Error creating Kibana client: %w", err)
}
return client, nil
}
Expand All @@ -111,13 +112,13 @@ func (loader KibanaLoader) ImportIndexFile(file string) error {
// read json file
reader, err := ioutil.ReadFile(file)
if err != nil {
return fmt.Errorf("fail to read index-pattern from file %s: %v", file, err)
return fmt.Errorf("fail to read index-pattern from file %s: %w", file, err)
}

var indexContent mapstr.M
err = json.Unmarshal(reader, &indexContent)
if err != nil {
return fmt.Errorf("fail to unmarshal the index content from file %s: %v", file, err)
return fmt.Errorf("fail to unmarshal the index content from file %s: %w", file, err)
}

return loader.ImportIndex(indexContent)
Expand All @@ -126,7 +127,7 @@ func (loader KibanaLoader) ImportIndexFile(file string) error {
// ImportIndex imports the passed index pattern to Kibana
func (loader KibanaLoader) ImportIndex(pattern mapstr.M) error {
if loader.version.LessThan(minimumRequiredVersionSavedObjects) {
return fmt.Errorf("Kibana version must be at least " + minimumRequiredVersionSavedObjects.String())
return fmt.Errorf("kibana version must be at least " + minimumRequiredVersionSavedObjects.String())
fearful-symmetry marked this conversation as resolved.
Show resolved Hide resolved
}

var errs multierror.Errors
Expand All @@ -138,7 +139,8 @@ func (loader KibanaLoader) ImportIndex(pattern mapstr.M) error {
errs = append(errs, fmt.Errorf("error setting index '%s' in index pattern: %w", loader.config.Index, err))
}

if err := loader.client.ImportMultiPartFormFile(importAPI, params, "index-template.ndjson", pattern.String()); err != nil {
err := loader.client.ImportMultiPartFormFile(importAPI, params, "index-template.ndjson", pattern.String())
if err != nil {
errs = append(errs, fmt.Errorf("error loading index pattern: %w", err))
}
return errs.Err()
Expand All @@ -158,18 +160,18 @@ func (loader KibanaLoader) ImportDashboard(file string) error {
// read json file
content, err := ioutil.ReadFile(file)
if err != nil {
return fmt.Errorf("fail to read dashboard from file %s: %v", file, err)
return fmt.Errorf("fail to read dashboard from file %s: %w", file, err)
}

content = loader.formatDashboardAssets(content)

dashboardWithReferences, err := loader.addReferences(file, content)
if err != nil {
return fmt.Errorf("error getting references of dashboard: %+v", err)
return fmt.Errorf("error getting references of dashboard: %w", err)
}

if err := loader.client.ImportMultiPartFormFile(importAPI, params, correctExtension(file), dashboardWithReferences); err != nil {
return fmt.Errorf("error dashboard asset: %+v", err)
return fmt.Errorf("error dashboard asset: %w", err)
}

loader.loadedAssets[file] = true
Expand All @@ -188,7 +190,7 @@ func (loader KibanaLoader) addReferences(path string, dashboard []byte) (string,
var d dashboardObj
err := json.Unmarshal(dashboard, &d)
if err != nil {
return "", fmt.Errorf("failed to parse dashboard references: %+v", err)
return "", fmt.Errorf("failed to parse dashboard references: %w", err)
}

base := filepath.Dir(path)
Expand All @@ -203,12 +205,12 @@ func (loader KibanaLoader) addReferences(path string, dashboard []byte) (string,
}
refContents, err := ioutil.ReadFile(referencePath)
if err != nil {
return "", fmt.Errorf("fail to read referenced asset from file %s: %v", referencePath, err)
return "", fmt.Errorf("fail to read referenced asset from file %s: %w", referencePath, err)
}
refContents = loader.formatDashboardAssets(refContents)
refContentsWithReferences, err := loader.addReferences(referencePath, refContents)
if err != nil {
return "", fmt.Errorf("failed to get references of %s: %+v", referencePath, err)
return "", fmt.Errorf("failed to get references of %s: %w", referencePath, err)
}

result += refContentsWithReferences
Expand All @@ -218,7 +220,7 @@ func (loader KibanaLoader) addReferences(path string, dashboard []byte) (string,
var res mapstr.M
err = json.Unmarshal(dashboard, &res)
if err != nil {
return "", fmt.Errorf("failed to convert asset: %+v", err)
return "", fmt.Errorf("failed to convert asset: %w", err)
}
result += res.String() + "\n"

Expand Down
Loading
Loading