-
Notifications
You must be signed in to change notification settings - Fork 487
/
client.go
81 lines (68 loc) · 2.15 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Package grafanacloud provides an interface to the Grafana Cloud API.
package grafanacloud
import (
"context"
"fmt"
"net/http"
"strings"
"gopkg.in/yaml.v2"
)
const integrationsAPIURL = "https://integrations-api.grafana.net"
// Client is a grafanacloud API client.
type Client struct {
c *http.Client
apiKey string
}
// NewClient creates a new Grafana Cloud client. All requests made will be
// performed using the provided http.Client c. If c is nil, the default
// http client will be used instead.
//
// apiKey will be used to authenticate against the API.
func NewClient(c *http.Client, apiKey string) *Client {
if c == nil {
c = http.DefaultClient
}
return &Client{c: c, apiKey: apiKey}
}
// AgentConfig generates a Grafana Agent config from the given stack.
// The config is returned as a string in YAML form.
func (c *Client) AgentConfig(ctx context.Context, stackID string) (string, error) {
req, err := http.NewRequestWithContext(
ctx, "GET",
fmt.Sprintf("%s/stacks/%s/agent_config", integrationsAPIURL, stackID),
nil,
)
if err != nil {
return "", fmt.Errorf("failed to generate request: %w", err)
}
req.Header.Add("Authorization", "Bearer "+c.apiKey)
resp, err := c.c.Do(req)
if err != nil {
return "", fmt.Errorf("failed to make request: %w", err)
}
defer resp.Body.Close()
// Even though the API returns json, we'll parse it as YAML here so we can
// re-encode it with the same order it was decoded in.
payload := struct {
Status string `yaml:"status"`
Data yaml.MapSlice `yaml:"data"`
Error string `yaml:"error"`
}{}
dec := yaml.NewDecoder(resp.Body)
dec.SetStrict(true)
if err := dec.Decode(&payload); err != nil {
if resp.StatusCode != 200 {
return "", fmt.Errorf("unexpected status code %d", resp.StatusCode)
}
return "", fmt.Errorf("failed to read response: %w", err)
}
if payload.Status != "success" {
return "", fmt.Errorf("request was not successful: %s", payload.Error)
}
// Convert the data to YAML
var sb strings.Builder
if err := yaml.NewEncoder(&sb).Encode(payload.Data); err != nil {
return "", fmt.Errorf("failed to generate YAML config: %w", err)
}
return sb.String(), nil
}