438 lines
12 KiB
Go
438 lines
12 KiB
Go
|
package mongodb
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"path/filepath"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"github.com/docker/go-connections/nat"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
"github.com/testcontainers/testcontainers-go/wait"
|
||
|
|
||
|
"github.com/influxdata/telegraf/config"
|
||
|
"github.com/influxdata/telegraf/plugins/common/tls"
|
||
|
"github.com/influxdata/telegraf/testutil"
|
||
|
)
|
||
|
|
||
|
func TestConnectAndWriteIntegrationNoAuth(t *testing.T) {
|
||
|
if testing.Short() {
|
||
|
t.Skip("Skipping integration test in short mode")
|
||
|
}
|
||
|
|
||
|
servicePort := "27017"
|
||
|
container := testutil.Container{
|
||
|
Image: "mongo",
|
||
|
ExposedPorts: []string{servicePort},
|
||
|
WaitingFor: wait.ForAll(
|
||
|
wait.NewHTTPStrategy("/").WithPort(nat.Port(servicePort)),
|
||
|
wait.ForLog("Waiting for connections"),
|
||
|
),
|
||
|
}
|
||
|
err := container.Start()
|
||
|
require.NoError(t, err, "failed to start container")
|
||
|
defer container.Terminate()
|
||
|
|
||
|
// Run test
|
||
|
plugin := &MongoDB{
|
||
|
Dsn: fmt.Sprintf("mongodb://%s:%s",
|
||
|
container.Address,
|
||
|
container.Ports[servicePort],
|
||
|
),
|
||
|
AuthenticationType: "NONE",
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
MetricGranularity: "seconds",
|
||
|
}
|
||
|
|
||
|
// validate config
|
||
|
require.NoError(t, plugin.Init())
|
||
|
require.NoError(t, plugin.Connect())
|
||
|
require.NoError(t, plugin.Write(testutil.MockMetrics()))
|
||
|
require.NoError(t, plugin.Close())
|
||
|
}
|
||
|
|
||
|
func TestConnectAndWriteIntegrationSCRAMAuth(t *testing.T) {
|
||
|
if testing.Short() {
|
||
|
t.Skip("Skipping integration test in short mode")
|
||
|
}
|
||
|
|
||
|
initdb, err := filepath.Abs("testdata/auth_scram/setup.js")
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
servicePort := "27017"
|
||
|
container := testutil.Container{
|
||
|
Image: "mongo",
|
||
|
ExposedPorts: []string{servicePort},
|
||
|
Files: map[string]string{
|
||
|
"/docker-entrypoint-initdb.d/setup.js": initdb,
|
||
|
},
|
||
|
WaitingFor: wait.ForAll(
|
||
|
wait.NewHTTPStrategy("/").WithPort(nat.Port(servicePort)),
|
||
|
wait.ForLog("Waiting for connections").WithOccurrence(2),
|
||
|
),
|
||
|
}
|
||
|
err = container.Start()
|
||
|
require.NoError(t, err, "failed to start container")
|
||
|
defer container.Terminate()
|
||
|
|
||
|
tests := []struct {
|
||
|
name string
|
||
|
plugin *MongoDB
|
||
|
connErrFunc func(t *testing.T, err error)
|
||
|
}{
|
||
|
{
|
||
|
name: "success with scram authentication",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: fmt.Sprintf("mongodb://%s:%s/admin",
|
||
|
container.Address, container.Ports[servicePort]),
|
||
|
AuthenticationType: "SCRAM",
|
||
|
Username: config.NewSecret([]byte("root")),
|
||
|
Password: config.NewSecret([]byte("changeme")),
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
MetricGranularity: "seconds",
|
||
|
},
|
||
|
connErrFunc: func(t *testing.T, err error) {
|
||
|
require.NoError(t, err)
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "fail with scram authentication bad password",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: fmt.Sprintf("mongodb://%s:%s/admin",
|
||
|
container.Address, container.Ports[servicePort]),
|
||
|
AuthenticationType: "SCRAM",
|
||
|
Username: config.NewSecret([]byte("root")),
|
||
|
Password: config.NewSecret([]byte("root")),
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
MetricGranularity: "seconds",
|
||
|
ServerSelectTimeout: config.Duration(time.Duration(5) * time.Second),
|
||
|
},
|
||
|
connErrFunc: func(t *testing.T, err error) {
|
||
|
require.Error(t, err)
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for _, tt := range tests {
|
||
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
// validate config
|
||
|
err := tt.plugin.Init()
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
if err == nil {
|
||
|
// connect
|
||
|
err = tt.plugin.Connect()
|
||
|
tt.connErrFunc(t, err)
|
||
|
|
||
|
if err == nil {
|
||
|
// insert mock metrics
|
||
|
err = tt.plugin.Write(testutil.MockMetrics())
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
// cleanup
|
||
|
err = tt.plugin.Close()
|
||
|
require.NoError(t, err)
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestConnectAndWriteIntegrationX509Auth(t *testing.T) {
|
||
|
if testing.Short() {
|
||
|
t.Skip("Skipping integration test in short mode")
|
||
|
}
|
||
|
|
||
|
pki := testutil.NewPKI("../../../testutil/pki")
|
||
|
|
||
|
// bind mount files
|
||
|
initdb, err := filepath.Abs("testdata/auth_x509/setup.js")
|
||
|
require.NoError(t, err)
|
||
|
cacert, err := filepath.Abs(pki.CACertPath())
|
||
|
require.NoError(t, err)
|
||
|
serverpem, err := filepath.Abs(pki.ServerCertAndKeyPath())
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
servicePort := "27017"
|
||
|
container := testutil.Container{
|
||
|
Image: "mongo",
|
||
|
ExposedPorts: []string{servicePort},
|
||
|
Files: map[string]string{
|
||
|
"/docker-entrypoint-initdb.d/setup.js": initdb,
|
||
|
"/cacert.pem": cacert,
|
||
|
"/server.pem": serverpem,
|
||
|
},
|
||
|
Entrypoint: []string{
|
||
|
"docker-entrypoint.sh",
|
||
|
"--auth", "--setParameter", "authenticationMechanisms=MONGODB-X509",
|
||
|
"--tlsMode", "preferTLS",
|
||
|
"--tlsCAFile", "/cacert.pem",
|
||
|
"--tlsCertificateKeyFile", "/server.pem",
|
||
|
},
|
||
|
WaitingFor: wait.ForAll(
|
||
|
wait.NewHTTPStrategy("/").WithPort(nat.Port(servicePort)),
|
||
|
wait.ForLog("Waiting for connections").WithOccurrence(2),
|
||
|
),
|
||
|
}
|
||
|
err = container.Start()
|
||
|
require.NoError(t, err, "failed to start container")
|
||
|
defer container.Terminate()
|
||
|
|
||
|
tests := []struct {
|
||
|
name string
|
||
|
plugin *MongoDB
|
||
|
connErrFunc func(t *testing.T, err error)
|
||
|
}{
|
||
|
{
|
||
|
name: "success with x509 authentication",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: fmt.Sprintf("mongodb://%s:%s",
|
||
|
container.Address, container.Ports[servicePort]),
|
||
|
AuthenticationType: "X509",
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
MetricGranularity: "seconds",
|
||
|
ServerSelectTimeout: config.Duration(time.Duration(5) * time.Second),
|
||
|
TTL: config.Duration(time.Duration(5) * time.Minute),
|
||
|
ClientConfig: tls.ClientConfig{
|
||
|
TLSCA: pki.CACertPath(),
|
||
|
TLSKey: pki.ClientCertAndKeyPath(),
|
||
|
InsecureSkipVerify: false,
|
||
|
},
|
||
|
},
|
||
|
connErrFunc: func(t *testing.T, err error) {
|
||
|
require.NoError(t, err)
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "success with x509 authentication using encrypted key file",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: fmt.Sprintf("mongodb://%s:%s",
|
||
|
container.Address, container.Ports[servicePort]),
|
||
|
AuthenticationType: "X509",
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
MetricGranularity: "seconds",
|
||
|
ServerSelectTimeout: config.Duration(time.Duration(5) * time.Second),
|
||
|
TTL: config.Duration(time.Duration(5) * time.Minute),
|
||
|
ClientConfig: tls.ClientConfig{
|
||
|
TLSCA: pki.CACertPath(),
|
||
|
TLSKey: pki.ClientCertAndEncKeyPath(),
|
||
|
TLSKeyPwd: "changeme",
|
||
|
InsecureSkipVerify: false,
|
||
|
},
|
||
|
},
|
||
|
connErrFunc: func(t *testing.T, err error) {
|
||
|
require.NoError(t, err)
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "success with x509 authentication missing ca and using insceure tls",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: fmt.Sprintf("mongodb://%s:%s",
|
||
|
container.Address, container.Ports[servicePort]),
|
||
|
AuthenticationType: "X509",
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
MetricGranularity: "seconds",
|
||
|
ServerSelectTimeout: config.Duration(time.Duration(5) * time.Second),
|
||
|
TTL: config.Duration(time.Duration(5) * time.Minute),
|
||
|
ClientConfig: tls.ClientConfig{
|
||
|
TLSKey: pki.ClientCertAndKeyPath(),
|
||
|
InsecureSkipVerify: true,
|
||
|
},
|
||
|
},
|
||
|
connErrFunc: func(t *testing.T, err error) {
|
||
|
require.NoError(t, err)
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "fail with x509 authentication missing ca",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: fmt.Sprintf("mongodb://%s:%s",
|
||
|
container.Address, container.Ports[servicePort]),
|
||
|
AuthenticationType: "X509",
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
MetricGranularity: "seconds",
|
||
|
ServerSelectTimeout: config.Duration(time.Duration(5) * time.Second),
|
||
|
TTL: config.Duration(time.Duration(5) * time.Minute),
|
||
|
ClientConfig: tls.ClientConfig{
|
||
|
TLSKey: pki.ClientCertAndKeyPath(),
|
||
|
InsecureSkipVerify: false,
|
||
|
},
|
||
|
},
|
||
|
connErrFunc: func(t *testing.T, err error) {
|
||
|
require.Error(t, err)
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "fail with x509 authentication using encrypted key file",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: fmt.Sprintf("mongodb://%s:%s",
|
||
|
container.Address, container.Ports[servicePort]),
|
||
|
AuthenticationType: "X509",
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
MetricGranularity: "seconds",
|
||
|
ServerSelectTimeout: config.Duration(time.Duration(5) * time.Second),
|
||
|
TTL: config.Duration(time.Duration(5) * time.Minute),
|
||
|
ClientConfig: tls.ClientConfig{
|
||
|
TLSCA: pki.CACertPath(),
|
||
|
TLSKey: pki.ClientCertAndEncKeyPath(),
|
||
|
TLSKeyPwd: "badpassword",
|
||
|
InsecureSkipVerify: false,
|
||
|
},
|
||
|
},
|
||
|
connErrFunc: func(t *testing.T, err error) {
|
||
|
require.Error(t, err)
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "fail with x509 authentication using invalid ca",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: fmt.Sprintf("mongodb://%s:%s",
|
||
|
container.Address, container.Ports[servicePort]),
|
||
|
AuthenticationType: "X509",
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
MetricGranularity: "seconds",
|
||
|
ServerSelectTimeout: config.Duration(time.Duration(5) * time.Second),
|
||
|
TTL: config.Duration(time.Duration(5) * time.Minute),
|
||
|
ClientConfig: tls.ClientConfig{
|
||
|
TLSCA: pki.ClientCertAndKeyPath(),
|
||
|
TLSKey: pki.ClientCertAndKeyPath(),
|
||
|
InsecureSkipVerify: false,
|
||
|
},
|
||
|
},
|
||
|
connErrFunc: func(t *testing.T, err error) {
|
||
|
require.Error(t, err)
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "fail with x509 authentication using invalid key",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: fmt.Sprintf("mongodb://%s:%s",
|
||
|
container.Address, container.Ports[servicePort]),
|
||
|
AuthenticationType: "X509",
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
MetricGranularity: "seconds",
|
||
|
ServerSelectTimeout: config.Duration(time.Duration(5) * time.Second),
|
||
|
TTL: config.Duration(time.Duration(5) * time.Minute),
|
||
|
ClientConfig: tls.ClientConfig{
|
||
|
TLSCA: pki.CACertPath(),
|
||
|
TLSKey: pki.CACertPath(),
|
||
|
InsecureSkipVerify: false,
|
||
|
},
|
||
|
},
|
||
|
connErrFunc: func(t *testing.T, err error) {
|
||
|
require.Error(t, err)
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for _, tt := range tests {
|
||
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
// validate config
|
||
|
err := tt.plugin.Init()
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
if err == nil {
|
||
|
// connect
|
||
|
err = tt.plugin.Connect()
|
||
|
tt.connErrFunc(t, err)
|
||
|
|
||
|
if err == nil {
|
||
|
// insert mock metrics
|
||
|
err = tt.plugin.Write(testutil.MockMetrics())
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
// cleanup
|
||
|
err = tt.plugin.Close()
|
||
|
require.NoError(t, err)
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestConfiguration(t *testing.T) {
|
||
|
tests := []struct {
|
||
|
name string
|
||
|
plugin *MongoDB
|
||
|
errFunc func(t *testing.T, err error)
|
||
|
}{
|
||
|
{
|
||
|
name: "fail with invalid connection string",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: "asdf1234",
|
||
|
AuthenticationType: "NONE",
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
MetricGranularity: "seconds",
|
||
|
TTL: config.Duration(time.Duration(5) * time.Minute),
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "fail with invalid metric granularity",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: "mongodb://localhost:27017",
|
||
|
AuthenticationType: "NONE",
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
MetricGranularity: "somerandomgranularitythatdoesntwork",
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "fail with scram authentication missing username field",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: "mongodb://localhost:27017",
|
||
|
AuthenticationType: "SCRAM",
|
||
|
Password: config.NewSecret([]byte("somerandompasswordthatwontwork")),
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
MetricGranularity: "seconds",
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "fail with scram authentication missing password field",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: "mongodb://localhost:27017",
|
||
|
AuthenticationType: "SCRAM",
|
||
|
Username: config.NewSecret([]byte("somerandomusernamethatwontwork")),
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
MetricGranularity: "seconds",
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for _, tt := range tests {
|
||
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
// validate config
|
||
|
err := tt.plugin.Init()
|
||
|
require.Error(t, err)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
tests = []struct {
|
||
|
name string
|
||
|
plugin *MongoDB
|
||
|
errFunc func(t *testing.T, err error)
|
||
|
}{
|
||
|
{
|
||
|
name: "success init with missing metric database",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: "mongodb://localhost:27017",
|
||
|
AuthenticationType: "NONE",
|
||
|
MetricGranularity: "seconds",
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "success init missing metric granularity",
|
||
|
plugin: &MongoDB{
|
||
|
Dsn: "mongodb://localhost:27017",
|
||
|
AuthenticationType: "NONE",
|
||
|
MetricDatabase: "telegraf_test",
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
for _, tt := range tests {
|
||
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
// validate config
|
||
|
err := tt.plugin.Init()
|
||
|
require.NoError(t, err)
|
||
|
})
|
||
|
}
|
||
|
}
|