package grafana import ( "bytes" "context" "encoding/json" "fmt" "net/url" "time" ) type BoardProperties struct { IsStarred bool `json:"isStarred,omitempty"` IsHome bool `json:"isHome,omitempty"` IsSnapshot bool `json:"isSnapshot,omitempty"` Type string `json:"type,omitempty"` CanSave bool `json:"canSave"` CanEdit bool `json:"canEdit"` CanStar bool `json:"canStar"` Slug string `json:"slug"` Expires time.Time `json:"expires"` Created time.Time `json:"created"` Updated time.Time `json:"updated"` UpdatedBy string `json:"updatedBy"` CreatedBy string `json:"createdBy"` Version int `json:"version"` FolderID int `json:"folderId"` FolderTitle string `json:"folderTitle"` FolderURL string `json:"folderUrl"` } type DashboardVersion struct { ID uint `json:"id"` DashboardID uint `json:"dashboardId"` DashboardUID string `json:"uid"` ParentVersion uint `json:"parentVersion"` RestoredFrom uint `json:"restoredFrom"` Version uint `json:"version"` Created time.Time `json:"created"` CreatedBy string `json:"createdBy"` Message string `json:"message"` } func (c *Client) getRawDashboardByUID(ctx context.Context, path string) ([]byte, BoardProperties, error) { raw, code, err := c.get(ctx, fmt.Sprintf("api/dashboards/%s", path), nil) if err != nil { return nil, BoardProperties{}, err } if code != 200 { return raw, BoardProperties{}, fmt.Errorf("HTTP error %d: returns %s", code, raw) } var result struct { Meta BoardProperties `json:"meta"` } dec := json.NewDecoder(bytes.NewReader(raw)) dec.UseNumber() if err := dec.Decode(&result); err != nil { return raw, BoardProperties{}, fmt.Errorf("failed unmarshalling dashboard from path %s: %v", path, err) } return raw, result.Meta, nil } func (c *Client) getRawDashboardFromVersion(ctx context.Context, path string) ([]byte, DashboardVersion, error) { var versionInfo DashboardVersion raw, code, err := c.get(ctx, fmt.Sprintf("api/dashboards/%s", path), nil) if err != nil { return nil, versionInfo, err } if code != 200 { return raw, versionInfo, fmt.Errorf("HTTP error %d: returns %s", code, raw) } dec := json.NewDecoder(bytes.NewReader(raw)) dec.UseNumber() if err := dec.Decode(&versionInfo); err != nil { return raw, versionInfo, fmt.Errorf("failed unmarshalling dashboard from path %s: %v", path, err) } return raw, versionInfo, nil } func queryParams(params ...QueryParam) url.Values { u := url.URL{} q := u.Query() for _, p := range params { p(&q) } return q } func (c *Client) GetDashboardVersionsByDashboardUID(ctx context.Context, uid string, params ...QueryParam) ([]DashboardVersion, error) { var ( raw []byte code int err error ) if raw, code, err = c.get(ctx, fmt.Sprintf("api/dashboards/uid/%s/versions", uid), queryParams(params...)); err != nil { return nil, err } if code != 200 { return nil, fmt.Errorf("HTTP error %d: returns %s", code, raw) } var versions []DashboardVersion err = json.Unmarshal(raw, &versions) return versions, err } func (c *Client) GetRawDashboardByUID(ctx context.Context, uid string) ([]byte, BoardProperties, error) { return c.getRawDashboardByUID(ctx, "uid/"+uid) } func (c *Client) GetRawDashboardByUIDAndVersion(ctx context.Context, uid string, version uint) ([]byte, DashboardVersion, error) { return c.getRawDashboardFromVersion(ctx, "uid/"+uid+"/versions/"+fmt.Sprint(version)) } func (c *Client) SearchDashboards(ctx context.Context, query string, starred bool, tags ...string) ([]FoundBoard, error) { params := []SearchParam{ SearchType(SearchTypeDashboard), SearchQuery(query), SearchStarred(starred), } for _, tag := range tags { params = append(params, SearchTag(tag)) } return c.Search(ctx, params...) } func ConvertRawToIndent(raw []byte) (string, error) { var buf bytes.Buffer err := json.Indent(&buf, raw, "", " ") if err != nil { return "", fmt.Errorf("error pritty-printing raw json string: %v", err) } return buf.String(), nil }