Skip to content

Commit

Permalink
Release database resources on each iteration of a loop (#4305)
Browse files Browse the repository at this point in the history
  • Loading branch information
Becca Petrin committed Apr 17, 2018
1 parent 7390abd commit f23b14a
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 123 deletions.
9 changes: 3 additions & 6 deletions builtin/logical/mssql/path_creds_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"

"github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/helper/dbtxn"
"github.com/hashicorp/vault/helper/strutil"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
Expand Down Expand Up @@ -90,15 +91,11 @@ func (b *backend) pathCredsCreateRead(ctx context.Context, req *logical.Request,
continue
}

stmt, err := tx.Prepare(Query(query, map[string]string{
m := map[string]string{
"name": username,
"password": password,
}))
if err != nil {
return nil, err
}
defer stmt.Close()
if _, err := stmt.Exec(); err != nil {
if err := dbtxn.ExecuteTxQuery(ctx, tx, m, query); err != nil {
return nil, err
}
}
Expand Down
10 changes: 3 additions & 7 deletions builtin/logical/mssql/secret_creds.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"

"github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/helper/dbtxn"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
Expand Down Expand Up @@ -130,16 +131,11 @@ func (b *backend) secretCredsRevoke(ctx context.Context, req *logical.Request, d
// many permissions as possible right now
var lastStmtError error
for _, query := range revokeStmts {
stmt, err := db.Prepare(query)
if err != nil {

if err := dbtxn.ExecuteDBQuery(ctx, db, nil, query); err != nil {
lastStmtError = err
continue
}
defer stmt.Close()
_, err = stmt.Exec()
if err != nil {
lastStmtError = err
}
}

// can't drop if not all database users are dropped
Expand Down
9 changes: 3 additions & 6 deletions builtin/logical/mysql/path_role_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"

"github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/helper/dbtxn"
"github.com/hashicorp/vault/helper/strutil"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
Expand Down Expand Up @@ -103,15 +104,11 @@ func (b *backend) pathRoleCreateRead(ctx context.Context, req *logical.Request,
continue
}

stmt, err := tx.Prepare(Query(query, map[string]string{
m := map[string]string{
"name": username,
"password": password,
}))
if err != nil {
return nil, err
}
defer stmt.Close()
if _, err := stmt.Exec(); err != nil {
if err := dbtxn.ExecuteTxQuery(ctx, tx, m, query); err != nil {
return nil, err
}
}
Expand Down
10 changes: 4 additions & 6 deletions builtin/logical/postgresql/path_role_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

"github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/helper/dbtxn"
"github.com/hashicorp/vault/helper/strutil"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
Expand Down Expand Up @@ -106,16 +107,13 @@ func (b *backend) pathRoleCreateRead(ctx context.Context, req *logical.Request,
continue
}

stmt, err := tx.Prepare(Query(query, map[string]string{
m := map[string]string{
"name": username,
"password": password,
"expiration": expiration,
}))
if err != nil {
return nil, err
}
defer stmt.Close()
if _, err := stmt.Exec(); err != nil {

if err := dbtxn.ExecuteTxQuery(ctx, tx, m, query); err != nil {
return nil, err
}
}
Expand Down
19 changes: 4 additions & 15 deletions builtin/logical/postgresql/secret_creds.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

"github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/helper/dbtxn"
"github.com/hashicorp/vault/helper/strutil"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
Expand Down Expand Up @@ -211,14 +212,7 @@ func (b *backend) secretCredsRevoke(ctx context.Context, req *logical.Request, d
// many permissions as possible right now
var lastStmtError error
for _, query := range revocationStmts {
stmt, err := db.Prepare(query)
if err != nil {
lastStmtError = err
continue
}
defer stmt.Close()
_, err = stmt.Exec()
if err != nil {
if err := dbtxn.ExecuteDBQuery(ctx, db, nil, query); err != nil {
lastStmtError = err
}
}
Expand Down Expand Up @@ -258,15 +252,10 @@ func (b *backend) secretCredsRevoke(ctx context.Context, req *logical.Request, d
continue
}

stmt, err := tx.Prepare(Query(query, map[string]string{
m := map[string]string{
"name": username,
}))
if err != nil {
return nil, err
}
defer stmt.Close()

if _, err := stmt.Exec(); err != nil {
if err := dbtxn.ExecuteTxQuery(ctx, tx, m, query); err != nil {
return nil, err
}
}
Expand Down
63 changes: 63 additions & 0 deletions helper/dbtxn/dbtxn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package dbtxn

import (
"context"
"database/sql"
"fmt"
"strings"
)

// ExecuteDBQuery handles executing one single statement, while properly releasing its resources.
// - ctx: Required
// - db: Required
// - config: Optional, may be nil
// - query: Required
func ExecuteDBQuery(ctx context.Context, db *sql.DB, params map[string]string, query string) error {

parsedQuery := parseQuery(params, query)

stmt, err := db.PrepareContext(ctx, parsedQuery)
if err != nil {
return err
}
defer stmt.Close()

return execute(ctx, stmt)
}

// ExecuteTxQuery handles executing one single statement, while properly releasing its resources.
// - ctx: Required
// - tx: Required
// - config: Optional, may be nil
// - query: Required
func ExecuteTxQuery(ctx context.Context, tx *sql.Tx, params map[string]string, query string) error {

parsedQuery := parseQuery(params, query)

stmt, err := tx.PrepareContext(ctx, parsedQuery)
if err != nil {
return err
}
defer stmt.Close()

return execute(ctx, stmt)
}

func execute(ctx context.Context, stmt *sql.Stmt) error {
if _, err := stmt.ExecContext(ctx); err != nil {
return err
}
return nil
}

func parseQuery(m map[string]string, tpl string) string {

if m == nil || len(m) <= 0 {
return tpl
}

for k, v := range m {
tpl = strings.Replace(tpl, fmt.Sprintf("{{%s}}", k), v, -1)
}
return tpl
}
17 changes: 5 additions & 12 deletions plugins/database/hana/hana.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
_ "github.com/SAP/go-hdb/driver"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
"github.com/hashicorp/vault/helper/dbtxn"
"github.com/hashicorp/vault/helper/strutil"
"github.com/hashicorp/vault/plugins"
"github.com/hashicorp/vault/plugins/helper/database/connutil"
Expand Down Expand Up @@ -143,16 +144,12 @@ func (h *HANA) CreateUser(ctx context.Context, statements dbplugin.Statements, u
continue
}

stmt, err := tx.PrepareContext(ctx, dbutil.QueryHelper(query, map[string]string{
m := map[string]string{
"name": username,
"password": password,
"expiration": expirationStr,
}))
if err != nil {
return "", "", err
}
defer stmt.Close()
if _, err := stmt.ExecContext(ctx); err != nil {
if err := dbtxn.ExecuteTxQuery(ctx, tx, m, query); err != nil {
return "", "", err
}
}
Expand Down Expand Up @@ -238,14 +235,10 @@ func (h *HANA) RevokeUser(ctx context.Context, statements dbplugin.Statements, u
continue
}

stmt, err := tx.PrepareContext(ctx, dbutil.QueryHelper(query, map[string]string{
m := map[string]string{
"name": username,
}))
if err != nil {
return err
}
defer stmt.Close()
if _, err := stmt.ExecContext(ctx); err != nil {
if err := dbtxn.ExecuteTxQuery(ctx, tx, m, query); err != nil {
return err
}
}
Expand Down
37 changes: 10 additions & 27 deletions plugins/database/mssql/mssql.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
"github.com/hashicorp/vault/helper/dbtxn"
"github.com/hashicorp/vault/helper/strutil"
"github.com/hashicorp/vault/plugins"
"github.com/hashicorp/vault/plugins/helper/database/connutil"
Expand Down Expand Up @@ -129,16 +130,13 @@ func (m *MSSQL) CreateUser(ctx context.Context, statements dbplugin.Statements,
continue
}

stmt, err := tx.PrepareContext(ctx, dbutil.QueryHelper(query, map[string]string{
m := map[string]string{
"name": username,
"password": password,
"expiration": expirationStr,
}))
if err != nil {
return "", "", err
}
defer stmt.Close()
if _, err := stmt.ExecContext(ctx); err != nil {

if err := dbtxn.ExecuteTxQuery(ctx, tx, m, query); err != nil {
return "", "", err
}
}
Expand Down Expand Up @@ -189,14 +187,10 @@ func (m *MSSQL) RevokeUser(ctx context.Context, statements dbplugin.Statements,
continue
}

stmt, err := tx.PrepareContext(ctx, dbutil.QueryHelper(query, map[string]string{
m := map[string]string{
"name": username,
}))
if err != nil {
return err
}
defer stmt.Close()
if _, err := stmt.ExecContext(ctx); err != nil {
if err := dbtxn.ExecuteTxQuery(ctx, tx, m, query); err != nil {
return err
}
}
Expand Down Expand Up @@ -285,14 +279,7 @@ func (m *MSSQL) revokeUserDefault(ctx context.Context, username string) error {
// many permissions as possible right now
var lastStmtError error
for _, query := range revokeStmts {
stmt, err := db.PrepareContext(ctx, query)
if err != nil {
lastStmtError = err
continue
}
defer stmt.Close()
_, err = stmt.ExecContext(ctx)
if err != nil {
if err := dbtxn.ExecuteDBQuery(ctx, db, nil, query); err != nil {
lastStmtError = err
}
}
Expand Down Expand Up @@ -355,16 +342,12 @@ func (m *MSSQL) RotateRootCredentials(ctx context.Context, statements []string)
if len(query) == 0 {
continue
}
stmt, err := tx.PrepareContext(ctx, dbutil.QueryHelper(query, map[string]string{

m := map[string]string{
"username": m.Username,
"password": password,
}))
if err != nil {
return nil, err
}

defer stmt.Close()
if _, err := stmt.ExecContext(ctx); err != nil {
if err := dbtxn.ExecuteTxQuery(ctx, tx, m, query); err != nil {
return nil, err
}
}
Expand Down
14 changes: 6 additions & 8 deletions plugins/database/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
stdmysql "github.com/go-sql-driver/mysql"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
"github.com/hashicorp/vault/helper/dbtxn"
"github.com/hashicorp/vault/helper/strutil"
"github.com/hashicorp/vault/plugins"
"github.com/hashicorp/vault/plugins/helper/database/connutil"
Expand Down Expand Up @@ -182,10 +183,11 @@ func (m *MySQL) CreateUser(ctx context.Context, statements dbplugin.Statements,

return "", "", err
}
defer stmt.Close()
if _, err := stmt.ExecContext(ctx); err != nil {
stmt.Close()
return "", "", err
}
stmt.Close()
}
}

Expand Down Expand Up @@ -291,16 +293,12 @@ func (m *MySQL) RotateRootCredentials(ctx context.Context, statements []string)
if len(query) == 0 {
continue
}
stmt, err := tx.PrepareContext(ctx, dbutil.QueryHelper(query, map[string]string{

m := map[string]string{
"username": m.Username,
"password": password,
}))
if err != nil {
return nil, err
}

defer stmt.Close()
if _, err := stmt.ExecContext(ctx); err != nil {
if err := dbtxn.ExecuteTxQuery(ctx, tx, m, query); err != nil {
return nil, err
}
}
Expand Down
Loading

0 comments on commit f23b14a

Please sign in to comment.