feat(http): Allow secrets in headers (#14743)
This commit is contained in:
parent
616ad305fe
commit
4f0ac6e155
|
|
@ -17,8 +17,8 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
||||||
|
|
||||||
## Secret-store support
|
## Secret-store support
|
||||||
|
|
||||||
This plugin supports secrets from secret-stores for the `username`, `password`
|
This plugin supports secrets from secret-stores for the `username`, `password`,
|
||||||
and `token` option.
|
`token` and `headers` option.
|
||||||
See the [secret-store documentation][SECRETSTORE] for more details on how
|
See the [secret-store documentation][SECRETSTORE] for more details on how
|
||||||
to use them.
|
to use them.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,9 @@ type HTTP struct {
|
||||||
Token config.Secret `toml:"token"`
|
Token config.Secret `toml:"token"`
|
||||||
TokenFile string `toml:"token_file"`
|
TokenFile string `toml:"token_file"`
|
||||||
|
|
||||||
Headers map[string]string `toml:"headers"`
|
Headers map[string]*config.Secret `toml:"headers"`
|
||||||
SuccessStatusCodes []int `toml:"success_status_codes"`
|
SuccessStatusCodes []int `toml:"success_status_codes"`
|
||||||
Log telegraf.Logger `toml:"-"`
|
Log telegraf.Logger `toml:"-"`
|
||||||
|
|
||||||
httpconfig.HTTPClientConfig
|
httpconfig.HTTPClientConfig
|
||||||
|
|
||||||
|
|
@ -142,11 +142,19 @@ func (h *HTTP) gatherURL(acc telegraf.Accumulator, url string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range h.Headers {
|
for k, v := range h.Headers {
|
||||||
if strings.EqualFold(k, "host") {
|
secret, err := v.Get()
|
||||||
request.Host = v
|
if err != nil {
|
||||||
} else {
|
return err
|
||||||
request.Header.Add(k, v)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
headerVal := secret.String()
|
||||||
|
if strings.EqualFold(k, "host") {
|
||||||
|
request.Host = headerVal
|
||||||
|
} else {
|
||||||
|
request.Header.Add(k, headerVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
secret.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.setRequestAuth(request); err != nil {
|
if err := h.setRequestAuth(request); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package http_test
|
||||||
import (
|
import (
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/influxdata/telegraf/config"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
|
|
@ -82,9 +83,10 @@ func TestHTTPHeaders(t *testing.T) {
|
||||||
defer fakeServer.Close()
|
defer fakeServer.Close()
|
||||||
|
|
||||||
address := fakeServer.URL + "/endpoint"
|
address := fakeServer.URL + "/endpoint"
|
||||||
|
headerSecret := config.NewSecret([]byte(headerValue))
|
||||||
plugin := &httpplugin.HTTP{
|
plugin := &httpplugin.HTTP{
|
||||||
URLs: []string{address},
|
URLs: []string{address},
|
||||||
Headers: map[string]string{header: headerValue},
|
Headers: map[string]*config.Secret{header: &headerSecret},
|
||||||
Log: testutil.Logger{},
|
Log: testutil.Logger{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,7 +118,7 @@ func TestHTTPContentLengthHeader(t *testing.T) {
|
||||||
address := fakeServer.URL + "/endpoint"
|
address := fakeServer.URL + "/endpoint"
|
||||||
plugin := &httpplugin.HTTP{
|
plugin := &httpplugin.HTTP{
|
||||||
URLs: []string{address},
|
URLs: []string{address},
|
||||||
Headers: map[string]string{},
|
Headers: map[string]*config.Secret{},
|
||||||
Body: "{}",
|
Body: "{}",
|
||||||
Log: testutil.Logger{},
|
Log: testutil.Logger{},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
||||||
|
|
||||||
## Secret-store support
|
## Secret-store support
|
||||||
|
|
||||||
This plugin supports secrets from secret-stores for the `username` and
|
This plugin supports secrets from secret-stores for the `username`, `password`
|
||||||
`password` option.
|
and `headers` option.
|
||||||
See the [secret-store documentation][SECRETSTORE] for more details on how
|
See the [secret-store documentation][SECRETSTORE] for more details on how
|
||||||
to use them.
|
to use them.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,15 +43,15 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type HTTP struct {
|
type HTTP struct {
|
||||||
URL string `toml:"url"`
|
URL string `toml:"url"`
|
||||||
Method string `toml:"method"`
|
Method string `toml:"method"`
|
||||||
Username config.Secret `toml:"username"`
|
Username config.Secret `toml:"username"`
|
||||||
Password config.Secret `toml:"password"`
|
Password config.Secret `toml:"password"`
|
||||||
Headers map[string]string `toml:"headers"`
|
Headers map[string]*config.Secret `toml:"headers"`
|
||||||
ContentEncoding string `toml:"content_encoding"`
|
ContentEncoding string `toml:"content_encoding"`
|
||||||
UseBatchFormat bool `toml:"use_batch_format"`
|
UseBatchFormat bool `toml:"use_batch_format"`
|
||||||
AwsService string `toml:"aws_service"`
|
AwsService string `toml:"aws_service"`
|
||||||
NonRetryableStatusCodes []int `toml:"non_retryable_statuscodes"`
|
NonRetryableStatusCodes []int `toml:"non_retryable_statuscodes"`
|
||||||
httpconfig.HTTPClientConfig
|
httpconfig.HTTPClientConfig
|
||||||
Log telegraf.Logger `toml:"-"`
|
Log telegraf.Logger `toml:"-"`
|
||||||
|
|
||||||
|
|
@ -204,11 +204,20 @@ func (h *HTTP) writeMetric(reqBody []byte) error {
|
||||||
if h.ContentEncoding == "gzip" {
|
if h.ContentEncoding == "gzip" {
|
||||||
req.Header.Set("Content-Encoding", "gzip")
|
req.Header.Set("Content-Encoding", "gzip")
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range h.Headers {
|
for k, v := range h.Headers {
|
||||||
if strings.EqualFold(k, "host") {
|
secret, err := v.Get()
|
||||||
req.Host = v
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
req.Header.Set(k, v)
|
|
||||||
|
headerVal := secret.String()
|
||||||
|
if strings.EqualFold(k, "host") {
|
||||||
|
req.Host = headerVal
|
||||||
|
}
|
||||||
|
req.Header.Set(k, headerVal)
|
||||||
|
|
||||||
|
secret.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := h.client.Do(req)
|
resp, err := h.client.Do(req)
|
||||||
|
|
|
||||||
|
|
@ -290,6 +290,7 @@ func TestContentType(t *testing.T) {
|
||||||
u, err := url.Parse("http://" + ts.Listener.Addr().String())
|
u, err := url.Parse("http://" + ts.Listener.Addr().String())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
headerSecret := config.NewSecret([]byte("application/json"))
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
plugin *HTTP
|
plugin *HTTP
|
||||||
|
|
@ -306,7 +307,7 @@ func TestContentType(t *testing.T) {
|
||||||
name: "overwrite content_type",
|
name: "overwrite content_type",
|
||||||
plugin: &HTTP{
|
plugin: &HTTP{
|
||||||
URL: u.String(),
|
URL: u.String(),
|
||||||
Headers: map[string]string{"Content-Type": "application/json"},
|
Headers: map[string]*config.Secret{"Content-Type": &headerSecret},
|
||||||
},
|
},
|
||||||
expected: "application/json",
|
expected: "application/json",
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue