Skip to content
This repository has been archived by the owner on Jun 21, 2022. It is now read-only.

PMM-5364 SSL support for Mongo. #528

Merged
merged 63 commits into from
Dec 29, 2020
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
24f864e
PMM-5364 Deps.
Nov 20, 2020
ea95dc8
PMM-5364 Add new fields to add request.
Nov 20, 2020
47a6682
Merge branch 'PMM-2.0' into PMM-5364-ssl-mongo
Nov 23, 2020
a662d69
PMM-5364 Deps.
Nov 23, 2020
fd4f9d8
PMM-5364 Deps.
Nov 23, 2020
75957a9
Merge branch 'PMM-2.0' into PMM-5364-ssl-mongo
Nov 24, 2020
efde7c7
PMM-5364 Add new fields into DB.
Nov 24, 2020
a56f79e
PMM-5364 Reform.
Nov 24, 2020
69a3b8b
PMM-5364 Another fields changes.
Nov 24, 2020
9193e30
Merge branch 'PMM-2.0' into PMM-5364-ssl-mongo
Nov 25, 2020
9496688
PMM-5364 Deps.
Nov 25, 2020
f972d65
PMM-5364 Deps.
Nov 25, 2020
253409a
PMM-5364 Fields.
Nov 25, 2020
a4a17b4
PMM-5364 Deps.
Nov 26, 2020
4d66bd5
PMM-7026 One more revert.
Nov 26, 2020
af7afe2
Merge branch 'PMM-7026-revert-pt-mysql-summary' into PMM-5364-ssl-mongo
Nov 26, 2020
8d1b31f
PMM-7026 Deps.
Nov 26, 2020
f82e0c9
PMM-5364 Fix VM problem.
Nov 26, 2020
f6f9faa
PMM-5364 Changes fields into struct.
Nov 26, 2020
41286cf
PMM-5364 Fix.
Nov 26, 2020
664dcbc
PMM-5364 Changes.
Nov 26, 2020
34b9394
Merge branch 'PMM-2.0' into PMM-5364-ssl-mongo
Nov 27, 2020
aa8c5b6
PMM-5364 Deps.
Nov 27, 2020
b599a6b
PMM-5364 Gen.
Nov 27, 2020
5011bfa
Merge branch 'PMM-2.0' into PMM-5364-ssl-mongo
Nov 27, 2020
f327f9c
PMM-5364 Deps.
Nov 27, 2020
d3a1381
PMM-5364 Add TLS keys to MongoDBExplainAction request.
Nov 27, 2020
3fb47bd
PMM-5364 Remove old code.
Nov 30, 2020
ab5cb72
Merge branch 'PMM-2.0' into PMM-5364-ssl-mongo
Nov 30, 2020
bc7dcd3
PMM-5364 Changes.
Nov 30, 2020
eb46757
PMM-5364 Fix new db fields VM problem.
Nov 30, 2020
751ee2f
PMM-5364 Naming changes.
Nov 30, 2020
e348d0d
Merge branch 'PMM-2.0' into PMM-5364-ssl-mongo
Nov 30, 2020
c107db2
PMM-5364 Changes.
Nov 30, 2020
58b0578
Merge branch 'PMM-2.0' into PMM-5364-ssl-mongo
Nov 30, 2020
101f89b
PMM-5364 Deps.
Nov 30, 2020
31a8be3
Merge branch 'PMM-2.0' into PMM-5364-ssl-mongo
Nov 30, 2020
60d9809
PMM-5364 Deps.
Nov 30, 2020
306c65f
PMM-5364 Fix build.
Dec 1, 2020
1652ff5
Merge branch 'PMM-2.0' into PMM-5364-ssl-mongo
Dec 1, 2020
7a0ced3
PMM-5364 Fix test.
Dec 1, 2020
c97283e
PMM-5367 Changes.
Dec 1, 2020
0cc6c43
PMM-5364 Deps.
Dec 2, 2020
f489b8b
PMM-5364 Set default prefix to same.
Dec 2, 2020
4ad197d
PMM-5364 Places for paste creating certs.
Dec 2, 2020
37a9d52
PMM-5364 Fix test.
Dec 2, 2020
ded9715
PMM-5364 Fix test.
Dec 2, 2020
24347fa
Merge remote-tracking branch 'origin/PMM-2.0' into PMM-5364-ssl-mongo
BupycHuk Dec 17, 2020
8ea457f
PMM-5364 Make MongoDBOptions struct.
BupycHuk Dec 20, 2020
98198b0
PMM-5364 Fix tests.
BupycHuk Dec 20, 2020
941465a
PMM-5364 Use text files parameters as .TextFiles. .
BupycHuk Dec 20, 2020
f2e0552
PMM-5364 Use text files parameters as .TextFiles .
BupycHuk Dec 23, 2020
28b5209
PMM-5364 Refactoring .
BupycHuk Dec 24, 2020
73d3f0b
Merge remote-tracking branch 'origin/PMM-2.0' into PMM-5364-ssl-mongo
BupycHuk Dec 24, 2020
c724bbe
Merge remote-tracking branch 'origin/PMM-2.0' into PMM-5364-ssl-mongo
BupycHuk Dec 24, 2020
35bc3c4
PMM-5364 Fix connection checker.
BupycHuk Dec 24, 2020
34277f3
PMM-5364 Fix tests.
BupycHuk Dec 25, 2020
7362ed0
Merge branch 'PMM-2.0' into PMM-5364-ssl-mongo
AlekSi Dec 26, 2020
d7e037b
Merge branch 'PMM-2.0' into PMM-5364-ssl-mongo
AlekSi Dec 26, 2020
3298308
PMM-5364 Fix QAN MongoDB Profiler.
BupycHuk Dec 28, 2020
fe9163b
PMM-5364 Fix Explain Action for MongoDB SSL.
BupycHuk Dec 28, 2020
5c66b4b
Merge remote-tracking branch 'origin/PMM-2.0' into PMM-5364-ssl-mongo
BupycHuk Dec 29, 2020
db45059
PMM-5364 Fix merge conflicts.
BupycHuk Dec 29, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ required = [

[[constraint]]
name = "github.com/percona/pmm"
branch = "PMM-2.0"
branch = "PMM-5364-ssl-mongo"

[[constraint]]
name = "github.com/percona-platform/saas"
Expand Down
2 changes: 1 addition & 1 deletion Makefile.devcontainer
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ install-race: ## Install pmm-managed binaries with race detect
go build -race -v $(PMM_LD_FLAGS) -o $(PMM_RELEASE_PATH)/pmm-managed-starlark ./cmd/pmm-managed-starlark

PMM_TEST_PACKAGES ?= ./...
PMM_TEST_FLAGS ?= -timeout=60s
PMM_TEST_FLAGS ?= -timeout=90s
PMM_TEST_RUN_UPDATE ?= 0

test: ## Run tests.
Expand Down
22 changes: 22 additions & 0 deletions models/agent_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,25 @@ import (
"gopkg.in/reform.v1"
)

// MongoDBOptionsParams contains methods to create MongoDBOptions object.
type MongoDBOptionsParams interface {
GetTlsCertificateKey() string
GetTlsCertificateKeyFilePassword() string
GetTlsCa() string
}

// MongoDBOptionsFromRequest creates MongoDBOptionsParams object from request.
func MongoDBOptionsFromRequest(params MongoDBOptionsParams) *MongoDBOptions {
if params.GetTlsCertificateKey() != "" || params.GetTlsCertificateKeyFilePassword() != "" || params.GetTlsCa() != "" {
return &MongoDBOptions{
TLSCertificateKey: params.GetTlsCertificateKey(),
TLSCertificateKeyFilePassword: params.GetTlsCertificateKeyFilePassword(),
TLSCa: params.GetTlsCa(),
}
}
return nil
}

func checkUniqueAgentID(q *reform.Querier, id string) error {
if id == "" {
panic("empty Agent ID")
Expand Down Expand Up @@ -312,6 +331,7 @@ func createPMMAgentWithID(q *reform.Querier, id, runsOnNodeID string, customLabe
if err := agent.SetCustomLabels(customLabels); err != nil {
return nil, err
}

if err := q.Insert(agent); err != nil {
return nil, errors.WithStack(err)
}
Expand Down Expand Up @@ -449,6 +469,7 @@ type CreateAgentParams struct {
CustomLabels map[string]string
TLS bool
TLSSkipVerify bool
MongoDBOptions *MongoDBOptions
TableCountTablestatsGroupLimit int32
QueryExamplesDisabled bool
MaxQueryLogSize int64
Expand Down Expand Up @@ -500,6 +521,7 @@ func CreateAgent(q *reform.Querier, agentType AgentType, params *CreateAgentPara
Password: pointer.ToStringOrNil(params.Password),
TLS: params.TLS,
TLSSkipVerify: params.TLSSkipVerify,
MongoDBOptions: params.MongoDBOptions,
TableCountTablestatsGroupLimit: params.TableCountTablestatsGroupLimit,
QueryExamplesDisabled: params.QueryExamplesDisabled,
MaxQueryLogSize: params.MaxQueryLogSize,
Expand Down
94 changes: 90 additions & 4 deletions models/agent_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
package models

import (
"database/sql/driver"
"fmt"
"net"
"net/url"
"strconv"
"strings"
"time"

"github.com/AlekSi/pointer"
Expand All @@ -35,6 +37,9 @@ import (
// pmm-managed's PostgreSQL, qan-api's ClickHouse, and VictoriaMetrics.
type AgentType string

const certificateKeyFilePlaceholder = "certificateKeyFilePlaceholder"
const caFilePlaceholder = "caFilePlaceholder"

// Agent types (in the same order as in agents.proto).
const (
PMMAgentType AgentType = "pmm-agent"
Expand All @@ -56,11 +61,23 @@ const (
// PMMServerAgentID is a special Agent ID representing pmm-agent on PMM Server.
const PMMServerAgentID string = "pmm-server" // no /agent_id/ prefix

// MongoDBOptions represents structure for special MongoDB options.
type MongoDBOptions struct {
TLSCertificateKey string `json:"tls_certificate_key"`
TLSCertificateKeyFilePassword string `json:"tls_certificate_key_file_password"`
TLSCa string `json:"tls_ca"`
}

// Value implements database/sql/driver.Valuer interface. Should be defined on the value.
func (c MongoDBOptions) Value() (driver.Value, error) { return jsonValue(c) }

// Scan implements database/sql.Scanner interface. Should be defined on the pointer.
func (c *MongoDBOptions) Scan(src interface{}) error { return jsonScan(c, src) }

// PMMAgentWithPushMetricsSupport - version of pmmAgent,
// that support vmagent and push metrics mode
// will be released with PMM Agent v2.12.
// TODO fix it to 2.11.99 before release
var PMMAgentWithPushMetricsSupport = version.MustParse("2.11.1")
var PMMAgentWithPushMetricsSupport = version.MustParse("2.11.99")

// Agent represents Agent as stored in database.
//reform:agents
Expand Down Expand Up @@ -105,6 +122,8 @@ type Agent struct {
RDSBasicMetricsDisabled bool `reform:"rds_basic_metrics_disabled"`
RDSEnhancedMetricsDisabled bool `reform:"rds_enhanced_metrics_disabled"`
PushMetrics bool `reform:"push_metrics"`

MongoDBOptions *MongoDBOptions `reform:"mongo_db_tls_options"`
}

// BeforeInsert implements reform.BeforeInserter interface.
Expand Down Expand Up @@ -169,13 +188,17 @@ func (s *Agent) UnifiedLabels() (map[string]string, error) {
}

// DSN returns DSN string for accessing given Service with this Agent (and implicit driver).
func (s *Agent) DSN(service *Service, dialTimeout time.Duration, database string) string {
func (s *Agent) DSN(service *Service, dialTimeout time.Duration, database string, tdp *DelimiterPair) string {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [golangci-lint] reported by reviewdog 🐶
Function 'DSN' has too many statements (96 > 40) (funlen)

host := pointer.GetString(service.Address)
port := pointer.GetUint16(service.Port)
socket := pointer.GetString(service.Socket)
username := pointer.GetString(s.Username)
password := pointer.GetString(s.Password)

if tdp == nil {
tdp = s.TemplateDelimiters(service)
}

switch s.AgentType {
case MySQLdExporterType, ProxySQLExporterType:
cfg := mysql.NewConfig()
Expand Down Expand Up @@ -256,6 +279,18 @@ func (s *Agent) DSN(service *Service, dialTimeout time.Duration, database string
if s.TLSSkipVerify {
q.Add("tlsInsecure", "true")
}

if s.MongoDBOptions != nil {
if s.MongoDBOptions.TLSCertificateKey != "" {
q.Add("tlsCertificateKeyFile", tdp.Left+".TextFiles."+certificateKeyFilePlaceholder+tdp.Right)
}
if s.MongoDBOptions.TLSCertificateKeyFilePassword != "" {
q.Add("tlsCertificateKeyFilePassword", s.MongoDBOptions.TLSCertificateKeyFilePassword)
}
if s.MongoDBOptions.TLSCa != "" {
q.Add("tlsCaFile", tdp.Left+".TextFiles."+caFilePlaceholder+tdp.Right)
}
}
}

address := socket
Expand All @@ -275,7 +310,10 @@ func (s *Agent) DSN(service *Service, dialTimeout time.Duration, database string
case username != "":
u.User = url.User(username)
}
return u.String()
dsn := u.String()
dsn = strings.ReplaceAll(dsn, url.QueryEscape(tdp.Left), tdp.Left)
dsn = strings.ReplaceAll(dsn, url.QueryEscape(tdp.Right), tdp.Right)
return dsn

case PostgresExporterType, QANPostgreSQLPgStatementsAgentType, QANPostgreSQLPgStatMonitorAgentType:
q := make(url.Values)
Expand Down Expand Up @@ -341,6 +379,54 @@ func (s *Agent) IsMySQLTablestatsGroupEnabled() bool {
}
}

// Files returns files map required to connect to DB.
func (s Agent) Files() map[string]string {
switch s.AgentType {
case MySQLdExporterType, ProxySQLExporterType:
return nil
case QANMySQLPerfSchemaAgentType, QANMySQLSlowlogAgentType:
return nil
case QANMongoDBProfilerAgentType, MongoDBExporterType:
if s.MongoDBOptions != nil {
return map[string]string{
caFilePlaceholder: s.MongoDBOptions.TLSCa,
certificateKeyFilePlaceholder: s.MongoDBOptions.TLSCertificateKey,
}
}
return nil
case PostgresExporterType, QANPostgreSQLPgStatementsAgentType, QANPostgreSQLPgStatMonitorAgentType:
return nil
default:
panic(fmt.Errorf("unhandled AgentType %q", s.AgentType))
}
}

// TemplateDelimiters returns a pair of safe template delimiters that are not present in agent parameters.
func (s Agent) TemplateDelimiters(svc *Service) *DelimiterPair {
templateParams := []string{
pointer.GetString(svc.Address),
pointer.GetString(s.Username),
pointer.GetString(s.Password),
pointer.GetString(s.MetricsPath),
}

switch svc.ServiceType {
case MySQLServiceType:
case MongoDBServiceType:
if s.MongoDBOptions != nil {
templateParams = append(templateParams, s.MongoDBOptions.TLSCertificateKeyFilePassword)
}
case PostgreSQLServiceType:
case ProxySQLServiceType:
case ExternalServiceType:
}

tdp := TemplateDelimsPair(
templateParams...,
)
return &tdp
}

// check interfaces
var (
_ reform.BeforeInserter = (*Agent)(nil)
Expand Down
7 changes: 6 additions & 1 deletion models/agent_model_reform.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading