diff --git a/cmd/dex/config.go b/cmd/dex/config.go index dc3715b8f3ca3a2c4db48049845a404af201036a..a2a653a719b10d17db360ae7b08898e971fdca23 100644 --- a/cmd/dex/config.go +++ b/cmd/dex/config.go @@ -8,6 +8,7 @@ import ( "golang.org/x/crypto/bcrypt" + "github.com/Sirupsen/logrus" "github.com/coreos/dex/connector" "github.com/coreos/dex/connector/github" "github.com/coreos/dex/connector/ldap" @@ -29,6 +30,7 @@ type Config struct { OAuth2 OAuth2 `json:"oauth2"` GRPC GRPC `json:"grpc"` Expiry Expiry `json:"expiry"` + Logger Logger `json:"logger"` Frontend server.WebConfig `json:"frontend"` @@ -119,7 +121,7 @@ type Storage struct { // StorageConfig is a configuration that can create a storage. type StorageConfig interface { - Open() (storage.Storage, error) + Open(logrus.FieldLogger) (storage.Storage, error) } var storages = map[string]func() StorageConfig{ @@ -170,7 +172,7 @@ type Connector struct { // ConnectorConfig is a configuration that can open a connector. type ConnectorConfig interface { - Open() (connector.Connector, error) + Open(logrus.FieldLogger) (connector.Connector, error) } var connectors = map[string]func() ConnectorConfig{ @@ -223,3 +225,12 @@ type Expiry struct { // IdTokens defines the duration of time for which the IdTokens will be valid. IDTokens string `json:"idTokens"` } + +// Logger holds configuration required to customize logging for dex. +type Logger struct { + // Level sets logging level severity. + Level string `json:"level"` + + // Format specifies the format to be used for logging. + Format string `json:"format"` +} diff --git a/cmd/dex/config_test.go b/cmd/dex/config_test.go index f0126f82fd46deda9ba6ae207d70011e3dead284..004fec00c7d3429a8f7de1c9db317e82e5faf13d 100644 --- a/cmd/dex/config_test.go +++ b/cmd/dex/config_test.go @@ -59,6 +59,10 @@ staticPasswords: expiry: signingKeys: "6h" idTokens: "24h" + +logger: + level: "debug" + format: "json" `) want := Config{ @@ -120,6 +124,10 @@ expiry: SigningKeys: "6h", IDTokens: "24h", }, + Logger: Logger{ + Level: "debug", + Format: "json", + }, } var c Config diff --git a/cmd/dex/serve.go b/cmd/dex/serve.go index c9baa9d38ce6a0de4ad05812c3404c6eb103c3e1..b47ea9efde1b1981e85091a291104592e32b459f 100644 --- a/cmd/dex/serve.go +++ b/cmd/dex/serve.go @@ -9,8 +9,11 @@ import ( "log" "net" "net/http" + "os" + "strings" "time" + "github.com/Sirupsen/logrus" "github.com/ghodss/yaml" "github.com/spf13/cobra" "golang.org/x/net/context" @@ -111,6 +114,8 @@ func serve(cmd *cobra.Command, args []string) error { } } + logger, _ := newLogger(c.Logger.Level, c.Logger.Format) + connectors := make([]server.Connector, len(c.Connectors)) for i, conn := range c.Connectors { if conn.ID == "" { @@ -119,7 +124,8 @@ func serve(cmd *cobra.Command, args []string) error { if conn.Config == nil { return fmt.Errorf("no config field for connector %q", conn.ID) } - c, err := conn.Config.Open() + connectorLogger := logger.WithField("connector", conn.Name) + c, err := conn.Config.Open(connectorLogger) if err != nil { return fmt.Errorf("open %s: %v", conn.ID, err) } @@ -130,7 +136,7 @@ func serve(cmd *cobra.Command, args []string) error { } } - s, err := c.Storage.Config.Open() + s, err := c.Storage.Config.Open(logger) if err != nil { return fmt.Errorf("initializing storage: %v", err) } @@ -153,6 +159,7 @@ func serve(cmd *cobra.Command, args []string) error { Storage: s, Web: c.Frontend, EnablePasswordDB: c.EnablePasswordDB, + Logger: logger, } if c.Expiry.SigningKeys != "" { signingKeys, err := time.ParseDuration(c.Expiry.SigningKeys) @@ -203,3 +210,33 @@ func serve(cmd *cobra.Command, args []string) error { return <-errc } + +func newLogger(level string, format string) (logrus.FieldLogger, error) { + var logLevel logrus.Level + switch strings.ToLower(level) { + case "debug": + logLevel = logrus.DebugLevel + case "", "info": + logLevel = logrus.InfoLevel + case "error": + logLevel = logrus.ErrorLevel + default: + return nil, fmt.Errorf("unsupported logLevel: %s", level) + } + + var formatter logrus.Formatter + switch strings.ToLower(format) { + case "", "text": + formatter = &logrus.TextFormatter{DisableColors: true} + case "json": + formatter = &logrus.JSONFormatter{} + default: + return nil, fmt.Errorf("unsupported logger format: %s", format) + } + + return &logrus.Logger{ + Out: os.Stderr, + Formatter: formatter, + Level: logLevel, + }, nil +} diff --git a/connector/github/github.go b/connector/github/github.go index 149883aa34da82bcee74ae66c9225f94658c9482..4ed438522ff9f365e4a452f8bd4ddb4e2bb254c2 100644 --- a/connector/github/github.go +++ b/connector/github/github.go @@ -13,6 +13,7 @@ import ( "golang.org/x/oauth2" "golang.org/x/oauth2/github" + "github.com/Sirupsen/logrus" "github.com/coreos/dex/connector" ) @@ -31,12 +32,13 @@ type Config struct { } // Open returns a strategy for logging in through GitHub. -func (c *Config) Open() (connector.Connector, error) { +func (c *Config) Open(logger logrus.FieldLogger) (connector.Connector, error) { return &githubConnector{ redirectURI: c.RedirectURI, org: c.Org, clientID: c.ClientID, clientSecret: c.ClientSecret, + logger: logger, }, nil } @@ -55,6 +57,7 @@ type githubConnector struct { org string clientID string clientSecret string + logger logrus.FieldLogger } func (c *githubConnector) oauth2Config(scopes connector.Scopes) *oauth2.Config { diff --git a/connector/ldap/ldap.go b/connector/ldap/ldap.go index d39175c3ccd21ac430cdf8698979399320c6ccae..1af9aab12026e7ec1c39f42984797dd9b4a14f99 100644 --- a/connector/ldap/ldap.go +++ b/connector/ldap/ldap.go @@ -13,6 +13,7 @@ import ( "golang.org/x/net/context" "gopkg.in/ldap.v2" + "github.com/Sirupsen/logrus" "github.com/coreos/dex/connector" ) @@ -135,8 +136,8 @@ func parseScope(s string) (int, bool) { } // Open returns an authentication strategy using LDAP. -func (c *Config) Open() (connector.Connector, error) { - conn, err := c.OpenConnector() +func (c *Config) Open(logger logrus.FieldLogger) (connector.Connector, error) { + conn, err := c.OpenConnector(logger) if err != nil { return nil, err } @@ -149,7 +150,7 @@ type refreshData struct { } // OpenConnector is the same as Open but returns a type with all implemented connector interfaces. -func (c *Config) OpenConnector() (interface { +func (c *Config) OpenConnector(logger logrus.FieldLogger) (interface { connector.Connector connector.PasswordConnector connector.RefreshConnector @@ -206,7 +207,7 @@ func (c *Config) OpenConnector() (interface { if !ok { return nil, fmt.Errorf("userSearch.Scope unknown value %q", c.GroupSearch.Scope) } - return &ldapConnector{*c, userSearchScope, groupSearchScope, tlsConfig}, nil + return &ldapConnector{*c, userSearchScope, groupSearchScope, tlsConfig, logger}, nil } type ldapConnector struct { @@ -216,6 +217,8 @@ type ldapConnector struct { groupSearchScope int tlsConfig *tls.Config + + logger logrus.FieldLogger } var ( diff --git a/connector/mock/connectortest.go b/connector/mock/connectortest.go index 167b0fb28620fc59c841e8414afab31decd77688..b754705b25016768f40d360254819d4e4c69e3e0 100644 --- a/connector/mock/connectortest.go +++ b/connector/mock/connectortest.go @@ -9,12 +9,13 @@ import ( "golang.org/x/net/context" + "github.com/Sirupsen/logrus" "github.com/coreos/dex/connector" ) // NewCallbackConnector returns a mock connector which requires no user interaction. It always returns // the same (fake) identity. -func NewCallbackConnector() connector.Connector { +func NewCallbackConnector(logger logrus.FieldLogger) connector.Connector { return &Callback{ Identity: connector.Identity{ UserID: "0-385-28089-0", @@ -24,6 +25,7 @@ func NewCallbackConnector() connector.Connector { Groups: []string{"authors"}, ConnectorData: connectorData, }, + Logger: logger, } } @@ -37,6 +39,7 @@ var ( type Callback struct { // The returned identity. Identity connector.Identity + Logger logrus.FieldLogger } // LoginURL returns the URL to redirect the user to login with. @@ -67,8 +70,8 @@ func (m *Callback) Refresh(ctx context.Context, s connector.Scopes, identity con type CallbackConfig struct{} // Open returns an authentication strategy which requires no user interaction. -func (c *CallbackConfig) Open() (connector.Connector, error) { - return NewCallbackConnector(), nil +func (c *CallbackConfig) Open(logger logrus.FieldLogger) (connector.Connector, error) { + return NewCallbackConnector(logger), nil } // PasswordConfig holds the configuration for a mock connector which prompts for the supplied @@ -79,19 +82,20 @@ type PasswordConfig struct { } // Open returns an authentication strategy which prompts for a predefined username and password. -func (c *PasswordConfig) Open() (connector.Connector, error) { +func (c *PasswordConfig) Open(logger logrus.FieldLogger) (connector.Connector, error) { if c.Username == "" { return nil, errors.New("no username supplied") } if c.Password == "" { return nil, errors.New("no password supplied") } - return &passwordConnector{c.Username, c.Password}, nil + return &passwordConnector{c.Username, c.Password, logger}, nil } type passwordConnector struct { username string password string + logger logrus.FieldLogger } func (p passwordConnector) Close() error { return nil } diff --git a/connector/oidc/oidc.go b/connector/oidc/oidc.go index 6a71d0173617327637d65b51c99575627260de1c..6a8b6f98689a7e0b564fd25554c6cf97eb4a2c5f 100644 --- a/connector/oidc/oidc.go +++ b/connector/oidc/oidc.go @@ -6,6 +6,7 @@ import ( "fmt" "net/http" + "github.com/Sirupsen/logrus" "github.com/coreos/go-oidc" "golang.org/x/net/context" "golang.org/x/oauth2" @@ -25,7 +26,7 @@ type Config struct { // Open returns a connector which can be used to login users through an upstream // OpenID Connect provider. -func (c *Config) Open() (conn connector.Connector, err error) { +func (c *Config) Open(logger logrus.FieldLogger) (conn connector.Connector, err error) { ctx, cancel := context.WithCancel(context.Background()) provider, err := oidc.NewProvider(ctx, c.Issuer) @@ -55,6 +56,7 @@ func (c *Config) Open() (conn connector.Connector, err error) { oidc.VerifyExpiry(), oidc.VerifyAudience(clientID), ), + logger: logger, }, nil } @@ -68,6 +70,7 @@ type oidcConnector struct { verifier *oidc.IDTokenVerifier ctx context.Context cancel context.CancelFunc + logger logrus.FieldLogger } func (c *oidcConnector) Close() error { diff --git a/server/api_test.go b/server/api_test.go index f6eb7a4d2d31a63847f873f1634de03594f987c2..9f325cbabe2de3d1529694e169b710fbc161dffc 100644 --- a/server/api_test.go +++ b/server/api_test.go @@ -2,15 +2,23 @@ package server import ( "context" + "os" "testing" + "github.com/Sirupsen/logrus" "github.com/coreos/dex/api" "github.com/coreos/dex/storage/memory" ) // Attempts to create, update and delete a test Password func TestPassword(t *testing.T) { - s := memory.New() + logger := &logrus.Logger{ + Out: os.Stderr, + Formatter: &logrus.TextFormatter{DisableColors: true}, + Level: logrus.DebugLevel, + } + + s := memory.New(logger) serv := NewAPI(s) ctx := context.Background() diff --git a/server/server.go b/server/server.go index 91d119e9fda8b06189eee939bbf3f3265bf9e911..1a87cb9c0e909ed01c01a7ebfa47ce3e6cd9e107 100644 --- a/server/server.go +++ b/server/server.go @@ -13,6 +13,7 @@ import ( "golang.org/x/crypto/bcrypt" "golang.org/x/net/context" + "github.com/Sirupsen/logrus" "github.com/gorilla/mux" "github.com/coreos/dex/connector" @@ -57,6 +58,8 @@ type Config struct { EnablePasswordDB bool Web WebConfig + + Logger logrus.FieldLogger } // WebConfig holds the server's frontend templates and asset configuration. @@ -112,6 +115,8 @@ type Server struct { now func() time.Time idTokensValidFor time.Duration + + logger logrus.FieldLogger } // NewServer constructs a server from the provided config. @@ -182,6 +187,7 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) skipApproval: c.SkipApprovalScreen, now: now, templates: tmpls, + logger: c.Logger, } for _, conn := range c.Connectors { diff --git a/server/server_test.go b/server/server_test.go index 3ab41940826a8352990a9ee418959f31a02cc87f..4c9621c9c31824da6bdf6eaa6826f4b2fda3c0e8 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -20,6 +20,7 @@ import ( "testing" "time" + "github.com/Sirupsen/logrus" oidc "github.com/coreos/go-oidc" "github.com/kylelemons/godebug/pretty" "golang.org/x/crypto/bcrypt" @@ -72,19 +73,26 @@ FDWV28nTP9sqbtsmU8Tem2jzMvZ7C/Q0AuDoKELFUpux8shm8wfIhyaPnXUGZoAZ Np4vUwMSYV5mopESLWOg3loBxKyLGFtgGKVCjGiQvy6zISQ4fQo= -----END RSA PRIVATE KEY-----`) +var logger = &logrus.Logger{ + Out: os.Stderr, + Formatter: &logrus.TextFormatter{DisableColors: true}, + Level: logrus.DebugLevel, +} + func newTestServer(ctx context.Context, t *testing.T, updateConfig func(c *Config)) (*httptest.Server, *Server) { var server *Server s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { server.ServeHTTP(w, r) })) + config := Config{ Issuer: s.URL, - Storage: memory.New(), + Storage: memory.New(logger), Connectors: []Connector{ { ID: "mock", DisplayName: "Mock", - Connector: mock.NewCallbackConnector(), + Connector: mock.NewCallbackConnector(logger), }, }, Web: WebConfig{ @@ -367,12 +375,17 @@ func TestOAuth2CodeFlow(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + logger := &logrus.Logger{ + Out: os.Stderr, + Formatter: &logrus.TextFormatter{DisableColors: true}, + Level: logrus.DebugLevel, + } httpServer, s := newTestServer(ctx, t, func(c *Config) { c.Issuer = c.Issuer + "/non-root-path" c.Now = now c.IDTokensValidFor = idTokensValidFor // Create a new mock callback connector for each test case. - conn = mock.NewCallbackConnector().(*mock.Callback) + conn = mock.NewCallbackConnector(logger).(*mock.Callback) c.Connectors = []Connector{ { ID: "mock", @@ -743,7 +756,7 @@ func TestCrossClientScopes(t *testing.T) { } func TestPasswordDB(t *testing.T) { - s := memory.New() + s := memory.New(logger) conn := newPasswordDB(s) pw := "hi" @@ -840,7 +853,7 @@ func TestKeyCacher(t *testing.T) { tNow := time.Now() now := func() time.Time { return tNow } - s := memory.New() + s := memory.New(logger) tests := []struct { before func() diff --git a/storage/kubernetes/client.go b/storage/kubernetes/client.go index 55389f1887455a9bbb1cfc0154030e63f57aa41c..b21fb63d20371525afac1438eef477c71e4a0b7d 100644 --- a/storage/kubernetes/client.go +++ b/storage/kubernetes/client.go @@ -21,6 +21,7 @@ import ( "strings" "time" + "github.com/Sirupsen/logrus" "github.com/ghodss/yaml" "github.com/gtank/cryptopasta" "golang.org/x/net/context" @@ -33,6 +34,7 @@ type client struct { client *http.Client baseURL string namespace string + logger logrus.FieldLogger // Hash function to map IDs (which could span a large range) to Kubernetes names. // While this is not currently upgradable, it could be in the future. @@ -230,7 +232,7 @@ func (c *client) put(resource, name string, v interface{}) error { return checkHTTPErr(resp, http.StatusOK) } -func newClient(cluster k8sapi.Cluster, user k8sapi.AuthInfo, namespace string) (*client, error) { +func newClient(cluster k8sapi.Cluster, user k8sapi.AuthInfo, namespace string, logger logrus.FieldLogger) (*client, error) { tlsConfig := cryptopasta.DefaultTLSConfig() data := func(b string, file string) ([]byte, error) { if b != "" { @@ -303,6 +305,7 @@ func newClient(cluster k8sapi.Cluster, user k8sapi.AuthInfo, namespace string) ( hash: func() hash.Hash { return fnv.New64() }, namespace: namespace, apiVersion: "oidc.coreos.com/v1", + logger: logger, }, nil } diff --git a/storage/kubernetes/storage.go b/storage/kubernetes/storage.go index 5471265264d736a0cf84fbe238ac686fff81300b..f3821ee1d64a179dc29acda51515c597b05867b5 100644 --- a/storage/kubernetes/storage.go +++ b/storage/kubernetes/storage.go @@ -10,6 +10,7 @@ import ( "golang.org/x/net/context" + "github.com/Sirupsen/logrus" "github.com/coreos/dex/storage" "github.com/coreos/dex/storage/kubernetes/k8sapi" ) @@ -39,8 +40,8 @@ type Config struct { } // Open returns a storage using Kubernetes third party resource. -func (c *Config) Open() (storage.Storage, error) { - cli, err := c.open() +func (c *Config) Open(logger logrus.FieldLogger) (storage.Storage, error) { + cli, err := c.open(logger) if err != nil { return nil, err } @@ -48,7 +49,7 @@ func (c *Config) Open() (storage.Storage, error) { } // open returns a client with no garbage collection. -func (c *Config) open() (*client, error) { +func (c *Config) open(logger logrus.FieldLogger) (*client, error) { if c.InCluster && (c.KubeConfigFile != "") { return nil, errors.New("cannot specify both 'inCluster' and 'kubeConfigFile'") } @@ -71,7 +72,7 @@ func (c *Config) open() (*client, error) { return nil, err } - cli, err := newClient(cluster, user, namespace) + cli, err := newClient(cluster, user, namespace, logger) if err != nil { return nil, fmt.Errorf("create client: %v", err) } diff --git a/storage/kubernetes/storage_test.go b/storage/kubernetes/storage_test.go index 769bba656d424770a58a0b8c8cbdb51f5163b995..dae641e8d6d357c768aa880de150e14b6d26d0bc 100644 --- a/storage/kubernetes/storage_test.go +++ b/storage/kubernetes/storage_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + "github.com/Sirupsen/logrus" "github.com/coreos/dex/storage" "github.com/coreos/dex/storage/conformance" ) @@ -22,7 +23,12 @@ func loadClient(t *testing.T) *client { if config.KubeConfigFile == "" { t.Skipf("test environment variable %q not set, skipping", testKubeConfigEnv) } - s, err := config.open() + logger := &logrus.Logger{ + Out: os.Stderr, + Formatter: &logrus.TextFormatter{DisableColors: true}, + Level: logrus.DebugLevel, + } + s, err := config.open(logger) if err != nil { t.Fatal(err) } diff --git a/storage/memory/memory.go b/storage/memory/memory.go index e8f2ce9a7da175239f74cbbe93bf2a20dd5c6506..6d60971753ce9cbb4a046006d004e2e6f0335e42 100644 --- a/storage/memory/memory.go +++ b/storage/memory/memory.go @@ -6,17 +6,19 @@ import ( "sync" "time" + "github.com/Sirupsen/logrus" "github.com/coreos/dex/storage" ) // New returns an in memory storage. -func New() storage.Storage { +func New(logger logrus.FieldLogger) storage.Storage { return &memStorage{ clients: make(map[string]storage.Client), authCodes: make(map[string]storage.AuthCode), refreshTokens: make(map[string]storage.RefreshToken), authReqs: make(map[string]storage.AuthRequest), passwords: make(map[string]storage.Password), + logger: logger, } } @@ -28,8 +30,8 @@ type Config struct { } // Open always returns a new in memory storage. -func (c *Config) Open() (storage.Storage, error) { - return New(), nil +func (c *Config) Open(logger logrus.FieldLogger) (storage.Storage, error) { + return New(logger), nil } type memStorage struct { @@ -42,6 +44,8 @@ type memStorage struct { passwords map[string]storage.Password keys storage.Keys + + logger logrus.FieldLogger } func (s *memStorage) tx(f func()) { diff --git a/storage/memory/memory_test.go b/storage/memory/memory_test.go index faa76283c7897e9770e1e72b68cb9eaa4058f2e0..aab63ffc5c474a0a13bb675b58b711f8fa2abc55 100644 --- a/storage/memory/memory_test.go +++ b/storage/memory/memory_test.go @@ -1,11 +1,23 @@ package memory import ( + "os" "testing" + "github.com/Sirupsen/logrus" + "github.com/coreos/dex/storage" "github.com/coreos/dex/storage/conformance" ) func TestStorage(t *testing.T) { - conformance.RunTests(t, New) + logger := &logrus.Logger{ + Out: os.Stderr, + Formatter: &logrus.TextFormatter{DisableColors: true}, + Level: logrus.DebugLevel, + } + + newStorage := func() storage.Storage { + return New(logger) + } + conformance.RunTests(t, newStorage) } diff --git a/storage/memory/static_clients_test.go b/storage/memory/static_clients_test.go index f85cad1624a18ccc4dd24fc4f722cc8d14a4bad1..aab8597e45e18c277ef073e0150668e3e736ec01 100644 --- a/storage/memory/static_clients_test.go +++ b/storage/memory/static_clients_test.go @@ -1,14 +1,21 @@ package memory import ( + "os" "reflect" "testing" + "github.com/Sirupsen/logrus" "github.com/coreos/dex/storage" ) func TestStaticClients(t *testing.T) { - s := New() + logger := &logrus.Logger{ + Out: os.Stderr, + Formatter: &logrus.TextFormatter{DisableColors: true}, + Level: logrus.DebugLevel, + } + s := New(logger) c1 := storage.Client{ID: "foo", Secret: "foo_secret"} c2 := storage.Client{ID: "bar", Secret: "bar_secret"} diff --git a/storage/sql/config.go b/storage/sql/config.go index 071f0b039997895e71f45e1be2573161125ba4f3..d77e5481311fb796a97b174af41ccbd1ecba6877 100644 --- a/storage/sql/config.go +++ b/storage/sql/config.go @@ -6,6 +6,7 @@ import ( "net/url" "strconv" + "github.com/Sirupsen/logrus" "github.com/coreos/dex/storage" ) @@ -16,15 +17,15 @@ type SQLite3 struct { } // Open creates a new storage implementation backed by SQLite3 -func (s *SQLite3) Open() (storage.Storage, error) { - conn, err := s.open() +func (s *SQLite3) Open(logger logrus.FieldLogger) (storage.Storage, error) { + conn, err := s.open(logger) if err != nil { return nil, err } return conn, nil } -func (s *SQLite3) open() (*conn, error) { +func (s *SQLite3) open(logger logrus.FieldLogger) (*conn, error) { db, err := sql.Open("sqlite3", s.File) if err != nil { return nil, err @@ -34,7 +35,7 @@ func (s *SQLite3) open() (*conn, error) { // doesn't support this, so limit the number of connections to 1. db.SetMaxOpenConns(1) } - c := &conn{db, flavorSQLite3} + c := &conn{db, flavorSQLite3, logger} if _, err := c.migrate(); err != nil { return nil, fmt.Errorf("failed to perform migrations: %v", err) } @@ -70,15 +71,15 @@ type Postgres struct { } // Open creates a new storage implementation backed by Postgres. -func (p *Postgres) Open() (storage.Storage, error) { - conn, err := p.open() +func (p *Postgres) Open(logger logrus.FieldLogger) (storage.Storage, error) { + conn, err := p.open(logger) if err != nil { return nil, err } return conn, nil } -func (p *Postgres) open() (*conn, error) { +func (p *Postgres) open(logger logrus.FieldLogger) (*conn, error) { v := url.Values{} set := func(key, val string) { if val != "" { @@ -113,7 +114,7 @@ func (p *Postgres) open() (*conn, error) { if err != nil { return nil, err } - c := &conn{db, flavorPostgres} + c := &conn{db, flavorPostgres, logger} if _, err := c.migrate(); err != nil { return nil, fmt.Errorf("failed to perform migrations: %v", err) } diff --git a/storage/sql/config_test.go b/storage/sql/config_test.go index 1afcf520d5a3b1a2550227b0bb0782ceb34d5c23..a91195ccfb610456ed3497a5346ae0d6648391b3 100644 --- a/storage/sql/config_test.go +++ b/storage/sql/config_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/Sirupsen/logrus" "github.com/coreos/dex/storage" "github.com/coreos/dex/storage/conformance" ) @@ -41,13 +42,19 @@ func cleanDB(c *conn) error { return err } +var logger = &logrus.Logger{ + Out: os.Stderr, + Formatter: &logrus.TextFormatter{DisableColors: true}, + Level: logrus.DebugLevel, +} + func TestSQLite3(t *testing.T) { newStorage := func() storage.Storage { // NOTE(ericchiang): In memory means we only get one connection at a time. If we // ever write tests that require using multiple connections, for instance to test // transactions, we need to move to a file based system. s := &SQLite3{":memory:"} - conn, err := s.open() + conn, err := s.open(logger) if err != nil { fmt.Fprintln(os.Stdout, err) t.Fatal(err) @@ -92,7 +99,7 @@ func TestPostgres(t *testing.T) { } newStorage := func() storage.Storage { - conn, err := p.open() + conn, err := p.open(logger) if err != nil { fatal(err) } diff --git a/storage/sql/migrate_test.go b/storage/sql/migrate_test.go index 6c0765a8197c56e60502588c4cf0f430ede2094b..d46839f1800a2ce9be4421b54a261d9ddc01cc25 100644 --- a/storage/sql/migrate_test.go +++ b/storage/sql/migrate_test.go @@ -2,7 +2,10 @@ package sql import ( "database/sql" + "os" "testing" + + "github.com/Sirupsen/logrus" ) func TestMigrate(t *testing.T) { @@ -12,7 +15,13 @@ func TestMigrate(t *testing.T) { } defer db.Close() - c := &conn{db, flavorSQLite3} + logger := &logrus.Logger{ + Out: os.Stderr, + Formatter: &logrus.TextFormatter{DisableColors: true}, + Level: logrus.DebugLevel, + } + + c := &conn{db, flavorSQLite3, logger} for _, want := range []int{len(migrations), 0} { got, err := c.migrate() if err != nil { diff --git a/storage/sql/sql.go b/storage/sql/sql.go index 02cc4f4a41945f66f9078dbbf10a1dae0e6cb646..c1f57b0e7f626e59fb0923ee5b61c7b37eb20cd0 100644 --- a/storage/sql/sql.go +++ b/storage/sql/sql.go @@ -5,6 +5,7 @@ import ( "database/sql" "regexp" + "github.com/Sirupsen/logrus" "github.com/cockroachdb/cockroach-go/crdb" // import third party drivers @@ -110,6 +111,7 @@ func (f flavor) translate(query string) string { type conn struct { db *sql.DB flavor flavor + logger logrus.FieldLogger } func (c *conn) Close() error {