repo init
This commit is contained in:
commit
7e44db87b2
48 files changed
+5346
No files matched your search
@@ -0,0 +1,65 @@
|
||||
// Package apiclient is a thin HTTP client for the Control API's /api/v1
|
||||
// surface, shared by the validator-agent and prober binaries. Neither
|
||||
// binary talks to the database directly — this is their only channel to
|
||||
// shared state, keeping both genuinely stateless.
|
||||
package apiclient
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
BaseURL string
|
||||
HTTPClient *http.Client
|
||||
}
|
||||
|
||||
func New(baseURL string, timeout time.Duration) *Client {
|
||||
return &Client{BaseURL: baseURL, HTTPClient: &http.Client{Timeout: timeout}}
|
||||
}
|
||||
|
||||
// Do issues a JSON request and decodes a JSON response into out (if
|
||||
// non-nil). A 204 response is treated as "no content" and out is left
|
||||
// untouched, with ok=false — used for the assignment poll's empty case.
|
||||
func (c *Client) Do(ctx context.Context, method, path string, body, out interface{}) (ok bool, err error) {
|
||||
var reader io.Reader
|
||||
if body != nil {
|
||||
b, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("marshal request: %w", err)
|
||||
}
|
||||
reader = bytes.NewReader(b)
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, method, c.BaseURL+path, reader)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("build request: %w", err)
|
||||
}
|
||||
if body != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("%s %s: %w", method, path, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusNoContent {
|
||||
return false, nil
|
||||
}
|
||||
respBody, _ := io.ReadAll(resp.Body)
|
||||
if resp.StatusCode >= 300 {
|
||||
return false, fmt.Errorf("%s %s: status %d: %s", method, path, resp.StatusCode, string(respBody))
|
||||
}
|
||||
if out != nil && len(respBody) > 0 {
|
||||
if err := json.Unmarshal(respBody, out); err != nil {
|
||||
return false, fmt.Errorf("%s %s: decode response: %w", method, path, err)
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
Reference in new issue
Block a user