diff --git a/internal/kibana/dashboards.go b/internal/kibana/dashboards.go index 38988a94c..0d8d4de8b 100644 --- a/internal/kibana/dashboards.go +++ b/internal/kibana/dashboards.go @@ -5,12 +5,15 @@ package kibana import ( + "bytes" "encoding/json" "errors" "fmt" "net/http" "strings" + "github.com/Masterminds/semver/v3" + "github.com/elastic/elastic-package/internal/common" "github.com/elastic/elastic-package/internal/logger" "github.com/elastic/elastic-package/internal/multierror" @@ -20,8 +23,68 @@ type exportedType struct { Objects []common.MapStr `json:"objects"` } -// Export method exports selected dashboards using the Kibana Export API. +// Export method exports selected dashboards using the Kibana APIs. func (c *Client) Export(dashboardIDs []string) ([]common.MapStr, error) { + if c.semver.LessThan(semver.MustParse("8.11.0")) { + return c.exportWithDashboardsAPI(dashboardIDs) + } + + return c.exportWithSavedObjectsAPI(dashboardIDs) +} + +type exportSavedObjectsRequest struct { + ExcludeExportDetails bool `json:"excludeExportDetails"` + IncludeReferencesDeep bool `json:"includeReferencesDeep"` + Objects []exportSavedObjectsRequestObject `json:"objects"` +} + +type exportSavedObjectsRequestObject struct { + ID string `json:"id"` + Type string `json:"type"` +} + +func (c *Client) exportWithSavedObjectsAPI(dashboardIDs []string) ([]common.MapStr, error) { + logger.Debug("Export dashboards using the Kibana Saved Objects Export API") + + exportRequest := exportSavedObjectsRequest{ + ExcludeExportDetails: true, + IncludeReferencesDeep: true, + } + for _, dashboardID := range dashboardIDs { + exportRequest.Objects = append(exportRequest.Objects, exportSavedObjectsRequestObject{ + ID: dashboardID, + Type: "dashboard", + }) + } + + body, err := json.Marshal(exportRequest) + if err != nil { + return nil, err + } + + path := SavedObjectsAPI + "/_export" + statusCode, respBody, err := c.SendRequest(http.MethodPost, path, body) + if err != nil { + return nil, fmt.Errorf("could not export dashboards; API status code = %d; response body = %s: %w", statusCode, respBody, err) + } + + var dashboards []common.MapStr + decoder := json.NewDecoder(bytes.NewReader(respBody)) + + for decoder.More() { + var dashboard common.MapStr + err := decoder.Decode(&dashboard) + if err != nil { + return nil, fmt.Errorf("unmarshalling response failed (body: \n%s): %w", respBody, err) + } + + dashboards = append(dashboards, dashboard) + } + + return dashboards, nil +} + +func (c *Client) exportWithDashboardsAPI(dashboardIDs []string) ([]common.MapStr, error) { logger.Debug("Export dashboards using the Kibana Export API") var query strings.Builder