diff --git a/elasticsearchdashboard/api.go b/elasticsearchdashboard/api.go index d48282918..b1c232fd4 100644 --- a/elasticsearchdashboard/api.go +++ b/elasticsearchdashboard/api.go @@ -25,5 +25,6 @@ type EDClient interface { GetStateFromHealthResponse(health *Health) (esapi.DashboardServerState, error) ExportSavedObjects(spaceName string) (*Response, error) ImportSavedObjects(spaceName, filepath string) (*Response, error) - ListSpaces() ([]string, error) + ListSpaces() ([]Space, error) + CreateSpace(space Space) error } diff --git a/elasticsearchdashboard/client.go b/elasticsearchdashboard/client.go index f5ce08cb7..cb9bbaa84 100644 --- a/elasticsearchdashboard/client.go +++ b/elasticsearchdashboard/client.go @@ -37,9 +37,14 @@ const ( "observability-visualization", "search"]}` SavedObjectsExportURL = "/api/saved_objects/_export" SavedObjectsImportURL = "/api/saved_objects/_import" - ListSpacesURL = "/api/spaces/space" + SpacesURL = "/api/spaces/space" ) +var jsonHeaderForKibanaAPI = map[string]string{ + "Content-Type": "application/json", + "kbn-xsrf": "true", +} + type Client struct { EDClient } @@ -88,3 +93,13 @@ type ResponseBody struct { Status map[string]interface{} `json:"status"` Metrics map[string]interface{} `json:"metrics"` } + +type Space struct { + Id string `json:"id"` + Name string `json:"name"` + Description string `json:"description,omitempty"` + Color string `json:"color,omitempty"` + Initials string `json:"initials,omitempty"` + DisabledFeatures []string `json:"disabledFeatures,omitempty"` + ImageUrl string `json:"imageUrl,omitempty"` +} diff --git a/elasticsearchdashboard/ed_client_v7.go b/elasticsearchdashboard/ed_client_v7.go index 0eedd9566..b451af458 100644 --- a/elasticsearchdashboard/ed_client_v7.go +++ b/elasticsearchdashboard/ed_client_v7.go @@ -112,10 +112,7 @@ func (h *EDClientV7) GetStateFromHealthResponse(health *Health) (esapi.Dashboard func (h *EDClientV7) ExportSavedObjects(spaceName string) (*Response, error) { req := h.Client.R(). SetDoNotParseResponse(true). - SetHeaders(map[string]string{ - "Content-Type": "application/json", - "kbn-xsrf": "true", - }). + SetHeaders(jsonHeaderForKibanaAPI). SetBody([]byte(SavedObjectsReqBodyES)) res, err := req.Post("/s/" + spaceName + SavedObjectsExportURL) if err != nil { @@ -147,14 +144,11 @@ func (h *EDClientV7) ImportSavedObjects(spaceName, filepath string) (*Response, }, nil } -func (h *EDClientV7) ListSpaces() ([]string, error) { +func (h *EDClientV7) ListSpaces() ([]Space, error) { req := h.Client.R(). SetDoNotParseResponse(true). - SetHeaders(map[string]string{ - "Content-Type": "application/json", - "kbn-xsrf": "true", - }) - res, err := req.Get(ListSpacesURL) + SetHeaders(jsonHeaderForKibanaAPI) + res, err := req.Get(SpacesURL) if err != nil { klog.Error("Failed to send http request") return nil, err @@ -169,15 +163,33 @@ func (h *EDClientV7) ListSpaces() ([]string, error) { return nil, fmt.Errorf("failed to list dashboard spaces %s", string(body)) } - var spaces []map[string]interface{} + var spaces []Space 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 spaces, nil +} + +func (h *EDClientV7) CreateSpace(space Space) error { + req := h.Client.R(). + SetDoNotParseResponse(true). + SetHeaders(jsonHeaderForKibanaAPI). + SetBody(space) + res, err := req.Post(SpacesURL) + if err != nil { + klog.Error(err, "Failed to send http request") + return err + } + + body, err := io.ReadAll(res.RawBody()) + if err != nil { + return err + } + + if res.StatusCode() != http.StatusOK { + return fmt.Errorf("failed to create dashboard space %s: %s", space.Name, string(body)) } - return spacesName, nil + return nil } diff --git a/elasticsearchdashboard/ed_client_v8.go b/elasticsearchdashboard/ed_client_v8.go index 551cf07c4..3b64484c3 100644 --- a/elasticsearchdashboard/ed_client_v8.go +++ b/elasticsearchdashboard/ed_client_v8.go @@ -110,10 +110,7 @@ func (h *EDClientV8) GetStateFromHealthResponse(health *Health) (esapi.Dashboard func (h *EDClientV8) ExportSavedObjects(spaceName string) (*Response, error) { req := h.Client.R(). SetDoNotParseResponse(true). - SetHeaders(map[string]string{ - "Content-Type": "application/json", - "kbn-xsrf": "true", - }). + SetHeaders(jsonHeaderForKibanaAPI). SetBody([]byte(SavedObjectsReqBodyES)) res, err := req.Post("/s/" + spaceName + SavedObjectsExportURL) if err != nil { @@ -145,14 +142,11 @@ func (h *EDClientV8) ImportSavedObjects(spaceName, filepath string) (*Response, }, nil } -func (h *EDClientV8) ListSpaces() ([]string, error) { +func (h *EDClientV8) ListSpaces() ([]Space, error) { req := h.Client.R(). SetDoNotParseResponse(true). - SetHeaders(map[string]string{ - "Content-Type": "application/json", - "kbn-xsrf": "true", - }) - res, err := req.Get(ListSpacesURL) + SetHeaders(jsonHeaderForKibanaAPI) + res, err := req.Get(SpacesURL) if err != nil { klog.Error("Failed to send http request") return nil, err @@ -167,15 +161,33 @@ func (h *EDClientV8) ListSpaces() ([]string, error) { return nil, fmt.Errorf("failed to list dashboard spaces %s", string(body)) } - var spaces []map[string]interface{} + var spaces []Space 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 spaces, nil +} + +func (h *EDClientV8) CreateSpace(space Space) error { + req := h.Client.R(). + SetDoNotParseResponse(true). + SetHeaders(jsonHeaderForKibanaAPI). + SetBody(space) + res, err := req.Post(SpacesURL) + if err != nil { + klog.Error(err, "Failed to send http request") + return err + } + + body, err := io.ReadAll(res.RawBody()) + if err != nil { + return err + } + + if res.StatusCode() != http.StatusOK { + return fmt.Errorf("failed to create dashboard space %s: %s", space.Name, string(body)) } - return spacesName, nil + return nil } diff --git a/elasticsearchdashboard/os_client.go b/elasticsearchdashboard/os_client.go index 01e114df5..a824cd039 100644 --- a/elasticsearchdashboard/os_client.go +++ b/elasticsearchdashboard/os_client.go @@ -145,6 +145,10 @@ func (h *OSClient) ImportSavedObjects(_, filepath string) (*Response, error) { }, nil } -func (h *OSClient) ListSpaces() ([]string, error) { - return []string{"default"}, nil +func (h *OSClient) ListSpaces() ([]Space, error) { + return []Space{{Id: "default"}}, nil +} + +func (h *OSClient) CreateSpace(_ Space) error { + return nil }