refactor(grafana): rework grafana package and make it more modular
This commit is contained in:
parent
cfcf3c6c2b
commit
7ce90dacc4
12 changed files with 710 additions and 282 deletions
143
pkg/grafana/client.go
Normal file
143
pkg/grafana/client.go
Normal file
|
@ -0,0 +1,143 @@
|
|||
package grafana
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"git.ar21.de/yolokube/grafana-backuper/pkg/grafana/schema"
|
||||
"golang.org/x/net/http/httpguts"
|
||||
)
|
||||
|
||||
const UserAgent = "grafana-backuper"
|
||||
|
||||
type Client struct {
|
||||
endpoint string
|
||||
token string
|
||||
tokenValid bool
|
||||
userAgent string
|
||||
httpClient *http.Client
|
||||
|
||||
Dashboard DashboardClient
|
||||
DashboardVersion DashboardVersionClient
|
||||
File SearchClient
|
||||
}
|
||||
|
||||
type ClientOption func(*Client)
|
||||
|
||||
func WithToken(token string) ClientOption {
|
||||
return func(client *Client) {
|
||||
client.token = token
|
||||
client.tokenValid = httpguts.ValidHeaderFieldName(token)
|
||||
}
|
||||
}
|
||||
|
||||
func WithHTTPClient(httpClient *http.Client) ClientOption {
|
||||
return func(client *Client) {
|
||||
client.httpClient = httpClient
|
||||
}
|
||||
}
|
||||
|
||||
func WithUserAgent(userAgent string) ClientOption {
|
||||
return func(client *Client) {
|
||||
client.userAgent = userAgent
|
||||
}
|
||||
}
|
||||
|
||||
func NewClient(endpoint string, options ...ClientOption) *Client {
|
||||
client := &Client{
|
||||
endpoint: endpoint,
|
||||
tokenValid: true,
|
||||
httpClient: &http.Client{},
|
||||
userAgent: UserAgent,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
option(client)
|
||||
}
|
||||
|
||||
client.Dashboard = DashboardClient{client: client}
|
||||
client.DashboardVersion = DashboardVersionClient{client: client}
|
||||
client.File = SearchClient{client: client}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
func (c *Client) NewRequest(ctx context.Context, method, path string, body io.Reader) (*http.Request, error) {
|
||||
url := fmt.Sprintf("%s/%s", c.endpoint, path)
|
||||
req, err := http.NewRequest(method, url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("User-Agent", c.userAgent)
|
||||
|
||||
if !c.tokenValid {
|
||||
return nil, errors.New("authorization token contains invalid characters")
|
||||
}
|
||||
|
||||
if c.token != "" {
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.token))
|
||||
}
|
||||
|
||||
if body != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
return req.WithContext(ctx), nil
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
*http.Response
|
||||
ErrorResponse *ErrorResponse
|
||||
|
||||
body []byte
|
||||
}
|
||||
|
||||
type ErrorResponse struct {
|
||||
Message string
|
||||
TraceID uint
|
||||
}
|
||||
|
||||
func (c *Client) Do(req *http.Request, v any) (*Response, error) {
|
||||
httpResp, err := c.httpClient.Do(req)
|
||||
resp := &Response{Response: httpResp}
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
defer httpResp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
resp.body = body
|
||||
|
||||
resp.Body = io.NopCloser(bytes.NewReader(body))
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
var errorResponse schema.ErrorResponse
|
||||
if err = json.Unmarshal(resp.body, &errorResponse); err == nil {
|
||||
return resp, fmt.Errorf(
|
||||
"grafana: got error with status code %d: %s",
|
||||
resp.StatusCode,
|
||||
ErrorResponseFromSchema(errorResponse).Message,
|
||||
)
|
||||
}
|
||||
return resp, fmt.Errorf("grafana: server responded with an unexpected status code %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
if v != nil {
|
||||
if writer, ok := v.(io.Writer); ok {
|
||||
_, err = io.Copy(writer, bytes.NewReader(resp.body))
|
||||
} else {
|
||||
err = json.Unmarshal(resp.body, v)
|
||||
}
|
||||
}
|
||||
|
||||
return resp, err
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue