Skip to content
This repository has been archived by the owner on Jan 15, 2024. It is now read-only.

Commit

Permalink
Add Grafana cloud regions API (#72)
Browse files Browse the repository at this point in the history
* Add Grafana cloud regions API
Structs and functions for this AP: https://grafana.com/docs/grafana-cloud/reference/cloud-api/#list-regions

* Fix function name
:facepalm:
  • Loading branch information
julienduchesne authored Mar 9, 2022
1 parent 0254e2c commit 44fb93c
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 0 deletions.
80 changes: 80 additions & 0 deletions cloud_regions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package gapi

import "fmt"

// CloudRegion represents a Grafana Cloud region.
// https://grafana.com/docs/grafana-cloud/reference/cloud-api/#list-regions
type CloudRegion struct {
ID int `json:"id"`
Status string `json:"status"`
Slug string `json:"slug"`
Name string `json:"name"`
Description string `json:"description"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
Visibility string `json:"visibility"`

// Service URLs for the region
StackStateServiceURL string `json:"stackStateServiceUrl"`
SyntheticMonitoringAPIURL string `json:"syntheticMonitoringApiUrl"`
IntegrationsAPIURL string `json:"integrationsApiUrl"`
HostedExportersAPIURL string `json:"hostedExportersApiUrl"`
MachineLearningAPIURL string `json:"machineLearningApiUrl"`
IncidentsAPIURL string `json:"incidentsApiUrl"`

// Hosted Grafana
HGClusterID int `json:"hgClusterId"`
HGClusterSlug string `json:"hgClusterSlug"`
HGClusterName string `json:"hgClusterName"`
HGClusterURL string `json:"hgClusterUrl"`

// Hosted Metrics: Prometheus
HMPromClusterID int `json:"hmPromClusterId"`
HMPromClusterSlug string `json:"hmPromClusterSlug"`
HMPromClusterName string `json:"hmPromClusterName"`
HMPromClusterURL string `json:"hmPromClusterUrl"`

// Hosted Metrics: Graphite
HMGraphiteClusterID int `json:"hmGraphiteClusterId"`
HMGraphiteClusterSlug string `json:"hmGraphiteClusterSlug"`
HMGraphiteClusterName string `json:"hmGraphiteClusterName"`
HMGraphiteClusterURL string `json:"hmGraphiteClusterUrl"`

// Hosted Logs
HLClusterID int `json:"hlClusterId"`
HLClusterSlug string `json:"hlClusterSlug"`
HLClusterName string `json:"hlClusterName"`
HLClusterURL string `json:"hlClusterUrl"`

// Alertmanager
AMClusterID int `json:"amClusterId"`
AMClusterSlug string `json:"amClusterSlug"`
AMClusterName string `json:"amClusterName"`
AMClusterURL string `json:"amClusterUrl"`

// Hosted Traces
HTClusterID int `json:"htClusterId"`
HTClusterSlug string `json:"htClusterSlug"`
HTClusterName string `json:"htClusterName"`
HTClusterURL string `json:"htClusterUrl"`
}

// CloudRegionsResponse represents the response from the Grafana Cloud regions API.
type CloudRegionsResponse struct {
Items []CloudRegion `json:"items"`
}

// GetCloudRegions fetches and returns all Grafana Cloud regions.
func (c *Client) GetCloudRegions() (CloudRegionsResponse, error) {
var regions CloudRegionsResponse
err := c.request("GET", "/api/stack-regions", nil, nil, &regions)
return regions, err
}

// GetCloudRegionBySlug fetches and returns the cloud region which matches the given slug.
// You can also provide a numeric region ID.
func (c *Client) GetCloudRegionBySlug(slug string) (CloudRegion, error) {
var region CloudRegion
err := c.request("GET", fmt.Sprintf("/api/stack-regions/%s", slug), nil, nil, &region)
return region, err
}
125 changes: 125 additions & 0 deletions cloud_regions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package gapi

import "testing"

var (
cloudRegionResponse = `{
"id": 1,
"status": "active",
"slug": "us",
"name": "United States",
"description": "United States",
"createdAt": "2021-08-20T20:00:27.000Z",
"updatedAt": "2022-01-18T20:00:51.000Z",
"visibility": "public",
"stackStateServiceUrl": "http://apiserver.stackstate.svc.cluster.local",
"syntheticMonitoringApiUrl": "https://synthetic-monitoring-api.grafana.net",
"integrationsApiUrl": "https://integrations-api-us-central.grafana.net",
"hostedExportersApiUrl": "https://hosted-exporters-api-us-central.grafana.net",
"machineLearningApiUrl": "https://machine-learning-prod-us-central-0.grafana.net/machine-learning",
"incidentApiUrl": null,
"hgClusterId": 69,
"hgClusterSlug": "prod-us-central-0",
"hgClusterName": "prod-us-central-0",
"hgClusterUrl": "https://hg-api-prod-us-central-0.grafana.net",
"hmPromClusterId": 105,
"hmPromClusterSlug": "prod-10-prod-us-central-0",
"hmPromClusterName": "cortex-prod-10",
"hmPromClusterUrl": "https://prometheus-prod-10-prod-us-central-0.grafana.net",
"hmGraphiteClusterId": 105,
"hmGraphiteClusterSlug": "prod-10-prod-us-central-0",
"hmGraphiteClusterName": "cortex-prod-10",
"hmGraphiteClusterUrl": "https://prometheus-prod-10-prod-us-central-0.grafana.net",
"hlClusterId": 84,
"hlClusterSlug": "loki-prod-us-central-0",
"hlClusterName": "Hosted Logs Cluster (prod-us-central-0)",
"hlClusterUrl": "https://logs-prod3.grafana.net",
"amClusterId": 68,
"amClusterSlug": "alertmanager-us-central1",
"amClusterName": "alertmanager-us-central1",
"amClusterUrl": "https://alertmanager-us-central1.grafana.net",
"htClusterId": 78,
"htClusterSlug": "tempo-prod-us-central1",
"htClusterName": "tempo-prod-us-central1",
"htClusterUrl": "https://tempo-us-central1.grafana.net"
}
`
cloudRegionsResponse = `{
"items": [
` + cloudRegionResponse + `
]
}
`
expectedRegion = CloudRegion{ID: 1,
Status: "active",
Slug: "us",
Name: "United States",
Description: "United States",
CreatedAt: "2021-08-20T20:00:27.000Z",
UpdatedAt: "2022-01-18T20:00:51.000Z",
Visibility: "public",
StackStateServiceURL: "http://apiserver.stackstate.svc.cluster.local",
SyntheticMonitoringAPIURL: "https://synthetic-monitoring-api.grafana.net",
IntegrationsAPIURL: "https://integrations-api-us-central.grafana.net",
HostedExportersAPIURL: "https://hosted-exporters-api-us-central.grafana.net",
MachineLearningAPIURL: "https://machine-learning-prod-us-central-0.grafana.net/machine-learning",
IncidentsAPIURL: "",
HGClusterID: 69,
HGClusterSlug: "prod-us-central-0",
HGClusterName: "prod-us-central-0",
HGClusterURL: "https://hg-api-prod-us-central-0.grafana.net",
HMPromClusterID: 105,
HMPromClusterSlug: "prod-10-prod-us-central-0",
HMPromClusterName: "cortex-prod-10",
HMPromClusterURL: "https://prometheus-prod-10-prod-us-central-0.grafana.net",
HMGraphiteClusterID: 105,
HMGraphiteClusterSlug: "prod-10-prod-us-central-0",
HMGraphiteClusterName: "cortex-prod-10",
HMGraphiteClusterURL: "https://prometheus-prod-10-prod-us-central-0.grafana.net",
HLClusterID: 84,
HLClusterSlug: "loki-prod-us-central-0",
HLClusterName: "Hosted Logs Cluster (prod-us-central-0)",
HLClusterURL: "https://logs-prod3.grafana.net",
AMClusterID: 68,
AMClusterSlug: "alertmanager-us-central1",
AMClusterName: "alertmanager-us-central1",
AMClusterURL: "https://alertmanager-us-central1.grafana.net",
HTClusterID: 78,
HTClusterSlug: "tempo-prod-us-central1",
HTClusterName: "tempo-prod-us-central1",
HTClusterURL: "https://tempo-us-central1.grafana.net"}
)

func TestCloudRegions(t *testing.T) {
server, client := gapiTestTools(t, 200, cloudRegionsResponse)
defer server.Close()

regions, err := client.GetCloudRegions()

if err != nil {
t.Fatalf("expected error to be nil; got: %s", err.Error())
}

// check that the number of items is the same
if got := len(regions.Items); got != 1 {
t.Errorf("Length of returned regions - Actual regions count: %d, Expected regions count: %d", got, 1)
}

if got := regions.Items[0]; got != expectedRegion {
t.Errorf("Unexpected Region - Got:\n%#v\n, Expected:\n%#v\n", got, expectedRegion)
}
}

func TestCloudRegionBySlug(t *testing.T) {
server, client := gapiTestTools(t, 200, cloudRegionResponse)
defer server.Close()

resp, err := client.GetCloudRegionBySlug("us")
if err != nil {
t.Fatal(err)
}

if resp != expectedRegion {
t.Errorf("Unexpected Region - Got:\n%#v\n, Expected:\n%#v\n", resp, expectedRegion)
}
}

0 comments on commit 44fb93c

Please sign in to comment.