Skip to content

Commit

Permalink
PMM-12153 reconfigure MySQL agent
Browse files Browse the repository at this point in the history
  • Loading branch information
ademidoff committed Mar 7, 2025
1 parent 8d11eb3 commit 8f69d8b
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 50 deletions.
82 changes: 43 additions & 39 deletions managed/services/agents/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,20 @@ import (
"github.com/percona/pmm/version"
)

var mysqlExporterVersionWithPluginCollector = version.MustParse("2.36.0-0")
var mysqlExporterVersion30 = version.MustParse("3.0.0-0")

// The mysqldExporterConfig returns desired configuration of mysqld_exporter process.
var (
mysqlExporterVersionWithPluginCollector = version.MustParse("2.36.0-0")
// TODO: put back to 3.2.0 before release
v3_2_0 = version.MustParse("3.1.0-0")
)

// mysqldExporterConfig returns desired configuration of mysqld_exporter process.
func mysqldExporterConfig(
node *models.Node,
service *models.Service,
exporter *models.Agent,
redactMode redactMode,
pmmAgentVersion *version.Parsed,
) *agentv1.SetStateRequest_AgentProcess {
) (*agentv1.SetStateRequest_AgentProcess, error) {
listenAddress := getExporterListenAddress(node, exporter)
tdp := exporter.TemplateDelimiters(service)

Expand Down Expand Up @@ -85,7 +87,7 @@ func mysqldExporterConfig(
args = append(args, "--collect.plugins")
}

if pmmAgentVersion.Less(mysqlExporterVersion30) {
if pmmAgentVersion.Less(v3_2_0) {
args = append(args, "--exporter.global-conn-pool")
}

Expand Down Expand Up @@ -115,35 +117,25 @@ func mysqldExporterConfig(

files := exporter.Files()
if files != nil {
// // Newer versions of exporter expect these to be provided in `my.cnf` file
// if pmmAgentVersion.Less(v3_2_0) {
for k := range files {
if pmmAgentVersion.Less(mysqlExporterVersion30) {
switch k {
case "tlsCa":
args = append(args, "--mysql.ssl-ca-file="+tdp.Left+" .TextFiles.tlsCa "+tdp.Right)
case "tlsCert":
args = append(args, "--mysql.ssl-cert-file="+tdp.Left+" .TextFiles.tlsCert "+tdp.Right)
case "tlsKey":
args = append(args, "--mysql.ssl-key-file="+tdp.Left+" .TextFiles.tlsKey "+tdp.Right)
default:
continue
}
} else {
switch k {
case "tlsCa":
args = append(args, "--tls.ca="+tdp.Left+" .TextFiles.tlsCa "+tdp.Right)
case "tlsCert":
args = append(args, "--tls.cert="+tdp.Left+" .TextFiles.tlsCert "+tdp.Right)
case "tlsKey":
args = append(args, "--tls.key="+tdp.Left+" .TextFiles.tlsKey "+tdp.Right)
default:
continue
}
switch k {
case "tlsCa":
args = append(args, "--mysql.ssl-ca-file="+tdp.Left+" .TextFiles.tlsCa "+tdp.Right)
case "tlsCert":
args = append(args, "--mysql.ssl-cert-file="+tdp.Left+" .TextFiles.tlsCert "+tdp.Right)
case "tlsKey":
args = append(args, "--mysql.ssl-key-file="+tdp.Left+" .TextFiles.tlsKey "+tdp.Right)
default:
continue
}
}
// }

if exporter.TLSSkipVerify {
if pmmAgentVersion.Less(mysqlExporterVersion30) {
args = append(args, "--mysql.ssl-insecure-skip-verify")
if pmmAgentVersion.Less(v3_2_0) {
args = append(args, "--mysql.ssl-skip-verify")
} else {
args = append(args, "--tls.insecure-skip-verify")
}
Expand All @@ -154,24 +146,36 @@ func mysqldExporterConfig(

sort.Strings(args)

var env []string
if pmmAgentVersion.Less(mysqlExporterVersion30) {
env = []string{
fmt.Sprintf("DATA_SOURCE_NAME=%s", exporter.DSN(service, models.DSNParams{DialTimeout: time.Second, Database: ""}, nil, pmmAgentVersion)),
fmt.Sprintf("HTTP_AUTH=pmm:%s", exporter.GetAgentPassword()),
}
}
res := &agentv1.SetStateRequest_AgentProcess{
Type: inventoryv1.AgentType_AGENT_TYPE_MYSQLD_EXPORTER,
TemplateLeftDelim: tdp.Left,
TemplateRightDelim: tdp.Right,
Args: args,
Env: env,
TextFiles: files,
}
if pmmAgentVersion.Less(v3_2_0) {
env := []string{
fmt.Sprintf("DATA_SOURCE_NAME=%s", exporter.DSN(service, models.DSNParams{DialTimeout: time.Second, Database: ""}, nil, pmmAgentVersion)),
fmt.Sprintf("HTTP_AUTH=pmm:%s", exporter.GetAgentPassword()),
}
res.Env = env
} else {
cfg, err := exporter.BuildMyCnfConfig(service)
if err != nil {
return nil, err
}
res.TextFiles["myCnf"] = cfg
res.Args = append(res.Args, "--config.my-cnf="+tdp.Left+" .TextFiles.myCnf "+tdp.Right)

if err := ensureAuthParams(exporter, res, pmmAgentVersion, v3_2_0, true); err != nil {
return nil, err
}
}

if redactMode != exposeSecrets {
res.RedactWords = redactWords(exporter)
}
return res
return res, nil
}

// qanMySQLPerfSchemaAgentConfig returns desired configuration of qan-mysql-perfschema built-in agent.
Expand Down
30 changes: 20 additions & 10 deletions managed/services/agents/mysql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func TestMySQLdExporterConfig(t *testing.T) {
}
pmmAgentVersion := version.MustParse("2.21.0")

actual := mysqldExporterConfig(node, mysql, exporter, redactSecrets, pmmAgentVersion)
actual, err := mysqldExporterConfig(node, mysql, exporter, redactSecrets, pmmAgentVersion)
expected := &agentv1.SetStateRequest_AgentProcess{
Type: inventoryv1.AgentType_AGENT_TYPE_MYSQLD_EXPORTER,
TemplateLeftDelim: "{{",
Expand Down Expand Up @@ -99,19 +99,22 @@ func TestMySQLdExporterConfig(t *testing.T) {
RedactWords: []string{"s3cur3 p@$$w0r4.", "agent-password"},
}
requireNoDuplicateFlags(t, actual.Args)
require.NoError(t, err)
require.Equal(t, expected.Args, actual.Args)
require.Equal(t, expected.Env, actual.Env)
require.Equal(t, expected, actual)

t.Run("EmptyPassword", func(t *testing.T) {
exporter.Password = nil
actual := mysqldExporterConfig(node, mysql, exporter, exposeSecrets, pmmAgentVersion)
actual, err := mysqldExporterConfig(node, mysql, exporter, exposeSecrets, pmmAgentVersion)
require.NoError(t, err)
assert.Equal(t, "DATA_SOURCE_NAME=username@tcp(1.2.3.4:3306)/?timeout=1s", actual.Env[0])
})

t.Run("EmptyUsername", func(t *testing.T) {
exporter.Username = nil
actual := mysqldExporterConfig(node, mysql, exporter, exposeSecrets, pmmAgentVersion)
actual, err := mysqldExporterConfig(node, mysql, exporter, exposeSecrets, pmmAgentVersion)
require.NoError(t, err)
assert.Equal(t, "DATA_SOURCE_NAME=tcp(1.2.3.4:3306)/?timeout=1s", actual.Env[0])
})

Expand All @@ -122,14 +125,15 @@ func TestMySQLdExporterConfig(t *testing.T) {
TLSCert: "content-of-tls-certificate-key",
TLSKey: "content-of-tls-key",
}
actual := mysqldExporterConfig(node, mysql, exporter, exposeSecrets, pmmAgentVersion)
actual, err := mysqldExporterConfig(node, mysql, exporter, exposeSecrets, pmmAgentVersion)
expected := "DATA_SOURCE_NAME=tcp(1.2.3.4:3306)/?timeout=1s&tls=custom"
assert.Equal(t, expected, actual.Env[0])
expectedFiles := map[string]string{
"tlsCa": exporter.MySQLOptions.TLSCa,
"tlsCert": exporter.MySQLOptions.TLSCert,
"tlsKey": exporter.MySQLOptions.TLSKey,
}
require.NoError(t, err)
assert.Equal(t, expectedFiles, actual.TextFiles)
})
}
Expand Down Expand Up @@ -158,7 +162,7 @@ func TestMySQLdExporterConfigTablestatsGroupDisabled(t *testing.T) {
}
pmmAgentVersion := version.MustParse("2.24.0")

actual := mysqldExporterConfig(node, mysql, exporter, redactSecrets, pmmAgentVersion)
actual, err := mysqldExporterConfig(node, mysql, exporter, redactSecrets, pmmAgentVersion)
expected := &agentv1.SetStateRequest_AgentProcess{
Type: inventoryv1.AgentType_AGENT_TYPE_MYSQLD_EXPORTER,
TemplateLeftDelim: "{{",
Expand Down Expand Up @@ -210,31 +214,36 @@ func TestMySQLdExporterConfigTablestatsGroupDisabled(t *testing.T) {
},
}
requireNoDuplicateFlags(t, actual.Args)
require.NoError(t, err)
require.Equal(t, expected.Args, actual.Args)
require.Equal(t, expected.Env, actual.Env)
require.Equal(t, expected, actual)

t.Run("EmptyPassword", func(t *testing.T) {
exporter.Password = nil
actual := mysqldExporterConfig(node, mysql, exporter, exposeSecrets, pmmAgentVersion)
actual, err := mysqldExporterConfig(node, mysql, exporter, exposeSecrets, pmmAgentVersion)
require.NoError(t, err)
assert.Equal(t, "DATA_SOURCE_NAME=username@tcp(1.2.3.4:3306)/?timeout=1s&tls=custom", actual.Env[0])
})

t.Run("EmptyUsername", func(t *testing.T) {
exporter.Username = nil
actual := mysqldExporterConfig(node, mysql, exporter, exposeSecrets, pmmAgentVersion)
actual, err := mysqldExporterConfig(node, mysql, exporter, exposeSecrets, pmmAgentVersion)
require.NoError(t, err)
assert.Equal(t, "DATA_SOURCE_NAME=tcp(1.2.3.4:3306)/?timeout=1s&tls=custom", actual.Env[0])
})

t.Run("V236_EnablesPluginCollector", func(t *testing.T) {
pmmAgentVersion := version.MustParse("2.36.0")
actual := mysqldExporterConfig(node, mysql, exporter, exposeSecrets, pmmAgentVersion)
actual, err := mysqldExporterConfig(node, mysql, exporter, exposeSecrets, pmmAgentVersion)
require.NoError(t, err)
assert.Contains(t, actual.Args, "--collect.plugins")
})

t.Run("beforeV236_NoPluginCollector", func(t *testing.T) {
pmmAgentVersion := version.MustParse("2.35.0")
actual := mysqldExporterConfig(node, mysql, exporter, exposeSecrets, pmmAgentVersion)
actual, err := mysqldExporterConfig(node, mysql, exporter, exposeSecrets, pmmAgentVersion)
require.NoError(t, err)
assert.NotContains(t, actual.Args, "--collect.plugins")
})
}
Expand All @@ -259,7 +268,7 @@ func TestMySQLdExporterConfigDisabledCollectors(t *testing.T) {
}
pmmAgentVersion := version.MustParse("2.24.0")

actual := mysqldExporterConfig(node, mysql, exporter, redactSecrets, pmmAgentVersion)
actual, err := mysqldExporterConfig(node, mysql, exporter, redactSecrets, pmmAgentVersion)
expected := &agentv1.SetStateRequest_AgentProcess{
Type: inventoryv1.AgentType_AGENT_TYPE_MYSQLD_EXPORTER,
TemplateLeftDelim: "{{",
Expand Down Expand Up @@ -307,6 +316,7 @@ func TestMySQLdExporterConfigDisabledCollectors(t *testing.T) {
RedactWords: []string{"s3cur3 p@$$w0r4."},
}
requireNoDuplicateFlags(t, actual.Args)
require.NoError(t, err)
require.Equal(t, expected.Args, actual.Args)
require.Equal(t, expected.Env, actual.Env)
require.Equal(t, expected, actual)
Expand Down
6 changes: 5 additions & 1 deletion managed/services/agents/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,11 @@ func (u *StateUpdater) sendSetStateRequest(ctx context.Context, agent *pmmAgentI
node, _ := models.FindNodeByID(u.db.Querier, pointer.GetString(pmmAgent.RunsOnNodeID))
switch row.AgentType { //nolint:exhaustive
case models.MySQLdExporterType:
agentProcesses[row.AgentID] = mysqldExporterConfig(node, service, row, redactMode, pmmAgentVersion)
cfg, err := mysqldExporterConfig(node, service, row, redactMode, pmmAgentVersion)
if err != nil {
return err
}
agentProcesses[row.AgentID] = cfg
case models.MongoDBExporterType:
cfg, err := mongodbExporterConfig(node, service, row, redactMode, pmmAgentVersion)
if err != nil {
Expand Down

0 comments on commit 8f69d8b

Please sign in to comment.