diff --git a/go.mod b/go.mod index 0d9535da65a1..2e283599e3b2 100644 --- a/go.mod +++ b/go.mod @@ -83,7 +83,7 @@ require ( github.com/hashicorp/vault-plugin-database-mongodbatlas v0.1.2-0.20200624203152-e5cd7c505e55 github.com/hashicorp/vault-plugin-secrets-ad v0.6.6-0.20200520202259-fc6b89630f9f github.com/hashicorp/vault-plugin-secrets-alicloud v0.5.5 - github.com/hashicorp/vault-plugin-secrets-azure v0.5.6 + github.com/hashicorp/vault-plugin-secrets-azure v0.5.7-0.20200818192400-40b6e36f1c79 github.com/hashicorp/vault-plugin-secrets-gcp v0.6.2-0.20200617162044-4a67a90aaca5 github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.5 github.com/hashicorp/vault-plugin-secrets-kv v0.5.5 diff --git a/go.sum b/go.sum index c652d1d84987..8fd62afb86cc 100644 --- a/go.sum +++ b/go.sum @@ -424,6 +424,8 @@ github.com/hashicorp/vault-plugin-secrets-alicloud v0.5.5 h1:BOOtSls+BQ1EtPmpE9L github.com/hashicorp/vault-plugin-secrets-alicloud v0.5.5/go.mod h1:gAoReoUpBHaBwkxQqTK7FY8nQC0MuaZHLiW5WOSny5g= github.com/hashicorp/vault-plugin-secrets-azure v0.5.6 h1:4PgQ5rCT29wW5PMyebEhPkEYuR5s+SnInuZz3x2cP50= github.com/hashicorp/vault-plugin-secrets-azure v0.5.6/go.mod h1:Q0cIL4kZWnMmQWkBfWtyOd7+JXTEpAyU4L932PMHq3E= +github.com/hashicorp/vault-plugin-secrets-azure v0.5.7-0.20200818192400-40b6e36f1c79 h1:7hVNnPIs5BHvh6H8nFPzSB1clwwc/39oj6hS4/JNwVE= +github.com/hashicorp/vault-plugin-secrets-azure v0.5.7-0.20200818192400-40b6e36f1c79/go.mod h1:1SpM7OmmHOY3DJv3CNP8j+0AaKVtRWscGSuMQeRmku8= github.com/hashicorp/vault-plugin-secrets-gcp v0.6.2-0.20200617162044-4a67a90aaca5 h1:X8jtQvuyLh6ZIFUQmG7Ky2QVQZCulz2BB/vroM6xTVc= github.com/hashicorp/vault-plugin-secrets-gcp v0.6.2-0.20200617162044-4a67a90aaca5/go.mod h1:jVTE1fuhRcBOb/gnCT9W++AnlwiyQEX4S8iVCKhKQsE= github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.5 h1:NigzA2v+h+cjBPl41pRirRwWELF+RPJGch/ys0Sijrc= diff --git a/vendor/github.com/hashicorp/vault-plugin-secrets-azure/backend.go b/vendor/github.com/hashicorp/vault-plugin-secrets-azure/backend.go index 255413dc4ae6..39eeae9497b6 100644 --- a/vendor/github.com/hashicorp/vault-plugin-secrets-azure/backend.go +++ b/vendor/github.com/hashicorp/vault-plugin-secrets-azure/backend.go @@ -4,6 +4,7 @@ import ( "context" "strings" "sync" + "time" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/locksutil" @@ -54,6 +55,12 @@ func backend() *azureSecretBackend { }, BackendType: logical.TypeLogical, Invalidate: b.invalidate, + + WALRollback: b.walRollback, + + // Role assignment can take up to a few minutes, so ensure we don't try + // to roll back during creation. + WALRollbackMinAge: 10 * time.Minute, } b.getProvider = newAzureProvider diff --git a/vendor/github.com/hashicorp/vault-plugin-secrets-azure/go.mod b/vendor/github.com/hashicorp/vault-plugin-secrets-azure/go.mod index 62279a4b1f9b..26e47ca77c7d 100644 --- a/vendor/github.com/hashicorp/vault-plugin-secrets-azure/go.mod +++ b/vendor/github.com/hashicorp/vault-plugin-secrets-azure/go.mod @@ -17,6 +17,5 @@ require ( github.com/hashicorp/vault/api v1.0.5-0.20200317185738-82f498082f02 github.com/hashicorp/vault/sdk v0.1.14-0.20200317185738-82f498082f02 github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect - golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db // indirect - google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107 // indirect + github.com/mitchellh/mapstructure v1.1.2 ) diff --git a/vendor/github.com/hashicorp/vault-plugin-secrets-azure/go.sum b/vendor/github.com/hashicorp/vault-plugin-secrets-azure/go.sum index f010e2449820..4d816d7a9d7b 100644 --- a/vendor/github.com/hashicorp/vault-plugin-secrets-azure/go.sum +++ b/vendor/github.com/hashicorp/vault-plugin-secrets-azure/go.sum @@ -148,59 +148,38 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 h1:O5YqonU5IWby+w98jVUG9h7zlCWCcH4RHyPVReBmhzk= golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e h1:nFYrTHrdrAOpShe27kaFHjsqYSEQ0KWqdWLu3xuZJts= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db h1:6/JqlYfC1CCaLnGceQTI+sDGhC9UBSPAsBqI0Gun6kU= -golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107 h1:xtNn7qFlagY2mQNFHMSRPjT2RkOV4OXM7P5TVy9xATo= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw= google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/github.com/hashicorp/vault-plugin-secrets-azure/path_service_principal.go b/vendor/github.com/hashicorp/vault-plugin-secrets-azure/path_service_principal.go index 409fba5deae3..3015e4232de5 100644 --- a/vendor/github.com/hashicorp/vault-plugin-secrets-azure/path_service_principal.go +++ b/vendor/github.com/hashicorp/vault-plugin-secrets-azure/path_service_principal.go @@ -77,7 +77,7 @@ func (b *azureSecretBackend) pathSPRead(ctx context.Context, req *logical.Reques if role.ApplicationObjectID != "" { resp, err = b.createStaticSPSecret(ctx, client, roleName, role) } else { - resp, err = b.createSPSecret(ctx, client, roleName, role) + resp, err = b.createSPSecret(ctx, req.Storage, client, roleName, role) } if err != nil { @@ -91,9 +91,10 @@ func (b *azureSecretBackend) pathSPRead(ctx context.Context, req *logical.Reques } // createSPSecret generates a new App/Service Principal. -func (b *azureSecretBackend) createSPSecret(ctx context.Context, c *client, roleName string, role *roleEntry) (*logical.Response, error) { +func (b *azureSecretBackend) createSPSecret(ctx context.Context, s logical.Storage, c *client, roleName string, role *roleEntry) (*logical.Response, error) { // Create the App, which is the top level object to be tracked in the secret - // and deleted upon revocation. If any subsequent step fails, the App is deleted. + // and deleted upon revocation. If any subsequent step fails, the App will be + // deleted as part of WAL rollback. app, err := c.createApp(ctx) if err != nil { return nil, err @@ -101,26 +102,38 @@ func (b *azureSecretBackend) createSPSecret(ctx context.Context, c *client, role appID := to.String(app.AppID) appObjID := to.String(app.ObjectID) + // Write a WAL entry in case the SP create process doesn't complete + walID, err := framework.PutWAL(ctx, s, walAppKey, &walApp{ + AppID: appID, + AppObjID: appObjID, + Expiration: time.Now().Add(maxWALAge), + }) + if err != nil { + return nil, errwrap.Wrapf("error writing WAL: {{err}}", err) + } + // Create a service principal associated with the new App sp, password, err := c.createSP(ctx, app, spExpiration) if err != nil { - c.deleteApp(ctx, appObjID) return nil, err } // Assign Azure roles to the new SP raIDs, err := c.assignRoles(ctx, sp, role.AzureRoles) if err != nil { - c.deleteApp(ctx, appObjID) return nil, err } // Assign Azure group memberships to the new SP if err := c.addGroupMemberships(ctx, sp, role.AzureGroups); err != nil { - c.deleteApp(ctx, appObjID) return nil, err } + // SP is fully created so delete the WAL + if err := framework.DeleteWAL(ctx, s, walID); err != nil { + return nil, errwrap.Wrapf("error deleting WAL: {{err}}", err) + } + data := map[string]interface{}{ "client_id": appID, "client_secret": password, diff --git a/vendor/github.com/hashicorp/vault-plugin-secrets-azure/wal.go b/vendor/github.com/hashicorp/vault-plugin-secrets-azure/wal.go new file mode 100644 index 000000000000..f3dc4ede3691 --- /dev/null +++ b/vendor/github.com/hashicorp/vault-plugin-secrets-azure/wal.go @@ -0,0 +1,62 @@ +package azuresecrets + +import ( + "context" + "fmt" + "time" + + "github.com/hashicorp/vault/sdk/logical" + "github.com/mitchellh/mapstructure" +) + +const walAppKey = "appCreate" + +// Eventually expire the WAL if for some reason the rollback operation consistently fails +var maxWALAge = 24 * time.Hour + +type walApp struct { + AppID string + AppObjID string + Expiration time.Time +} + +func (b *azureSecretBackend) walRollback(ctx context.Context, req *logical.Request, kind string, data interface{}) error { + if kind != walAppKey { + return fmt.Errorf("unknown rollback type %q", kind) + } + // Decode the WAL data + var entry walApp + d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ + DecodeHook: mapstructure.StringToTimeHookFunc(time.RFC3339), + Result: &entry, + }) + if err != nil { + return err + } + err = d.Decode(data) + if err != nil { + return err + } + + client, err := b.getClient(ctx, req.Storage) + if err != nil { + return err + } + + b.Logger().Debug("rolling back SP", "appID", entry.AppID, "appObjID", entry.AppObjID) + + // Attempt to delete the App. deleteApp doesn't return an error if the app isn't + // found, so no special handling is needed for that case. If we don't succeed within + // maxWALAge (e.g. client creds have changed and the delete will never succeed), + // unconditionally remove the WAL. + if err := client.deleteApp(ctx, entry.AppObjID); err != nil { + b.Logger().Warn("rollback error deleting App", "err", err) + + if time.Now().After(entry.Expiration) { + return nil + } + return err + } + + return nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 03830ce33356..ef640cb62165 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -418,7 +418,7 @@ github.com/hashicorp/vault-plugin-secrets-ad/plugin/util # github.com/hashicorp/vault-plugin-secrets-alicloud v0.5.5 github.com/hashicorp/vault-plugin-secrets-alicloud github.com/hashicorp/vault-plugin-secrets-alicloud/clients -# github.com/hashicorp/vault-plugin-secrets-azure v0.5.6 +# github.com/hashicorp/vault-plugin-secrets-azure v0.5.7-0.20200818192400-40b6e36f1c79 github.com/hashicorp/vault-plugin-secrets-azure # github.com/hashicorp/vault-plugin-secrets-gcp v0.6.2-0.20200617162044-4a67a90aaca5 github.com/hashicorp/vault-plugin-secrets-gcp/plugin