[MM-18625] Fix database source parsing on go 1.12.8 (#12250)

This commit is contained in:
Ben Schumacher
2019-09-20 06:22:40 +02:00
committed by GitHub
parent 33cf37bbc0
commit 05fae599b8
2 changed files with 24 additions and 17 deletions

View File

@@ -8,6 +8,7 @@ import (
"database/sql"
"io/ioutil"
"net/url"
"regexp"
"strings"
"github.com/jmoiron/sqlx"
@@ -22,6 +23,8 @@ import (
_ "github.com/lib/pq"
)
var tcpStripper = regexp.MustCompile(`@tcp\((.*)\)`)
// DatabaseStore is a config store backed by a database.
type DatabaseStore struct {
commonStore
@@ -101,23 +104,22 @@ func initializeConfigurationsTable(db *sqlx.DB) error {
// By contrast, a Postgres DSN is returned unmodified.
func parseDSN(dsn string) (string, string, error) {
// Treat the DSN as the URL that it is.
u, err := url.Parse(dsn)
if err != nil {
return "", "", errors.Wrap(err, "failed to parse DSN as URL")
s := strings.SplitN(dsn, "://", 2)
if len(s) != 2 {
errors.New("failed to parse DSN as URL")
}
scheme := u.Scheme
scheme := s[0]
switch scheme {
case "mysql":
// Strip off the mysql:// for the dsn with which to connect.
u.Scheme = ""
dsn = strings.TrimPrefix(u.String(), "//")
dsn = s[1]
case "postgres":
// No changes required
default:
return "", "", errors.Wrapf(err, "unsupported scheme %s", scheme)
return "", "", errors.Errorf("unsupported scheme %s", scheme)
}
return scheme, dsn, nil
@@ -293,7 +295,11 @@ func (ds *DatabaseStore) RemoveFile(name string) error {
// String returns the path to the database backing the config, masking the password.
func (ds *DatabaseStore) String() string {
u, _ := url.Parse(ds.originalDsn)
// Remove @tcp and the parentheses from the host and parse the rest as a URL
u, err := url.Parse(tcpStripper.ReplaceAllString(ds.originalDsn, `@$1`))
if err != nil {
return "(omitted due to error parsing the DSN)"
}
// Strip out the password to avoid leaking in logs.
u.User = url.User(u.User.Username())

View File

@@ -6,7 +6,6 @@ package config_test
import (
"bytes"
"fmt"
"net/url"
"os"
"strings"
"testing"
@@ -137,6 +136,11 @@ func TestDatabaseStoreNew(t *testing.T) {
_, err := config.NewDatabaseStore("invalid")
require.Error(t, err)
})
t.Run("unsupported scheme with valid data source", func(t *testing.T) {
_, err := config.NewDatabaseStore(fmt.Sprintf("invalid://%s", *sqlSettings.DataSource))
require.Error(t, err)
})
}
func TestDatabaseStoreGet(t *testing.T) {
@@ -930,14 +934,11 @@ func TestDatabaseStoreString(t *testing.T) {
sqlSettings := mainHelper.GetSqlSettings()
ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource))
require.NoError(t, err)
require.NotNil(t, ds)
defer ds.Close()
actualStringURL, err := url.Parse(ds.String())
require.NoError(t, err)
assert.Equal(t, *sqlSettings.DriverName, actualStringURL.Scheme)
actualUsername := actualStringURL.User.Username()
actualPassword, _ := actualStringURL.User.Password()
assert.NotEmpty(t, actualUsername)
assert.Empty(t, actualPassword, "should mask password")
maskedDSN := ds.String()
assert.True(t, strings.HasPrefix(maskedDSN, "mysql://"))
assert.True(t, strings.Contains(maskedDSN, "mmuser"))
assert.False(t, strings.Contains(maskedDSN, "mostest"))
}