mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-30 18:17:55 +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 bool | ||||
|  | ||||
| 	// CloneTLSConfig from parent (tls.Config). | ||||
| 	CloneTLSConfig bool | ||||
|  | ||||
| 	// ReadYourWrites ensures isolated read-after-write semantics by | ||||
| 	// providing discovered cluster replication states in each request. | ||||
| 	// 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 { | ||||
| 		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 | ||||
| 	foundClientCert := false | ||||
| @@ -1143,6 +1153,26 @@ func (c *Client) ReadYourWrites() bool { | ||||
| 	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 | ||||
| // 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 | ||||
| @@ -1189,6 +1219,11 @@ func (c *Client) clone(cloneHeaders bool) (*Client, error) { | ||||
| 		CloneToken:     config.CloneToken, | ||||
| 		ReadYourWrites: config.ReadYourWrites, | ||||
| 	} | ||||
|  | ||||
| 	if config.CloneTLSConfig { | ||||
| 		newConfig.clientTLSConfig = config.clientTLSConfig | ||||
| 	} | ||||
|  | ||||
| 	client, err := NewClient(newConfig) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
|   | ||||
| @@ -6,6 +6,7 @@ package api | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"context" | ||||
| 	"crypto/tls" | ||||
| 	"crypto/x509" | ||||
| 	"encoding/base64" | ||||
| 	"fmt" | ||||
| @@ -591,6 +592,24 @@ func TestClone(t *testing.T) { | ||||
| 			}, | ||||
| 			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 { | ||||
| @@ -699,6 +718,22 @@ func TestClone(t *testing.T) { | ||||
| 				t.Fatalf("expected replicationStateStore %v, actual %v", parent.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