Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
433
plugins/secretstores/http/http_test.go
Normal file
433
plugins/secretstores/http/http_test.go
Normal file
|
@ -0,0 +1,433 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/plugins/secretstores"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
func TestCases(t *testing.T) {
|
||||
// Get all directories in testcases
|
||||
folders, err := os.ReadDir("testcases")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Make sure tests contains data
|
||||
require.NotEmpty(t, folders)
|
||||
|
||||
// Set up for file inputs
|
||||
secretstores.Add("http", func(string) telegraf.SecretStore {
|
||||
return &HTTP{Log: testutil.Logger{}}
|
||||
})
|
||||
|
||||
for _, f := range folders {
|
||||
// Only handle folders
|
||||
if !f.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
fname := f.Name()
|
||||
t.Run(fname, func(t *testing.T) {
|
||||
testdataPath := filepath.Join("testcases", fname)
|
||||
configFilename := filepath.Join(testdataPath, "telegraf.conf")
|
||||
inputFilename := filepath.Join(testdataPath, "secrets.json")
|
||||
expectedFilename := filepath.Join(testdataPath, "expected.json")
|
||||
|
||||
// Read the input data
|
||||
input, err := os.ReadFile(inputFilename)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Read the expected output data
|
||||
buf, err := os.ReadFile(expectedFilename)
|
||||
require.NoError(t, err)
|
||||
var expected map[string]string
|
||||
require.NoError(t, json.Unmarshal(buf, &expected))
|
||||
|
||||
// Configure the plugin
|
||||
cfg := config.NewConfig()
|
||||
require.NoError(t, cfg.LoadConfig(configFilename))
|
||||
require.NotEmpty(t, cfg.SecretStores)
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path == "/secrets" {
|
||||
if _, err = w.Write(input); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
us, err := url.Parse(server.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
var id string
|
||||
var plugin telegraf.SecretStore
|
||||
actual := make(map[string]string, len(expected))
|
||||
for id, plugin = range cfg.SecretStores {
|
||||
// Setup dummy server and redirect the plugin's URL to that dummy
|
||||
httpPlugin, ok := plugin.(*HTTP)
|
||||
require.True(t, ok)
|
||||
|
||||
u, err := url.Parse(httpPlugin.URL)
|
||||
require.NoError(t, err)
|
||||
u.Host = us.Host
|
||||
httpPlugin.URL = u.String()
|
||||
require.NoError(t, httpPlugin.download())
|
||||
|
||||
// Retrieve the secrets from the plugin
|
||||
keys, err := plugin.List()
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, k := range keys {
|
||||
v, err := plugin.Get(k)
|
||||
require.NoError(t, err)
|
||||
actual[id+"."+k] = string(v)
|
||||
}
|
||||
}
|
||||
require.EqualValues(t, expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSampleConfig(t *testing.T) {
|
||||
plugin := &HTTP{}
|
||||
require.NotEmpty(t, plugin.SampleConfig())
|
||||
}
|
||||
|
||||
func TestInit(t *testing.T) {
|
||||
plugin := &HTTP{
|
||||
DecryptionConfig: DecryptionConfig{
|
||||
Cipher: "AES128/CBC/PKCS#5",
|
||||
Aes: AesEncryptor{
|
||||
Key: config.NewSecret([]byte("7465737474657374657374746573740a")),
|
||||
Vec: config.NewSecret([]byte("7465737474657374657374746573740a")),
|
||||
},
|
||||
},
|
||||
}
|
||||
require.NoError(t, plugin.Init())
|
||||
}
|
||||
|
||||
func TestInitErrors(t *testing.T) {
|
||||
plugin := &HTTP{Transformation: "{some: malformed"}
|
||||
require.ErrorContains(t, plugin.Init(), "setting up data transformation failed")
|
||||
|
||||
plugin = &HTTP{DecryptionConfig: DecryptionConfig{Cipher: "non-existing/CBC/lala"}}
|
||||
require.ErrorContains(t, plugin.Init(), "creating decryptor failed: unknown cipher")
|
||||
}
|
||||
|
||||
func TestSetNotSupported(t *testing.T) {
|
||||
plugin := &HTTP{}
|
||||
require.NoError(t, plugin.Init())
|
||||
|
||||
require.ErrorContains(t, plugin.Set("key", "value"), "setting secrets not supported")
|
||||
}
|
||||
|
||||
func TestGetErrors(t *testing.T) {
|
||||
plugin := &HTTP{
|
||||
DecryptionConfig: DecryptionConfig{
|
||||
Cipher: "AES256/CBC/PKCS#5",
|
||||
Aes: AesEncryptor{
|
||||
Key: config.NewSecret([]byte("63238c069e3c5d6aaa20048c43ce4ed0a910eef95f22f55bacdddacafa06b656")),
|
||||
Vec: config.NewSecret([]byte("61737570657273656372657469763432")),
|
||||
},
|
||||
},
|
||||
}
|
||||
require.NoError(t, plugin.Init())
|
||||
|
||||
_, err := plugin.Get("OMG")
|
||||
require.ErrorContains(t, err, "not found")
|
||||
|
||||
plugin.cache = map[string]string{"test": "aedMZXaLR246OHHjVtJKXQ=X"}
|
||||
_, err = plugin.Get("test")
|
||||
require.ErrorContains(t, err, "base64 decoding failed")
|
||||
}
|
||||
|
||||
func TestResolver(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
if _, err := w.Write([]byte(`{"test": "aedMZXaLR246OHHjVtJKXQ=="}`)); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
plugin := &HTTP{
|
||||
URL: server.URL,
|
||||
DecryptionConfig: DecryptionConfig{
|
||||
Cipher: "AES256/CBC/PKCS#5",
|
||||
Aes: AesEncryptor{
|
||||
Key: config.NewSecret([]byte("63238c069e3c5d6aaa20048c43ce4ed0a910eef95f22f55bacdddacafa06b656")),
|
||||
Vec: config.NewSecret([]byte("61737570657273656372657469763432")),
|
||||
},
|
||||
},
|
||||
}
|
||||
plugin.Timeout = config.Duration(200 * time.Millisecond)
|
||||
require.NoError(t, plugin.Init())
|
||||
|
||||
resolver, err := plugin.GetResolver("test")
|
||||
require.NoError(t, err)
|
||||
|
||||
s, _, err := resolver()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "password-B", string(s))
|
||||
}
|
||||
|
||||
func TestGetResolverErrors(t *testing.T) {
|
||||
dummy, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
require.NoError(t, err)
|
||||
defer dummy.Close()
|
||||
|
||||
plugin := &HTTP{
|
||||
URL: "http://" + dummy.Addr().String(),
|
||||
}
|
||||
plugin.Timeout = config.Duration(200 * time.Millisecond)
|
||||
require.NoError(t, plugin.Init())
|
||||
|
||||
_, err = plugin.GetResolver("test")
|
||||
require.ErrorContains(t, err, "context deadline exceeded")
|
||||
dummy.Close()
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
if _, err = w.Write([]byte(`[{"test": "aedMZXaLR246OHHjVtJKXQ=="}]`)); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
plugin = &HTTP{
|
||||
URL: server.URL,
|
||||
DecryptionConfig: DecryptionConfig{
|
||||
Cipher: "AES256/CBC/PKCS#5",
|
||||
Aes: AesEncryptor{
|
||||
Key: config.NewSecret([]byte("63238c069e3c5d6aaa20048c43ce4ed0a910eef95f22f55bacdddacafa06b656")),
|
||||
Vec: config.NewSecret([]byte("61737570657273656372657469763432")),
|
||||
},
|
||||
},
|
||||
}
|
||||
plugin.Timeout = config.Duration(200 * time.Millisecond)
|
||||
require.NoError(t, plugin.Init())
|
||||
|
||||
_, err = plugin.GetResolver("test")
|
||||
require.ErrorContains(t, err, "maybe missing or wrong data transformation")
|
||||
|
||||
plugin.Transformation = "{awe:skds}"
|
||||
require.NoError(t, plugin.Init())
|
||||
|
||||
_, err = plugin.GetResolver("test")
|
||||
require.ErrorContains(t, err, "transforming data failed")
|
||||
}
|
||||
|
||||
func TestInvalidServerResponse(t *testing.T) {
|
||||
dummy, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
require.NoError(t, err)
|
||||
defer dummy.Close()
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
if _, err = w.Write([]byte(`[somerandomebytes`)); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
plugin := &HTTP{
|
||||
URL: server.URL,
|
||||
DecryptionConfig: DecryptionConfig{
|
||||
Cipher: "AES256/CBC/PKCS#5",
|
||||
Aes: AesEncryptor{
|
||||
Key: config.NewSecret([]byte("63238c069e3c5d6aaa20048c43ce4ed0a910eef95f22f55bacdddacafa06b656")),
|
||||
Vec: config.NewSecret([]byte("61737570657273656372657469763432")),
|
||||
},
|
||||
},
|
||||
}
|
||||
plugin.Timeout = config.Duration(200 * time.Millisecond)
|
||||
require.NoError(t, plugin.Init())
|
||||
|
||||
_, err = plugin.GetResolver("test")
|
||||
require.Error(t, err)
|
||||
var expectedErr *json.SyntaxError
|
||||
require.ErrorAs(t, err, &expectedErr)
|
||||
}
|
||||
|
||||
func TestAdditionalHeaders(t *testing.T) {
|
||||
dummy, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
require.NoError(t, err)
|
||||
defer dummy.Close()
|
||||
|
||||
var actual http.Header
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
actual = r.Header.Clone()
|
||||
if r.Host != "" {
|
||||
actual.Add("host", r.Host)
|
||||
}
|
||||
if _, err = w.Write([]byte(`{"test": "aedMZXaLR246OHHjVtJKXQ=="}`)); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
plugin := &HTTP{
|
||||
URL: server.URL,
|
||||
Headers: map[string]string{
|
||||
"host": "a.host.com",
|
||||
"foo": "bar",
|
||||
},
|
||||
DecryptionConfig: DecryptionConfig{
|
||||
Cipher: "AES256/CBC/PKCS#5",
|
||||
Aes: AesEncryptor{
|
||||
Key: config.NewSecret([]byte("63238c069e3c5d6aaa20048c43ce4ed0a910eef95f22f55bacdddacafa06b656")),
|
||||
Vec: config.NewSecret([]byte("61737570657273656372657469763432")),
|
||||
},
|
||||
},
|
||||
}
|
||||
plugin.Timeout = config.Duration(200 * time.Millisecond)
|
||||
require.NoError(t, plugin.Init())
|
||||
|
||||
require.NoError(t, plugin.download())
|
||||
|
||||
secret, err := plugin.Get("test")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "password-B", string(secret))
|
||||
|
||||
for k, v := range plugin.Headers {
|
||||
av := actual.Get(k)
|
||||
require.NotEmptyf(t, av, "header %q not found", k)
|
||||
require.Equal(t, v, av, "mismatch for header %q", k)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerReturnCodes(t *testing.T) {
|
||||
dummy, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
require.NoError(t, err)
|
||||
defer dummy.Close()
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/", "/200":
|
||||
if _, err = w.Write([]byte(`{}`)); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
case "/201":
|
||||
w.WriteHeader(201)
|
||||
case "/300":
|
||||
w.WriteHeader(300)
|
||||
if _, err = w.Write([]byte(`{}`)); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
case "/401":
|
||||
w.WriteHeader(401)
|
||||
default:
|
||||
w.WriteHeader(404)
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
plugin := &HTTP{
|
||||
URL: server.URL,
|
||||
SuccessStatusCodes: []int{200, 300},
|
||||
}
|
||||
plugin.Timeout = config.Duration(200 * time.Millisecond)
|
||||
require.NoError(t, plugin.Init())
|
||||
|
||||
// 200 and 300 should not return an error
|
||||
require.NoError(t, plugin.download())
|
||||
plugin.URL = server.URL + "/200"
|
||||
require.NoError(t, plugin.download())
|
||||
plugin.URL = server.URL + "/300"
|
||||
require.NoError(t, plugin.download())
|
||||
|
||||
// other error codes should cause errors
|
||||
plugin.URL = server.URL + "/201"
|
||||
require.ErrorContains(t, plugin.download(), "received status code 201")
|
||||
plugin.URL = server.URL + "/401"
|
||||
require.ErrorContains(t, plugin.download(), "received status code 401")
|
||||
plugin.URL = server.URL + "/somewhere"
|
||||
require.ErrorContains(t, plugin.download(), "received status code 404")
|
||||
}
|
||||
|
||||
func TestAuthenticationBasic(t *testing.T) {
|
||||
dummy, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
require.NoError(t, err)
|
||||
defer dummy.Close()
|
||||
|
||||
var header http.Header
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
header = r.Header
|
||||
if _, err = w.Write([]byte(`{}`)); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
plugin := &HTTP{
|
||||
URL: server.URL,
|
||||
Username: config.NewSecret([]byte("myuser")),
|
||||
Password: config.NewSecret([]byte("mypass")),
|
||||
SuccessStatusCodes: []int{200, 300},
|
||||
}
|
||||
plugin.Timeout = config.Duration(200 * time.Millisecond)
|
||||
require.NoError(t, plugin.Init())
|
||||
require.NoError(t, plugin.download())
|
||||
|
||||
auth := header.Get("Authorization")
|
||||
require.NotEmpty(t, auth)
|
||||
require.Equal(t, "Basic bXl1c2VyOm15cGFzcw==", auth)
|
||||
}
|
||||
|
||||
func TestAuthenticationToken(t *testing.T) {
|
||||
dummy, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
require.NoError(t, err)
|
||||
defer dummy.Close()
|
||||
|
||||
var header http.Header
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
header = r.Header
|
||||
if _, err = w.Write([]byte(`{}`)); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
token := "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJUaWdlciIsImlhdCI6M..."
|
||||
plugin := &HTTP{
|
||||
URL: server.URL,
|
||||
Token: config.NewSecret([]byte(token)),
|
||||
SuccessStatusCodes: []int{200, 300},
|
||||
}
|
||||
plugin.Timeout = config.Duration(200 * time.Millisecond)
|
||||
require.NoError(t, plugin.Init())
|
||||
require.NoError(t, plugin.download())
|
||||
|
||||
auth := header.Get("Authorization")
|
||||
require.NotEmpty(t, auth)
|
||||
require.Equal(t, "Bearer "+token, auth)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue