fix(inputs.mysql): Handle custom TLS configs correctly (#15493)
This commit is contained in:
parent
d8fb6e4c98
commit
53ae9841d0
|
|
@ -7,6 +7,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
|
@ -26,6 +27,8 @@ import (
|
|||
//go:embed sample.conf
|
||||
var sampleConfig string
|
||||
|
||||
var tlsRe = regexp.MustCompile(`([\?&])(?:tls=custom)($|&)`)
|
||||
|
||||
type Mysql struct {
|
||||
Servers []*config.Secret `toml:"servers"`
|
||||
PerfEventsStatementsDigestTextLimit int64 `toml:"perf_events_statements_digest_text_limit"`
|
||||
|
|
@ -52,9 +55,9 @@ type Mysql struct {
|
|||
PerfSummaryEvents []string `toml:"perf_summary_events"`
|
||||
IntervalSlow config.Duration `toml:"interval_slow"`
|
||||
MetricVersion int `toml:"metric_version"`
|
||||
|
||||
Log telegraf.Logger `toml:"-"`
|
||||
Log telegraf.Logger `toml:"-"`
|
||||
tls.ClientConfig
|
||||
|
||||
lastT time.Time
|
||||
getStatusQuery string
|
||||
loggedConvertFields map[string]bool
|
||||
|
|
@ -115,6 +118,12 @@ func (m *Mysql) Init() error {
|
|||
}
|
||||
dsn := dsnSecret.String()
|
||||
dsnSecret.Destroy()
|
||||
|
||||
// Reference the custom TLS config of _THIS_ plugin instance
|
||||
if tlsRe.MatchString(dsn) {
|
||||
dsn = tlsRe.ReplaceAllString(dsn, "${1}tls="+tlsid+"${2}")
|
||||
}
|
||||
|
||||
conf, err := mysql.ParseDSN(dsn)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing %q failed: %w", dsn, err)
|
||||
|
|
@ -125,14 +134,10 @@ func (m *Mysql) Init() error {
|
|||
conf.Timeout = time.Second * 5
|
||||
}
|
||||
|
||||
// Reference the custom TLS config of _THIS_ plugin instance
|
||||
if conf.TLSConfig == "custom" {
|
||||
conf.TLSConfig = tlsid
|
||||
}
|
||||
|
||||
if err := server.Set([]byte(conf.FormatDSN())); err != nil {
|
||||
return fmt.Errorf("replacing server %q failed: %w", dsn, err)
|
||||
}
|
||||
|
||||
m.Servers[i] = server
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package mysql
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
|
@ -11,6 +13,7 @@ import (
|
|||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
|
||||
"github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/plugins/common/tls"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
|
|
@ -295,9 +298,118 @@ func TestMysqlDNSAddTimeout(t *testing.T) {
|
|||
Servers: []*config.Secret{&s},
|
||||
}
|
||||
require.NoError(t, m.Init())
|
||||
equal, err := m.Servers[0].EqualTo([]byte(tt.output))
|
||||
require.Len(t, m.Servers, 1)
|
||||
dsn, err := m.Servers[0].Get()
|
||||
require.NoError(t, err)
|
||||
require.True(t, equal)
|
||||
defer dsn.Destroy()
|
||||
require.Equal(t, tt.output, dsn.TemporaryString())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMysqlTLSCustomization(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
errmsg string
|
||||
}{
|
||||
{
|
||||
name: "custom only param",
|
||||
input: "root:passwd@tcp(192.168.1.1:3306)/?tls=custom",
|
||||
expected: "root:passwd@tcp(192.168.1.1:3306)/?timeout=5s&tls=custom-<id>",
|
||||
},
|
||||
{
|
||||
name: "custom start param",
|
||||
input: "root:passwd@tcp(192.168.1.1:3306)/?tls=custom&timeout=20s",
|
||||
expected: "root:passwd@tcp(192.168.1.1:3306)/?timeout=20s&tls=custom-<id>",
|
||||
},
|
||||
{
|
||||
name: "custom end param",
|
||||
input: "root:passwd@tcp(192.168.1.1:3306)/?timeout=20s&tls=custom",
|
||||
expected: "root:passwd@tcp(192.168.1.1:3306)/?timeout=20s&tls=custom-<id>",
|
||||
},
|
||||
{
|
||||
name: "custom middle param",
|
||||
input: "root:passwd@tcp(192.168.1.1:3306)/?timeout=20s&tls=custom&foo=bar",
|
||||
expected: "root:passwd@tcp(192.168.1.1:3306)/?timeout=20s&tls=custom-<id>&foo=bar",
|
||||
},
|
||||
{
|
||||
name: "non-custom param false",
|
||||
input: "root:passwd@tcp(192.168.1.1:3306)/?tls=false",
|
||||
expected: "root:passwd@tcp(192.168.1.1:3306)/?timeout=5s&tls=false",
|
||||
},
|
||||
{
|
||||
name: "non-custom param true",
|
||||
input: "root:passwd@tcp(192.168.1.1:3306)/?tls=true",
|
||||
expected: "root:passwd@tcp(192.168.1.1:3306)/?timeout=5s&tls=true",
|
||||
},
|
||||
{
|
||||
name: "non-custom param skip-verify",
|
||||
input: "root:passwd@tcp(192.168.1.1:3306)/?tls=skip-verify",
|
||||
expected: "root:passwd@tcp(192.168.1.1:3306)/?timeout=5s&tls=skip-verify",
|
||||
},
|
||||
{
|
||||
name: "non-custom param preferred",
|
||||
input: "root:passwd@tcp(192.168.1.1:3306)/?tls=preferred",
|
||||
expected: "root:passwd@tcp(192.168.1.1:3306)/?allowFallbackToPlaintext=true&timeout=5s&tls=preferred",
|
||||
},
|
||||
{
|
||||
name: "non-custom param customcfg",
|
||||
input: "root:passwd@tcp(192.168.1.1:3306)/?tls=customcfg",
|
||||
expected: "root:passwd@tcp(192.168.1.1:3306)/?tls=customcfg",
|
||||
errmsg: "invalid value / unknown config name: customcfg",
|
||||
},
|
||||
{
|
||||
name: "non-custom param custom-cfg",
|
||||
input: "root:passwd@tcp(192.168.1.1:3306)/?tls=custom-cfg",
|
||||
expected: "root:passwd@tcp(192.168.1.1:3306)/?tls=custom-cfg",
|
||||
errmsg: "invalid value / unknown config name: custom-cfg",
|
||||
},
|
||||
{
|
||||
name: "non-custom param custom-cfg and following",
|
||||
input: "root:passwd@tcp(192.168.1.1:3306)/?tls=custom-cfg&timeout=20s",
|
||||
expected: "root:passwd@tcp(192.168.1.1:3306)/?tls=custom-cfg&timeout=20s",
|
||||
errmsg: "invalid value / unknown config name: custom-cfg",
|
||||
},
|
||||
{
|
||||
name: "non-custom param notls keyword",
|
||||
input: "root:passwd@tcp(192.168.1.1:3306)/?timeout=20s¬ls=custom",
|
||||
expected: "root:passwd@tcp(192.168.1.1:3306)/?timeout=20s¬ls=custom",
|
||||
},
|
||||
}
|
||||
|
||||
customIDRe := regexp.MustCompile(`[\?&]tls=custom-([\w-]*)(?:$|&)`)
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
s := config.NewSecret([]byte(test.input))
|
||||
plugin := &Mysql{
|
||||
Servers: []*config.Secret{&s},
|
||||
ClientConfig: tls.ClientConfig{InsecureSkipVerify: true},
|
||||
}
|
||||
err := plugin.Init()
|
||||
if test.errmsg != "" {
|
||||
require.ErrorContains(t, err, test.errmsg)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
require.Len(t, plugin.Servers, 1)
|
||||
rs, err := plugin.Servers[0].Get()
|
||||
require.NoError(t, err)
|
||||
defer rs.Destroy()
|
||||
|
||||
// Replace the `<id>` part with a potential actual ID
|
||||
actual := rs.String()
|
||||
expected := test.expected
|
||||
if strings.Contains(expected, "<id>") {
|
||||
matches := customIDRe.FindStringSubmatch(actual)
|
||||
if len(matches) == 2 {
|
||||
expected = strings.Replace(expected, "<id>", matches[1], 1)
|
||||
}
|
||||
}
|
||||
|
||||
require.Equal(t, expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue