diff --git a/elasticsearchdashboard/api.go b/elasticsearchdashboard/api.go index 4cd9b552b..d48282918 100644 --- a/elasticsearchdashboard/api.go +++ b/elasticsearchdashboard/api.go @@ -23,6 +23,7 @@ import ( type EDClient interface { GetHealthStatus() (*Health, error) GetStateFromHealthResponse(health *Health) (esapi.DashboardServerState, error) - ExportSavedObjects() (*Response, error) - ImportSavedObjects(filepath string) (*Response, error) + ExportSavedObjects(spaceName string) (*Response, error) + ImportSavedObjects(spaceName, filepath string) (*Response, error) + ListSpaces() ([]string, error) } diff --git a/elasticsearchdashboard/client.go b/elasticsearchdashboard/client.go index ffea20b9c..f5ce08cb7 100644 --- a/elasticsearchdashboard/client.go +++ b/elasticsearchdashboard/client.go @@ -33,10 +33,11 @@ const ( SavedObjectsReqBodyES = `{"type": ["dashboard", "config", "index-pattern", "url", "query", "tag", "canvas-element", "canvas-workpad", "action", "alert", "visualization", "graph-workspace", "map", "lens", "cases", "search", "osquery-saved-query", "osquery-pack", "uptime-dynamic-settings", "infrastructure-ui-source", "metrics-explorer-view", "inventory-view", "apm-indices"]}` - SavedObjectsReqBodyOS = `{"type": ["config", "url", "index-pattern", "query", "dashboard", "visualization", "visualization-visbuilder", "augment-vis", "map", -"observability-panel", "observability-visualization", "search"]}` + SavedObjectsReqBodyOS = `{"type": ["config", "url", "index-pattern", "query", "dashboard", "visualization", "visualization-visbuilder", "map", "observability-panel", +"observability-visualization", "search"]}` SavedObjectsExportURL = "/api/saved_objects/_export" SavedObjectsImportURL = "/api/saved_objects/_import" + ListSpacesURL = "/api/spaces/space" ) type Client struct { diff --git a/elasticsearchdashboard/ed_client_v7.go b/elasticsearchdashboard/ed_client_v7.go index 91dda15e9..0eedd9566 100644 --- a/elasticsearchdashboard/ed_client_v7.go +++ b/elasticsearchdashboard/ed_client_v7.go @@ -18,7 +18,9 @@ package elasticsearchdashboard import ( "encoding/json" + "fmt" "io" + "net/http" "strings" esapi "kubedb.dev/apimachinery/apis/elasticsearch/v1alpha1" @@ -107,7 +109,7 @@ func (h *EDClientV7) GetStateFromHealthResponse(health *Health) (esapi.Dashboard return esapi.DashboardServerState(health.OverallState), nil } -func (h *EDClientV7) ExportSavedObjects() (*Response, error) { +func (h *EDClientV7) ExportSavedObjects(spaceName string) (*Response, error) { req := h.Client.R(). SetDoNotParseResponse(true). SetHeaders(map[string]string{ @@ -115,7 +117,7 @@ func (h *EDClientV7) ExportSavedObjects() (*Response, error) { "kbn-xsrf": "true", }). SetBody([]byte(SavedObjectsReqBodyES)) - res, err := req.Post(SavedObjectsExportURL) + res, err := req.Post("/s/" + spaceName + SavedObjectsExportURL) if err != nil { klog.Error(err, "Failed to send http request") return nil, err @@ -127,13 +129,13 @@ func (h *EDClientV7) ExportSavedObjects() (*Response, error) { }, nil } -func (h *EDClientV7) ImportSavedObjects(filepath string) (*Response, error) { +func (h *EDClientV7) ImportSavedObjects(spaceName, filepath string) (*Response, error) { req := h.Client.R(). SetDoNotParseResponse(true). SetHeader("kbn-xsrf", "true"). SetFile("file", filepath). SetQueryParam("overwrite", "true") - res, err := req.Post(SavedObjectsImportURL) + res, err := req.Post("/s/" + spaceName + SavedObjectsImportURL) if err != nil { klog.Error(err, "Failed to send http request") return nil, err @@ -144,3 +146,38 @@ func (h *EDClientV7) ImportSavedObjects(filepath string) (*Response, error) { Body: res.RawBody(), }, nil } + +func (h *EDClientV7) ListSpaces() ([]string, error) { + req := h.Client.R(). + SetDoNotParseResponse(true). + SetHeaders(map[string]string{ + "Content-Type": "application/json", + "kbn-xsrf": "true", + }) + res, err := req.Get(ListSpacesURL) + if err != nil { + klog.Error("Failed to send http request") + return nil, err + } + + body, err := io.ReadAll(res.RawBody()) + if err != nil { + return nil, err + } + + if res.StatusCode() != http.StatusOK { + return nil, fmt.Errorf("failed to list dashboard spaces %s", string(body)) + } + + var spaces []map[string]interface{} + if err = json.Unmarshal(body, &spaces); err != nil { + return nil, err + } + + var spacesName []string + for _, space := range spaces { + spacesName = append(spacesName, space["id"].(string)) + } + + return spacesName, nil +} diff --git a/elasticsearchdashboard/ed_client_v8.go b/elasticsearchdashboard/ed_client_v8.go index f2a47fdd8..551cf07c4 100644 --- a/elasticsearchdashboard/ed_client_v8.go +++ b/elasticsearchdashboard/ed_client_v8.go @@ -18,7 +18,9 @@ package elasticsearchdashboard import ( "encoding/json" + "fmt" "io" + "net/http" "strings" esapi "kubedb.dev/apimachinery/apis/elasticsearch/v1alpha1" @@ -105,7 +107,7 @@ func (h *EDClientV8) GetStateFromHealthResponse(health *Health) (esapi.Dashboard return esapi.DashboardServerState(health.OverallState), nil } -func (h *EDClientV8) ExportSavedObjects() (*Response, error) { +func (h *EDClientV8) ExportSavedObjects(spaceName string) (*Response, error) { req := h.Client.R(). SetDoNotParseResponse(true). SetHeaders(map[string]string{ @@ -113,7 +115,7 @@ func (h *EDClientV8) ExportSavedObjects() (*Response, error) { "kbn-xsrf": "true", }). SetBody([]byte(SavedObjectsReqBodyES)) - res, err := req.Post(SavedObjectsExportURL) + res, err := req.Post("/s/" + spaceName + SavedObjectsExportURL) if err != nil { klog.Error(err, "Failed to send http request") return nil, err @@ -125,13 +127,13 @@ func (h *EDClientV8) ExportSavedObjects() (*Response, error) { }, nil } -func (h *EDClientV8) ImportSavedObjects(filepath string) (*Response, error) { +func (h *EDClientV8) ImportSavedObjects(spaceName, filepath string) (*Response, error) { req := h.Client.R(). SetDoNotParseResponse(true). SetHeader("kbn-xsrf", "true"). SetFile("file", filepath). SetQueryParam("overwrite", "true") - res, err := req.Post(SavedObjectsImportURL) + res, err := req.Post("/s/" + spaceName + SavedObjectsImportURL) if err != nil { klog.Error(err, "Failed to send http request") return nil, err @@ -142,3 +144,38 @@ func (h *EDClientV8) ImportSavedObjects(filepath string) (*Response, error) { Body: res.RawBody(), }, nil } + +func (h *EDClientV8) ListSpaces() ([]string, error) { + req := h.Client.R(). + SetDoNotParseResponse(true). + SetHeaders(map[string]string{ + "Content-Type": "application/json", + "kbn-xsrf": "true", + }) + res, err := req.Get(ListSpacesURL) + if err != nil { + klog.Error("Failed to send http request") + return nil, err + } + + body, err := io.ReadAll(res.RawBody()) + if err != nil { + return nil, err + } + + if res.StatusCode() != http.StatusOK { + return nil, fmt.Errorf("failed to list dashboard spaces %s", string(body)) + } + + var spaces []map[string]interface{} + if err = json.Unmarshal(body, &spaces); err != nil { + return nil, err + } + + var spacesName []string + for _, space := range spaces { + spacesName = append(spacesName, space["id"].(string)) + } + + return spacesName, nil +} diff --git a/elasticsearchdashboard/os_client.go b/elasticsearchdashboard/os_client.go index abb78d3d9..01e114df5 100644 --- a/elasticsearchdashboard/os_client.go +++ b/elasticsearchdashboard/os_client.go @@ -107,7 +107,7 @@ func (h *OSClient) GetStateFromHealthResponse(health *Health) (esapi.DashboardSe return esapi.DashboardServerState(health.OverallState), nil } -func (h *OSClient) ExportSavedObjects() (*Response, error) { +func (h *OSClient) ExportSavedObjects(_ string) (*Response, error) { req := h.Client.R(). SetDoNotParseResponse(true). SetHeaders(map[string]string{ @@ -127,7 +127,7 @@ func (h *OSClient) ExportSavedObjects() (*Response, error) { }, nil } -func (h *OSClient) ImportSavedObjects(filepath string) (*Response, error) { +func (h *OSClient) ImportSavedObjects(_, filepath string) (*Response, error) { req := h.Client.R(). SetDoNotParseResponse(true). SetHeader("osd-xsrf", "true"). @@ -144,3 +144,7 @@ func (h *OSClient) ImportSavedObjects(filepath string) (*Response, error) { Body: res.RawBody(), }, nil } + +func (h *OSClient) ListSpaces() ([]string, error) { + return []string{"default"}, nil +}