Skip to content

Commit b6099cd

Browse files
committed
Add source_address to HTTPClientConfig
This unlocks setting `source_ip_address` for HTTP probes in `blackbox_exporter`. Signed-off-by: Ivan Babrou <[email protected]>
1 parent 6e540be commit b6099cd

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

config/http_config.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ package config
1717

1818
import (
1919
"bytes"
20+
"context"
2021
"crypto/sha256"
2122
"crypto/tls"
2223
"crypto/x509"
2324
"fmt"
2425
"io/ioutil"
26+
"net"
2527
"net/http"
2628
"net/url"
2729
"strings"
@@ -100,6 +102,40 @@ func (u URL) MarshalYAML() (interface{}, error) {
100102
return nil, nil
101103
}
102104

105+
// TCPAddr is a custom TCP address type that allows validation at configuration load time.
106+
type TCPAddr struct {
107+
*net.TCPAddr
108+
}
109+
110+
// UnmarshalYAML implements the yaml.Unmarshaler interface for TCP addresses.
111+
func (a TCPAddr) UnmarshalYAML(unmarshal func(interface{}) error) error {
112+
var s string
113+
if err := unmarshal(&s); err != nil {
114+
return err
115+
}
116+
117+
if len(s) == 0 {
118+
a.TCPAddr = nil
119+
}
120+
121+
ip := net.ParseIP(s)
122+
if ip == nil {
123+
return fmt.Errorf("error parsing ip %q", s)
124+
}
125+
126+
a.TCPAddr = &net.TCPAddr{IP: ip}
127+
128+
return nil
129+
}
130+
131+
// MarshalYAML implements the yaml.Marshaler interface for TCP addresses.
132+
func (a TCPAddr) MarshalYAML() (interface{}, error) {
133+
if a.TCPAddr != nil {
134+
return a.TCPAddr.String(), nil
135+
}
136+
return nil, nil
137+
}
138+
103139
// HTTPClientConfig configures an HTTP client.
104140
type HTTPClientConfig struct {
105141
// The HTTP basic authentication credentials for the targets.
@@ -120,6 +156,8 @@ type HTTPClientConfig struct {
120156
// The omitempty flag is not set, because it would be hidden from the
121157
// marshalled configuration when set to false.
122158
FollowRedirects bool `yaml:"follow_redirects"`
159+
// SourceAddress specifies a source address to use for outgoing connections.
160+
SourceAddress *TCPAddr `yaml:"source_address,omitempty"`
123161
}
124162

125163
// SetDirectory joins any relative file paths with dir.
@@ -236,6 +274,13 @@ func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, disableKeepAli
236274
DialContext: conntrack.NewDialContextFunc(
237275
conntrack.DialWithTracing(),
238276
conntrack.DialWithName(name),
277+
conntrack.DialWithDialContextFunc(func(ctx context.Context, network string, address string) (net.Conn, error) {
278+
dialer := &net.Dialer{}
279+
if cfg.SourceAddress != nil {
280+
dialer.LocalAddr = cfg.SourceAddress.TCPAddr
281+
}
282+
return dialer.DialContext(ctx, network, address)
283+
}),
239284
),
240285
}
241286
if enableHTTP2 {

0 commit comments

Comments
 (0)