Skip to content

Commit

Permalink
feat(metadata): add timeout option (#293) (#294)
Browse files Browse the repository at this point in the history
(cherry picked from commit 913bf74)

Co-authored-by: Julian Tölle <[email protected]>
  • Loading branch information
github-actions[bot] and apricote committed Jul 21, 2023
1 parent 11e2297 commit 6b1d465
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions hcloud/metadata/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/http"
"strconv"
"strings"
"time"

"github.com/prometheus/client_golang/prometheus"

Expand All @@ -18,55 +19,65 @@ const Endpoint = "http://169.254.169.254/hetzner/v1/metadata"
// Client is a client for the Hetzner Cloud Server Metadata Endpoints.
type Client struct {
endpoint string
timeout time.Duration

httpClient *http.Client
instrumentationRegistry *prometheus.Registry
}

// A ClientOption is used to configure a Client.
// A ClientOption is used to configure a [Client].
type ClientOption func(*Client)

// WithEndpoint configures a Client to use the specified Metadata API endpoint.
// WithEndpoint configures a [Client] to use the specified Metadata API endpoint.
func WithEndpoint(endpoint string) ClientOption {
return func(client *Client) {
client.endpoint = strings.TrimRight(endpoint, "/")
}
}

// WithHTTPClient configures a Client to perform HTTP requests with httpClient.
// WithHTTPClient configures a [Client] to perform HTTP requests with httpClient.
func WithHTTPClient(httpClient *http.Client) ClientOption {
return func(client *Client) {
client.httpClient = httpClient
}
}

// WithInstrumentation configures a Client to collect metrics about the performed HTTP requests.
// WithInstrumentation configures a [Client] to collect metrics about the performed HTTP requests.
func WithInstrumentation(registry *prometheus.Registry) ClientOption {
return func(client *Client) {
client.instrumentationRegistry = registry
}
}

// NewClient creates a new client.
// WithTimeout specifies a time limit for requests made by this [Client]. Defaults to 5 seconds.
func WithTimeout(timeout time.Duration) ClientOption {
return func(client *Client) {
client.timeout = timeout
}
}

// NewClient creates a new [Client] with the options applied.
func NewClient(options ...ClientOption) *Client {
client := &Client{
endpoint: Endpoint,
httpClient: &http.Client{},
timeout: 5 * time.Second,
}

for _, option := range options {
option(client)
}

client.httpClient.Timeout = client.timeout

if client.instrumentationRegistry != nil {
i := instrumentation.New("metadata", client.instrumentationRegistry)
client.httpClient.Transport = i.InstrumentedRoundTripper()
}
return client
}

// NewRequest creates an HTTP request against the API. The returned request
// is assigned with ctx and has all necessary headers set (auth, user agent, etc.).
// get executes an HTTP request against the API.
func (c *Client) get(path string) (string, error) {
url := c.endpoint + path
resp, err := c.httpClient.Get(url)
Expand Down

0 comments on commit 6b1d465

Please sign in to comment.