@@ -51,6 +51,8 @@ const (
51
51
EnvRateLimit = "VAULT_RATE_LIMIT"
52
52
EnvHTTPProxy = "VAULT_HTTP_PROXY"
53
53
HeaderIndex = "X-Vault-Index"
54
+ HeaderForward = "X-Vault-Forward"
55
+ HeaderInconsistent = "X-Vault-Inconsistent"
54
56
)
55
57
56
58
// Deprecated values
@@ -132,13 +134,22 @@ type Config struct {
132
134
// with the same client. Cloning a client will not clone this value.
133
135
OutputCurlString bool
134
136
137
+ // curlCACert, curlCAPath, curlClientCert and curlClientKey are used to keep
138
+ // track of the name of the TLS certs and keys when OutputCurlString is set.
139
+ // Cloning a client will also not clone those values.
140
+ curlCACert , curlCAPath string
141
+ curlClientCert , curlClientKey string
142
+
135
143
// SRVLookup enables the client to lookup the host through DNS SRV lookup
136
144
SRVLookup bool
137
145
138
146
// CloneHeaders ensures that the source client's headers are copied to
139
147
// its clone.
140
148
CloneHeaders bool
141
149
150
+ // CloneToken from parent.
151
+ CloneToken bool
152
+
142
153
// ReadYourWrites ensures isolated read-after-write semantics by
143
154
// providing discovered cluster replication states in each request.
144
155
// The shared state is automatically propagated to all Client clones.
@@ -180,7 +191,7 @@ type TLSConfig struct {
180
191
// The default Address is https://127.0.0.1:8200, but this can be overridden by
181
192
// setting the `VAULT_ADDR` environment variable.
182
193
//
183
- // If an error is encountered, this will return nil .
194
+ // If an error is encountered, the Error field on the returned *Config will be populated with the specific error .
184
195
func DefaultConfig () * Config {
185
196
config := & Config {
186
197
Address : "https://127.0.0.1:8200" ,
@@ -222,9 +233,9 @@ func DefaultConfig() *Config {
222
233
return config
223
234
}
224
235
225
- // ConfigureTLS takes a set of TLS configurations and applies those to the
226
- // HTTP client.
227
- func (c * Config ) ConfigureTLS (t * TLSConfig ) error {
236
+ // configureTLS is a lock free version of ConfigureTLS that can be used in
237
+ // ReadEnvironment where the lock is already hold
238
+ func (c * Config ) configureTLS (t * TLSConfig ) error {
228
239
if c .HttpClient == nil {
229
240
c .HttpClient = DefaultConfig ().HttpClient
230
241
}
@@ -241,11 +252,15 @@ func (c *Config) ConfigureTLS(t *TLSConfig) error {
241
252
return err
242
253
}
243
254
foundClientCert = true
255
+ c .curlClientCert = t .ClientCert
256
+ c .curlClientKey = t .ClientKey
244
257
case t .ClientCert != "" || t .ClientKey != "" :
245
258
return fmt .Errorf ("both client cert and client key must be provided" )
246
259
}
247
260
248
261
if t .CACert != "" || t .CAPath != "" {
262
+ c .curlCACert = t .CACert
263
+ c .curlCAPath = t .CAPath
249
264
rootConfig := & rootcerts.Config {
250
265
CAFile : t .CACert ,
251
266
CAPath : t .CAPath ,
@@ -275,6 +290,15 @@ func (c *Config) ConfigureTLS(t *TLSConfig) error {
275
290
return nil
276
291
}
277
292
293
+ // ConfigureTLS takes a set of TLS configurations and applies those to the
294
+ // HTTP client.
295
+ func (c * Config ) ConfigureTLS (t * TLSConfig ) error {
296
+ c .modifyLock .Lock ()
297
+ defer c .modifyLock .Unlock ()
298
+
299
+ return c .configureTLS (t )
300
+ }
301
+
278
302
// ReadEnvironment reads configuration information from the environment. If
279
303
// there is an error, no configuration value is updated.
280
304
func (c * Config ) ReadEnvironment () error {
@@ -379,7 +403,7 @@ func (c *Config) ReadEnvironment() error {
379
403
c .SRVLookup = envSRVLookup
380
404
c .Limiter = limit
381
405
382
- if err := c .ConfigureTLS (t ); err != nil {
406
+ if err := c .configureTLS (t ); err != nil {
383
407
return err
384
408
}
385
409
@@ -547,6 +571,7 @@ func (c *Client) CloneConfig() *Config {
547
571
newConfig .OutputCurlString = c .config .OutputCurlString
548
572
newConfig .SRVLookup = c .config .SRVLookup
549
573
newConfig .CloneHeaders = c .config .CloneHeaders
574
+ newConfig .CloneToken = c .config .CloneToken
550
575
newConfig .ReadYourWrites = c .config .ReadYourWrites
551
576
552
577
// we specifically want a _copy_ of the client here, not a pointer to the original one
@@ -775,6 +800,12 @@ func (c *Client) setNamespace(namespace string) {
775
800
c .headers .Set (consts .NamespaceHeaderName , namespace )
776
801
}
777
802
803
+ func (c * Client ) ClearNamespace () {
804
+ c .modifyLock .Lock ()
805
+ defer c .modifyLock .Unlock ()
806
+ c .headers .Del (consts .NamespaceHeaderName )
807
+ }
808
+
778
809
// Token returns the access token being used by this client. It will
779
810
// return the empty string if there is no token set.
780
811
func (c * Client ) Token () string {
@@ -873,6 +904,26 @@ func (c *Client) CloneHeaders() bool {
873
904
return c .config .CloneHeaders
874
905
}
875
906
907
+ // SetCloneToken from parent
908
+ func (c * Client ) SetCloneToken (cloneToken bool ) {
909
+ c .modifyLock .Lock ()
910
+ defer c .modifyLock .Unlock ()
911
+ c .config .modifyLock .Lock ()
912
+ defer c .config .modifyLock .Unlock ()
913
+
914
+ c .config .CloneToken = cloneToken
915
+ }
916
+
917
+ // CloneToken gets the configured CloneToken value.
918
+ func (c * Client ) CloneToken () bool {
919
+ c .modifyLock .RLock ()
920
+ defer c .modifyLock .RUnlock ()
921
+ c .config .modifyLock .RLock ()
922
+ defer c .config .modifyLock .RUnlock ()
923
+
924
+ return c .config .CloneToken
925
+ }
926
+
876
927
// SetReadYourWrites to prevent reading stale cluster replication state.
877
928
func (c * Client ) SetReadYourWrites (preventStaleReads bool ) {
878
929
c .modifyLock .Lock ()
@@ -904,12 +955,25 @@ func (c *Client) ReadYourWrites() bool {
904
955
// Clone creates a new client with the same configuration. Note that the same
905
956
// underlying http.Client is used; modifying the client from more than one
906
957
// goroutine at once may not be safe, so modify the client as needed and then
907
- // clone.
958
+ // clone. The headers are cloned based on the CloneHeaders property of the
959
+ // source config
908
960
//
909
961
// Also, only the client's config is currently copied; this means items not in
910
962
// the api.Config struct, such as policy override and wrapping function
911
963
// behavior, must currently then be set as desired on the new client.
912
964
func (c * Client ) Clone () (* Client , error ) {
965
+ return c .clone (c .config .CloneHeaders )
966
+ }
967
+
968
+ // CloneWithHeaders creates a new client similar to Clone, with the difference
969
+ // being that the headers are always cloned
970
+ func (c * Client ) CloneWithHeaders () (* Client , error ) {
971
+ return c .clone (true )
972
+ }
973
+
974
+ // clone creates a new client, with the headers being cloned based on the
975
+ // passed in cloneheaders boolean
976
+ func (c * Client ) clone (cloneHeaders bool ) (* Client , error ) {
913
977
c .modifyLock .RLock ()
914
978
defer c .modifyLock .RUnlock ()
915
979
@@ -932,17 +996,22 @@ func (c *Client) Clone() (*Client, error) {
932
996
AgentAddress : config .AgentAddress ,
933
997
SRVLookup : config .SRVLookup ,
934
998
CloneHeaders : config .CloneHeaders ,
999
+ CloneToken : config .CloneToken ,
935
1000
ReadYourWrites : config .ReadYourWrites ,
936
1001
}
937
1002
client , err := NewClient (newConfig )
938
1003
if err != nil {
939
1004
return nil , err
940
1005
}
941
1006
942
- if config . CloneHeaders {
1007
+ if cloneHeaders {
943
1008
client .SetHeaders (c .Headers ().Clone ())
944
1009
}
945
1010
1011
+ if config .CloneToken {
1012
+ client .SetToken (c .token )
1013
+ }
1014
+
946
1015
client .replicationStateStore = c .replicationStateStore
947
1016
948
1017
return client , nil
@@ -1080,6 +1149,10 @@ START:
1080
1149
LastOutputStringError = & OutputStringError {
1081
1150
Request : req ,
1082
1151
TLSSkipVerify : c .config .HttpClient .Transport .(* http.Transport ).TLSClientConfig .InsecureSkipVerify ,
1152
+ ClientCert : c .config .curlClientCert ,
1153
+ ClientKey : c .config .curlClientKey ,
1154
+ ClientCACert : c .config .curlCACert ,
1155
+ ClientCAPath : c .config .curlCAPath ,
1083
1156
}
1084
1157
return nil , LastOutputStringError
1085
1158
}
@@ -1330,7 +1403,7 @@ func ParseReplicationState(raw string, hmacKey []byte) (*logical.WALState, error
1330
1403
// conjunction with RequireState.
1331
1404
func ForwardInconsistent () RequestCallback {
1332
1405
return func (req * Request ) {
1333
- req .Headers .Set ("X-Vault-Inconsistent" , "forward-active-node" )
1406
+ req .Headers .Set (HeaderInconsistent , "forward-active-node" )
1334
1407
}
1335
1408
}
1336
1409
@@ -1339,7 +1412,7 @@ func ForwardInconsistent() RequestCallback {
1339
1412
// This feature must be enabled in Vault's configuration.
1340
1413
func ForwardAlways () RequestCallback {
1341
1414
return func (req * Request ) {
1342
- req .Headers .Set ("X-Vault-Forward" , "active-node" )
1415
+ req .Headers .Set (HeaderForward , "active-node" )
1343
1416
}
1344
1417
}
1345
1418
0 commit comments