Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update api.Client for isolated read-after-write support #1188

Merged
merged 12 commits into from
Oct 14, 2021
2 changes: 1 addition & 1 deletion GNUmakefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
TEST?=$$(go list ./...)
TEST?=$$(go list ./... | grep '/vault$$')
GOFMT_FILES?=$$(find . -name '*.go')
WEBSITE_REPO=github.com/hashicorp/terraform-website
PKG_NAME=vault
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ require (
github.com/gosimple/slug v1.4.1
github.com/hashicorp/errwrap v1.1.0
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/hashicorp/go-hclog v0.16.1
github.com/hashicorp/go-hclog v0.16.2
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/go-retryablehttp v0.6.8 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1
github.com/hashicorp/terraform-plugin-sdk/v2 v2.8.0
github.com/hashicorp/vault v1.2.0
github.com/hashicorp/vault/api v1.1.2-0.20210719211531-6b31c12b0af2
github.com/hashicorp/vault/api v1.1.2-0.20211007120609-7bd2be52c891
vinay-gopalan marked this conversation as resolved.
Show resolved Hide resolved
github.com/hashicorp/vault/sdk v0.2.1
github.com/mitchellh/go-homedir v1.1.0
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,8 @@ github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.15.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.16.1 h1:IVQwpTGNRRIHafnTs2dQLIk4ENtneRIEEJWOVDqz99o=
github.com/hashicorp/go-hclog v0.16.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.16.2 h1:K4ev2ib4LdQETX5cSZBG0DVLk1jwGqSPXBjdah3veNs=
github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.1.0 h1:vN9wG1D6KG6YHRTWr8512cxGOVgTMEfgEdSj/hr8MPc=
github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
Expand Down Expand Up @@ -488,8 +488,8 @@ github.com/hashicorp/vault/api v1.0.1/go.mod h1:AV/+M5VPDpB90arloVX0rVDUIHkONiwz
github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q=
github.com/hashicorp/vault/api v1.0.5-0.20190730042357-746c0b111519/go.mod h1:i9PKqwFko/s/aihU1uuHGh/FaQS+Xcgvd9dvnfAvQb0=
github.com/hashicorp/vault/api v1.0.5-0.20200519221902-385fac77e20f/go.mod h1:euTFbi2YJgwcju3imEt919lhJKF68nN1cQPq3aA+kBE=
github.com/hashicorp/vault/api v1.1.2-0.20210719211531-6b31c12b0af2 h1:USe1c6Hqxe8VHcSMh1J/UAF9YWC89V1G1ZdgVLSaSFk=
github.com/hashicorp/vault/api v1.1.2-0.20210719211531-6b31c12b0af2/go.mod h1:zjj22aA35OvtC52m/PKTDkzkwMjNX/yyhx4VGoBhvIE=
github.com/hashicorp/vault/api v1.1.2-0.20211007120609-7bd2be52c891 h1:d6toaeUIc8khu3EWBv5wF4uPB+5R3H+zUAkdc7HhSzI=
github.com/hashicorp/vault/api v1.1.2-0.20211007120609-7bd2be52c891/go.mod h1:9U4a2WCiFAjrhzef8lA6BnG05/t5yYjaJ3pgSmOMPYU=
github.com/hashicorp/vault/sdk v0.1.8/go.mod h1:tHZfc6St71twLizWNHvnnbiGFo1aq0eD2jGPLtP8kAU=
github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
github.com/hashicorp/vault/sdk v0.1.14-0.20190729200543-e88721c7db1e/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
Expand Down
73 changes: 73 additions & 0 deletions vault/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package vault

import (
"sync"

"github.com/hashicorp/vault/api"
)

const indexHeaderName = "X-Vault-Index"

// ClientFactory ensures a consistent way of managing Vault clients for the provider.
// The factory ensures that all api.Client instances support the Client Controlled Consistency
// model (VLT-146).
// All Client instances share the same replication state store.
type ClientFactory struct {
benashz marked this conversation as resolved.
Show resolved Hide resolved
m sync.RWMutex
states []string
client *api.Client
}

// Client for this factory
func (w *ClientFactory) Client() *api.Client {
return w.client
}

// Clone this factory's Client
// Note: even though it is possible to clone the clone, it should be avoided as the
// clone will no longer track replication states.
func (w *ClientFactory) Clone() (*api.Client, error) {
c, err := w.Client().Clone()
if err != nil {
return nil, err
}

return w.registerCallbacks(c), nil
}

func (w *ClientFactory) registerCallbacks(c *api.Client) *api.Client {
return c.WithRequestCallbacks(w.requireStates).
WithResponseCallbacks(w.recordStates)
}

func (w *ClientFactory) recordStates(resp *api.Response) {
w.m.Lock()
defer w.m.Unlock()
newState := resp.Header.Get(indexHeaderName)
if newState != "" {
w.states = api.MergeReplicationStates(w.states, newState)
}
}

func (w *ClientFactory) requireStates(req *api.Request) {
w.m.RLock()
defer w.m.RUnlock()
for _, s := range w.states {
req.Headers.Add(indexHeaderName, s)
}
}

// NewClientFactory sets up a new ClientFactory
func NewClientFactory(config *api.Config) (*ClientFactory, error) {
client, err := api.NewClient(config)
if err != nil {
return nil, err
}

wrapper := &ClientFactory{
states: []string{},
}
wrapper.client = wrapper.registerCallbacks(client)

return wrapper, nil
}