mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 18:48:08 +00:00 
			
		
		
		
	Add support for cloning a Client's tls.Config (#21424)
Additional fixes: - handle a failed type assert in api.Config.configureTLS() Co-authored-by: Anton Averchenkov <84287187+averche@users.noreply.github.com>
This commit is contained in:
		| @@ -185,6 +185,9 @@ type Config struct { | |||||||
| 	// CloneToken from parent. | 	// CloneToken from parent. | ||||||
| 	CloneToken bool | 	CloneToken bool | ||||||
|  |  | ||||||
|  | 	// CloneTLSConfig from parent (tls.Config). | ||||||
|  | 	CloneTLSConfig bool | ||||||
|  |  | ||||||
| 	// ReadYourWrites ensures isolated read-after-write semantics by | 	// ReadYourWrites ensures isolated read-after-write semantics by | ||||||
| 	// providing discovered cluster replication states in each request. | 	// providing discovered cluster replication states in each request. | ||||||
| 	// The shared state is automatically propagated to all Client clones. | 	// The shared state is automatically propagated to all Client clones. | ||||||
| @@ -290,7 +293,14 @@ func (c *Config) configureTLS(t *TLSConfig) error { | |||||||
| 	if c.HttpClient == nil { | 	if c.HttpClient == nil { | ||||||
| 		c.HttpClient = DefaultConfig().HttpClient | 		c.HttpClient = DefaultConfig().HttpClient | ||||||
| 	} | 	} | ||||||
| 	clientTLSConfig := c.HttpClient.Transport.(*http.Transport).TLSClientConfig |  | ||||||
|  | 	transport, ok := c.HttpClient.Transport.(*http.Transport) | ||||||
|  | 	if !ok { | ||||||
|  | 		return fmt.Errorf( | ||||||
|  | 			"unsupported HTTPClient transport type %T", c.HttpClient.Transport) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	clientTLSConfig := transport.TLSClientConfig | ||||||
|  |  | ||||||
| 	var clientCert tls.Certificate | 	var clientCert tls.Certificate | ||||||
| 	foundClientCert := false | 	foundClientCert := false | ||||||
| @@ -1143,6 +1153,26 @@ func (c *Client) ReadYourWrites() bool { | |||||||
| 	return c.config.ReadYourWrites | 	return c.config.ReadYourWrites | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // SetCloneTLSConfig from parent. | ||||||
|  | func (c *Client) SetCloneTLSConfig(clone bool) { | ||||||
|  | 	c.modifyLock.Lock() | ||||||
|  | 	defer c.modifyLock.Unlock() | ||||||
|  | 	c.config.modifyLock.Lock() | ||||||
|  | 	defer c.config.modifyLock.Unlock() | ||||||
|  |  | ||||||
|  | 	c.config.CloneTLSConfig = clone | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // CloneTLSConfig gets the configured CloneTLSConfig value. | ||||||
|  | func (c *Client) CloneTLSConfig() bool { | ||||||
|  | 	c.modifyLock.RLock() | ||||||
|  | 	defer c.modifyLock.RUnlock() | ||||||
|  | 	c.config.modifyLock.RLock() | ||||||
|  | 	defer c.config.modifyLock.RUnlock() | ||||||
|  |  | ||||||
|  | 	return c.config.CloneTLSConfig | ||||||
|  | } | ||||||
|  |  | ||||||
| // Clone creates a new client with the same configuration. Note that the same | // Clone creates a new client with the same configuration. Note that the same | ||||||
| // underlying http.Client is used; modifying the client from more than one | // underlying http.Client is used; modifying the client from more than one | ||||||
| // goroutine at once may not be safe, so modify the client as needed and then | // goroutine at once may not be safe, so modify the client as needed and then | ||||||
| @@ -1189,6 +1219,11 @@ func (c *Client) clone(cloneHeaders bool) (*Client, error) { | |||||||
| 		CloneToken:     config.CloneToken, | 		CloneToken:     config.CloneToken, | ||||||
| 		ReadYourWrites: config.ReadYourWrites, | 		ReadYourWrites: config.ReadYourWrites, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if config.CloneTLSConfig { | ||||||
|  | 		newConfig.clientTLSConfig = config.clientTLSConfig | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	client, err := NewClient(newConfig) | 	client, err := NewClient(newConfig) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ package api | |||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"crypto/tls" | ||||||
| 	"crypto/x509" | 	"crypto/x509" | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| @@ -591,6 +592,24 @@ func TestClone(t *testing.T) { | |||||||
| 			}, | 			}, | ||||||
| 			token: "cloneToken", | 			token: "cloneToken", | ||||||
| 		}, | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name: "cloneTLSConfig-enabled", | ||||||
|  | 			config: &Config{ | ||||||
|  | 				CloneTLSConfig: true, | ||||||
|  | 				clientTLSConfig: &tls.Config{ | ||||||
|  | 					ServerName: "foo.bar.baz", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name: "cloneTLSConfig-disabled", | ||||||
|  | 			config: &Config{ | ||||||
|  | 				CloneTLSConfig: false, | ||||||
|  | 				clientTLSConfig: &tls.Config{ | ||||||
|  | 					ServerName: "foo.bar.baz", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for _, tt := range tests { | 	for _, tt := range tests { | ||||||
| @@ -699,6 +718,22 @@ func TestClone(t *testing.T) { | |||||||
| 				t.Fatalf("expected replicationStateStore %v, actual %v", parent.replicationStateStore, | 				t.Fatalf("expected replicationStateStore %v, actual %v", parent.replicationStateStore, | ||||||
| 					clone.replicationStateStore) | 					clone.replicationStateStore) | ||||||
| 			} | 			} | ||||||
|  | 			if tt.config.CloneTLSConfig { | ||||||
|  | 				if !reflect.DeepEqual(parent.config.TLSConfig(), clone.config.TLSConfig()) { | ||||||
|  | 					t.Fatalf("config.clientTLSConfig doesn't match: %v vs %v", | ||||||
|  | 						parent.config.TLSConfig(), clone.config.TLSConfig()) | ||||||
|  | 				} | ||||||
|  | 			} else if tt.config.clientTLSConfig != nil { | ||||||
|  | 				if reflect.DeepEqual(parent.config.TLSConfig(), clone.config.TLSConfig()) { | ||||||
|  | 					t.Fatalf("config.clientTLSConfig should not match: %v vs %v", | ||||||
|  | 						parent.config.TLSConfig(), clone.config.TLSConfig()) | ||||||
|  | 				} | ||||||
|  | 			} else { | ||||||
|  | 				if !reflect.DeepEqual(parent.config.TLSConfig(), clone.config.TLSConfig()) { | ||||||
|  | 					t.Fatalf("config.clientTLSConfig doesn't match: %v vs %v", | ||||||
|  | 						parent.config.TLSConfig(), clone.config.TLSConfig()) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								changelog/21424.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								changelog/21424.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | ```release-note:improvement | ||||||
|  | api: add support for cloning a Client's tls.Config. | ||||||
|  | ``` | ||||||
		Reference in New Issue
	
	Block a user
	 Ben Ash
					Ben Ash