Skip to content

Commit

Permalink
Merge pull request #1187 from ruflin/mb-mysql-auth
Browse files Browse the repository at this point in the history
Add authentication for mysql
  • Loading branch information
tsg committed Mar 21, 2016
2 parents 76aa20b + 3e9b1af commit 07d5d72
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 76 deletions.
9 changes: 9 additions & 0 deletions metricbeat/etc/beat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,13 @@ metricbeat:
metricsets: ["status"]
enabled: true
period: 2s

# Host DSN should be defined as "tcp(127.0.0.1:3306)/"
# The username and password can either be set in the DSN or for all hosts in username and password config option
hosts: ["root@tcp(127.0.0.1:3306)/"]

# Username of hosts. Empty by default
#username: root

# Password of hosts. Empty by default
#password: test
9 changes: 9 additions & 0 deletions metricbeat/metricbeat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,16 @@ metricbeat:
metricsets: ["status"]
enabled: true
period: 2s

# Host DSN should be defined as "tcp(127.0.0.1:3306)/"
# The username and password can either be set in the DSN or for all hosts in username and password config option
hosts: ["root@tcp(127.0.0.1:3306)/"]

# Username of hosts. Empty by default
#username: root

# Password of hosts. Empty by default
#password: test
###############################################################################
############################# Libbeat Config ##################################
# Base config file used by all other beats for using libbeat features
Expand Down
13 changes: 0 additions & 13 deletions metricbeat/module/apache/apache.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package apache

import (
"os"

"github.com/elastic/beats/metricbeat/helper"
)

Expand All @@ -20,14 +18,3 @@ type Moduler struct{}
func (m *Moduler) Setup(mo *helper.Module) error {
return nil
}

///*** Helper functions for testing ***///

func GetApacheEnvHost() string {
host := os.Getenv("APACHE_HOST")

if len(host) == 0 {
host = "127.0.0.1"
}
return host
}
19 changes: 19 additions & 0 deletions metricbeat/module/apache/testing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
Helper functions for testing used in the apache metricsets
*/
package apache

import (
"os"
)

func GetApacheEnvHost() string {
host := os.Getenv("APACHE_HOST")

if len(host) == 0 {
host = "127.0.0.1"
}
return host
}
30 changes: 19 additions & 11 deletions metricbeat/module/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package mysql

