Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ The library currently supports the following API endpoints:
* [Metrics Accounts](https://api-docs.logz.io/docs/logz/create-a-new-metrics-account)
* [Metrics drop filters](./drop_metrics/README.md) <!--- This should be replaced with the proper docs link once released. -->
* [Metrics roll-up rules](./metrics_rollup_rules/README.md) <!--- This should be replaced with the proper docs link once released. -->
* [Unified Projects](https://github.com/logzio/logzio_terraform_client/tree/master/unified_projects).
* [Unified Dashboards](https://github.com/logzio/logzio_terraform_client/tree/master/unified_dashboards).

#### Contributing

Expand Down
83 changes: 83 additions & 0 deletions unified_dashboards/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Unified Dashboards

Compatible with Logz.io's [unified dashboards API](https://api-docs.logz.io/docs/logz/create-a-new-dashboard).

Provides endpoints for managing unified dashboards, including CRUD operations, search, dashboard movement, and global datasource management.

## Usage

```go
client, _ := unified_dashboards.New(apiToken, baseUrl)

// List all dashboards
dashboards, err := client.ListDashboards()

// Get a specific dashboard by folder and UID
dashboard, err := client.GetDashboard("project-1", "dashboard-1", nil)

// Get dashboard with source parameter
source := "grafana"
dashboard, err := client.GetDashboard("project-1", "dashboard-1", &source)

// Create a new dashboard
result, err := client.CreateDashboard("project-1", unified_dashboards.CreateDashboardRequest{
Doc: map[string]interface{}{
"title": "CPU Usage Dashboard",
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"title": "CPU Usage",
"type": "graph",
},
},
},
})

// Update a dashboard
updatedDashboard, err := client.UpdateDashboard("project-1", "dashboard-1", unified_dashboards.UpdateDashboardRequest{
Doc: map[string]interface{}{
"title": "Updated Dashboard",
"description": "Updated description",
},
})

// Search dashboards
searchResults, err := client.SearchDashboards(unified_dashboards.SearchDashboardsRequest{
Query: "CPU",
Limit: 10,
Page: 1,
})

// Delete a dashboard
err = client.DeleteDashboard("project-1", "dashboard-1")
```

## Functions

| Function | Signature |
|----------|-----------|
| list | `func (c *DashboardsClient) ListDashboards() ([]Dashboard, error)` |
| get | `func (c *DashboardsClient) GetDashboard(folderId, uid string, source *string) (*Dashboard, error)` |
| create | `func (c *DashboardsClient) CreateDashboard(folderId string, req CreateDashboardRequest) (*Dashboard, error)` |
| update | `func (c *DashboardsClient) UpdateDashboard(folderId, uid string, req UpdateDashboardRequest) (*Dashboard, error)` |
| delete | `func (c *DashboardsClient) DeleteDashboard(folderId, uid string) error` |
| search | `func (c *DashboardsClient) SearchDashboards(req SearchDashboardsRequest) ([]Dashboard, error)` |

## Data Types

### Request Types

- `CreateDashboardRequest` - Request payload for creating a dashboard
- `UpdateDashboardRequest` - Request payload for updating a dashboard
- `SearchDashboardsRequest` - Search parameters for dashboard queries

### Response Types

- `Dashboard` - Dashboard definition with metadata

All request and response types include proper JSON tags with `omitempty` for optional fields.

## Notes

- Dashboard snapshots are not supported in this implementation
- The `Doc` field in dashboard requests/responses uses `map[string]interface{}` to support flexible panel configurations
117 changes: 117 additions & 0 deletions unified_dashboards/client_unified_dashboards.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package unified_dashboards

import (
"fmt"

"github.com/logzio/logzio_terraform_client/client"
)

const (
dashboardsListEndpoint = "%s/perses/api/v1/dashboards"
dashboardByUidEndpoint = "%s/perses/api/v1/projects/%s/dashboards/%s"
dashboardsCreateEndpoint = "%s/perses/api/v1/projects/%s/dashboards"
dashboardsSearchEndpoint = "%s/perses/api/v1/dashboards/search"

dashboardResourceName = "unified dashboard"

createDashboardOperation = "CreateUnifiedDashboard"
getDashboardOperation = "GetUnifiedDashboard"
listDashboardsOperation = "ListUnifiedDashboards"
updateDashboardOperation = "UpdateUnifiedDashboard"
searchDashboardsOperation = "SearchUnifiedDashboards"
deleteDashboardOperation = "DeleteUnifiedDashboard"
)

type DashboardsClient struct {
*client.Client
}

// Request types
type CreateDashboardRequest struct {
Doc map[string]interface{} `json:"doc"`
}

type UpdateDashboardRequest struct {
Doc map[string]interface{} `json:"doc"`
}

type SearchDashboardsRequest struct {
Query string `json:"query,omitempty"`
Tag []string `json:"tag,omitempty"`
Starred *bool `json:"starred,omitempty"`
Limit int `json:"limit,omitempty"`
Page int `json:"page,omitempty"`
Sort string `json:"sort,omitempty"`
Order string `json:"order,omitempty"`
}

// Response types
type Dashboard struct {
Uid string `json:"uid"`
Doc map[string]interface{} `json:"doc"`
Version int `json:"version,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
UpdatedAt string `json:"updatedAt,omitempty"`
CreatedBy string `json:"createdBy,omitempty"`
UpdatedBy string `json:"updatedBy,omitempty"`
}

func New(apiToken, baseUrl string) (*DashboardsClient, error) {
if len(apiToken) == 0 {
return nil, fmt.Errorf("API token not defined")
}
if len(baseUrl) == 0 {
return nil, fmt.Errorf("Base URL not defined")
}
return &DashboardsClient{
Client: client.New(apiToken, baseUrl),
}, nil
}

// Validation helpers
func validateCreateDashboardRequest(folderId string, req CreateDashboardRequest) error {
if len(folderId) == 0 {
return fmt.Errorf("folderId must be set")
}
if req.Doc == nil || len(req.Doc) == 0 {
return fmt.Errorf("doc must be set")
}
return nil
}

func validateUpdateDashboardRequest(folderId, uid string, req UpdateDashboardRequest) error {
if len(folderId) == 0 {
return fmt.Errorf("folderId must be set")
}
if len(uid) == 0 {
return fmt.Errorf("uid must be set")
}
if req.Doc == nil || len(req.Doc) == 0 {
return fmt.Errorf("doc must be set")
}
return nil
}

func validateGetDashboardRequest(folderId, uid string) error {
if len(folderId) == 0 {
return fmt.Errorf("folderId must be set")
}
if len(uid) == 0 {
return fmt.Errorf("uid must be set")
}
return nil
}

func validateDeleteDashboardRequest(folderId, uid string) error {
if len(folderId) == 0 {
return fmt.Errorf("folderId must be set")
}
if len(uid) == 0 {
return fmt.Errorf("uid must be set")
}
return nil
}

func validateSearchDashboardsRequest(req SearchDashboardsRequest) error {
return nil
}
48 changes: 48 additions & 0 deletions unified_dashboards/client_unified_dashboards_create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package unified_dashboards

import (
"encoding/json"
"fmt"
"net/http"

logzio_client "github.com/logzio/logzio_terraform_client"
)

const (
createDashboardMethod = http.MethodPost
createDashboardSuccess = http.StatusCreated
createDashboardNotFound = http.StatusNotFound
)

func (c *DashboardsClient) CreateDashboard(folderId string, req CreateDashboardRequest) (*Dashboard, error) {
if err := validateCreateDashboardRequest(folderId, req); err != nil {
return nil, err
}

body, err := json.Marshal(req)
if err != nil {
return nil, err
}

res, err := logzio_client.CallLogzioApi(logzio_client.LogzioApiCallDetails{
ApiToken: c.ApiToken,
HttpMethod: createDashboardMethod,
Url: fmt.Sprintf(dashboardsCreateEndpoint, c.BaseUrl, folderId),
Body: body,
SuccessCodes: []int{createDashboardSuccess, http.StatusOK},
NotFoundCode: createDashboardNotFound,
ResourceId: folderId,
ApiAction: createDashboardOperation,
ResourceName: dashboardResourceName,
})
if err != nil {
return nil, err
}

var result Dashboard
if err := json.Unmarshal(res, &result); err != nil {
return nil, err
}

return &result, nil
}
38 changes: 38 additions & 0 deletions unified_dashboards/client_unified_dashboards_delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package unified_dashboards

import (
"fmt"
"net/http"

logzio_client "github.com/logzio/logzio_terraform_client"
)

const (
deleteDashboardMethod = http.MethodDelete
deleteDashboardSuccess = http.StatusNoContent
deleteDashboardOk = http.StatusOK
deleteDashboardNotFound = http.StatusNotFound
)

func (c *DashboardsClient) DeleteDashboard(folderId, uid string) error {
if err := validateDeleteDashboardRequest(folderId, uid); err != nil {
return err
}

_, err := logzio_client.CallLogzioApi(logzio_client.LogzioApiCallDetails{
ApiToken: c.ApiToken,
HttpMethod: deleteDashboardMethod,
Url: fmt.Sprintf(dashboardByUidEndpoint, c.BaseUrl, folderId, uid),
Body: nil,
SuccessCodes: []int{deleteDashboardSuccess, deleteDashboardOk},
NotFoundCode: deleteDashboardNotFound,
ResourceId: uid,
ApiAction: deleteDashboardOperation,
ResourceName: dashboardResourceName,
})
if err != nil {
return err
}

return nil
}
57 changes: 57 additions & 0 deletions unified_dashboards/client_unified_dashboards_get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package unified_dashboards

import (
"encoding/json"
"fmt"
"net/http"
"net/url"

logzio_client "github.com/logzio/logzio_terraform_client"
)

const (
getDashboardMethod = http.MethodGet
getDashboardSuccess = http.StatusOK
getDashboardNotFound = http.StatusNotFound
)

func (c *DashboardsClient) GetDashboard(folderId, uid string, source *string) (*Dashboard, error) {
if err := validateGetDashboardRequest(folderId, uid); err != nil {
return nil, err
}

endpoint := fmt.Sprintf(dashboardByUidEndpoint, c.BaseUrl, folderId, uid)

if source != nil && len(*source) > 0 {
u, err := url.Parse(endpoint)
if err != nil {
return nil, err
}
q := u.Query()
q.Set("source", *source)
u.RawQuery = q.Encode()
endpoint = u.String()
}

res, err := logzio_client.CallLogzioApi(logzio_client.LogzioApiCallDetails{
ApiToken: c.ApiToken,
HttpMethod: getDashboardMethod,
Url: endpoint,
Body: nil,
SuccessCodes: []int{getDashboardSuccess},
NotFoundCode: getDashboardNotFound,
ResourceId: uid,
ApiAction: getDashboardOperation,
ResourceName: dashboardResourceName,
})
if err != nil {
return nil, err
}

var result Dashboard
if err := json.Unmarshal(res, &result); err != nil {
return nil, err
}

return &result, nil
}
39 changes: 39 additions & 0 deletions unified_dashboards/client_unified_dashboards_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package unified_dashboards

import (
"encoding/json"
"fmt"
"net/http"

logzio_client "github.com/logzio/logzio_terraform_client"
)

const (
listDashboardsMethod = http.MethodGet
listDashboardsSuccess = http.StatusOK
listDashboardsNotFound = http.StatusNotFound
)

func (c *DashboardsClient) ListDashboards() ([]Dashboard, error) {
res, err := logzio_client.CallLogzioApi(logzio_client.LogzioApiCallDetails{
ApiToken: c.ApiToken,
HttpMethod: listDashboardsMethod,
Url: fmt.Sprintf(dashboardsListEndpoint, c.BaseUrl),
Body: nil,
SuccessCodes: []int{listDashboardsSuccess},
NotFoundCode: listDashboardsNotFound,
ResourceId: "list",
ApiAction: listDashboardsOperation,
ResourceName: dashboardResourceName,
})
if err != nil {
return nil, err
}

var result []Dashboard
if err := json.Unmarshal(res, &result); err != nil {
return nil, err
}

return result, nil
}
Loading
Loading