diff --git a/plugins/database/mongodb/connection_producer.go b/plugins/database/mongodb/connection_producer.go index 1b59496cf319..ab0ddf216caa 100644 --- a/plugins/database/mongodb/connection_producer.go +++ b/plugins/database/mongodb/connection_producer.go @@ -138,7 +138,6 @@ func (c *mongoDBConnectionProducer) Connection(_ context.Context) (interface{}, return c.session, nil } -// Close terminates the database connection. func (c *mongoDBConnectionProducer) Close() error { c.Lock() defer c.Unlock() diff --git a/plugins/database/mongodb/mongodb.go b/plugins/database/mongodb/mongodb.go index 85c5cdc06723..75ce16b792e5 100644 --- a/plugins/database/mongodb/mongodb.go +++ b/plugins/database/mongodb/mongodb.go @@ -11,7 +11,6 @@ import ( "fmt" - "github.com/hashicorp/errwrap" "github.com/hashicorp/vault/api" "github.com/hashicorp/vault/sdk/database/dbplugin" "github.com/hashicorp/vault/sdk/database/helper/credsutil" @@ -140,6 +139,20 @@ func (m *MongoDB) CreateUser(ctx context.Context, statements dbplugin.Statements case err == nil: case err == io.EOF, strings.Contains(err.Error(), "EOF"): // Call getConnection to reset and retry query if we get an EOF error on first attempt. + session, err := m.getConnection(ctx) + if err != nil { + return "", "", err + } + err = session.DB(mongoCS.DB).Run(createUserCmd, nil) + if err != nil { + return "", "", err + } + case strings.Contains(err.Error(), "not master"): + // Close connection and reconnect if connected node is not primary. + if m.mongoDBConnectionProducer.session != nil { + m.mongoDBConnectionProducer.session.Close(); + } + session, err := m.getConnection(ctx) if err != nil { return "", "", err @@ -190,6 +203,21 @@ func (m *MongoDB) SetCredentials(ctx context.Context, statements dbplugin.Statem case err == nil: case err == io.EOF, strings.Contains(err.Error(), "EOF"): // Call getConnection to reset and retry query if we get an EOF error on first attempt. + session, err := m.getConnection(ctx) + if err != nil { + return "", "", err + } + err = session.DB(dialInfo.Database).UpsertUser(&mongoUser) + if err != nil { + return "", "", err + } + case strings.Contains(err.Error(), "not master"): + // Close connection and reconnect if connected node is not primary. + if m.mongoDBConnectionProducer.session != nil { + m.mongoDBConnectionProducer.session.Close(); + } + m.mongoDBConnectionProducer.session = nil + session, err := m.getConnection(ctx) if err != nil { return "", "", err @@ -251,9 +279,9 @@ func (m *MongoDB) RevokeUser(ctx context.Context, statements dbplugin.Statements err = session.DB(db).RemoveUser(username) switch { case err == nil, err == mgo.ErrNotFound: - case err == io.EOF, strings.Contains(err.Error(), "EOF"): - if err := m.Close(); err != nil { - return errwrap.Wrapf("error closing EOF'd mongo connection: {{err}}", err) + case err == io.EOF, strings.Contains(err.Error(), "EOF"), strings.Contains(err.Error(), "not master"): + if m.mongoDBConnectionProducer.session != nil { + m.mongoDBConnectionProducer.session.Close(); } session, err := m.getConnection(ctx) if err != nil {