import (
"database/sql"
"os"

"github.com/elastic/beats/metricbeat/helper"

Expand All @@ -24,19 +23,28 @@ func (m *Moduler) Setup(mo *helper.Module) error {
return nil
}

// Connect expects a full mysql dsn
// Example: [username[:password]@][protocol[(address)]]/
func Connect(dsn string) (*sql.DB, error) {
return sql.Open("mysql", dsn)
}
// CreateDSN creates a dsn string out of hostname, username and password
func CreateDSN(host string, username string, password string) string {
// Example: [username[:password]@][protocol[(address)]]/

dsn := host

///*** Testing helpers ***///
if username != "" || password != "" {
dsn = "@" + dsn
}

func GetMySQLEnvDSN() string {
dsn := os.Getenv("MYSQL_DSN")
if password != "" {
dsn = ":" + password + dsn
}

if len(dsn) == 0 {
dsn = "root@tcp(127.0.0.1:3306)/"
if username != "" {
dsn = username + dsn
}
return dsn
}

// Connect expects a full mysql dsn
// Example: [username[:password]@][protocol[(address)]]/
func Connect(dsn string) (*sql.DB, error) {
return sql.Open("mysql", dsn)
}
18 changes: 18 additions & 0 deletions metricbeat/module/mysql/mysql_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// +build integration

package mysql

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestConnect(t *testing.T) {

db, err := Connect(GetMySQLEnvDSN())
assert.NoError(t, err)

err = db.Ping()
assert.NoError(t, err)
}
19 changes: 13 additions & 6 deletions metricbeat/module/mysql/mysql_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// +build integration
// +build !integration

package mysql

Expand All @@ -8,11 +8,18 @@ import (
"github.com/stretchr/testify/assert"
)

func TestConnect(t *testing.T) {
func TestCreateDSN(t *testing.T) {

db, err := Connect(GetMySQLEnvDSN())
assert.NoError(t, err)
hostname := "tcp(127.0.0.1:3306)/"
username := "root"
password := "test"

err = db.Ping()
assert.NoError(t, err)
dsn := CreateDSN(hostname, username, password)
assert.Equal(t, "root:test@tcp(127.0.0.1:3306)/", dsn)

dsn = CreateDSN(hostname, username, "")
assert.Equal(t, "root@tcp(127.0.0.1:3306)/", dsn)

dsn = CreateDSN(hostname, "", "")
assert.Equal(t, "tcp(127.0.0.1:3306)/", dsn)
}
44 changes: 22 additions & 22 deletions metricbeat/module/mysql/status/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,43 +38,43 @@ type MetricSeter struct {

// Setup any metric specific configuration
func (m *MetricSeter) Setup(ms *helper.MetricSet) error {
return nil
}

// Fetches status messages from mysql hosts
func (m *MetricSeter) Fetch(ms *helper.MetricSet, host string) (event common.MapStr, err error) {

db, err := m.getConnection(host)
if err != nil {
logp.Err("MySQL conenction error: %s", err)
// Additional configuration options
config := struct {
Username string `config:"username"`
Password string `config:"password"`
}{
Username: "",
Password: "",
}

status, err := m.loadStatus(db)
for _, host := range ms.Config.Hosts {
dsn := mysql.CreateDSN(host, config.Username, config.Password)

if err != nil {
return nil, err
}
db, err := mysql.Connect(dsn)
if err != nil {
logp.Err(err.Error())
}

return eventMapping(status), nil
m.connections[host] = db
}

return nil
}

// getConnection returns the connection object for the given dsn
// In case a connection already exists it is reused
func (m *MetricSeter) getConnection(dsn string) (*sql.DB, error) {
// Fetches status messages from mysql hosts
func (m *MetricSeter) Fetch(ms *helper.MetricSet, host string) (event common.MapStr, err error) {

if db, ok := m.connections[dsn]; ok {
return db, nil
}
db := m.connections[host]

status, err := m.loadStatus(db)

db, err := mysql.Connect(dsn)
if err != nil {
return nil, err
}

m.connections[dsn] = db
return eventMapping(status), nil

return db, nil
}

// loadStatus loads all status entries from the given database into an array
Expand Down
9 changes: 8 additions & 1 deletion metricbeat/module/mysql/status/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,16 @@ func TestFetch(t *testing.T) {
module := &helper.Module{
Config: config,
}

ms, msErr := helper.NewMetricSet("status", New, module)
assert.NoError(t, msErr)

var err error

// Setup metricset
err = ms.Setup()
assert.NoError(t, err)

// Load events
event, err := ms.MetricSeter.Fetch(ms, module.Config.Hosts[0])
assert.NoError(t, err)
Expand All @@ -36,6 +43,6 @@ func TestFetch(t *testing.T) {

assert.True(t, connections > 0)
assert.True(t, openTables > 0)
assert.True(t, openFiles > 0)
assert.True(t, openFiles >= 0)
assert.True(t, openStreams == 0)
}
19 changes: 19 additions & 0 deletions metricbeat/module/mysql/testing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
Helper functions for testing used in the mysql metricsets
*/
package mysql

import (
"os"
)

func GetMySQLEnvDSN() string {
dsn := os.Getenv("MYSQL_DSN")

if len(dsn) == 0 {
dsn = CreateDSN("tcp(127.0.0.1:3306)/", "root", "")
}
return dsn
}
22 changes: 0 additions & 22 deletions metricbeat/module/redis/redis.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package redis

import (
"os"

"github.com/garyburd/redigo/redis"

"github.com/elastic/beats/libbeat/logp"
Expand Down Expand Up @@ -35,23 +33,3 @@ func Connect(host string) (redis.Conn, error) {
//defer conn.Close()
return conn, err
}

///*** Helper functions for testing ***///

func GetRedisEnvHost() string {
host := os.Getenv("REDIS_HOST")

if len(host) == 0 {
host = "127.0.0.1"
}
return host
}

func GetRedisEnvPort() string {
port := os.Getenv("REDIS_PORT")

if len(port) == 0 {
port = "6379"
}
return port
}
28 changes: 28 additions & 0 deletions metricbeat/module/redis/testing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
Helper functions for testing used in the redis metricsets
*/
package redis

import (
"os"
)

func GetRedisEnvHost() string {
host := os.Getenv("REDIS_HOST")

if len(host) == 0 {
host = "127.0.0.1"
}
return host
}

func GetRedisEnvPort() string {
port := os.Getenv("REDIS_PORT")

if len(port) == 0 {
port = "6379"
}
return port
}
2 changes: 1 addition & 1 deletion metricbeat/tests/system/config/metricbeat.yml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metricbeat:
- "{{ redis_host | default("127.0.0.1", true) }}:6379"
metricsets:
- info
period: 1s
period: 2s
enabled: true
selectors: {{ redis_selectors }}
{% endif %}
Expand Down

0 comments on commit 07d5d72

Please sign in to comment.