mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 02:28:09 +00:00 
			
		
		
		
	Minor improvements to test cluster libraries (#25329)
Add WaitForMatchingMerkleRootsClients and Clients to sdk testcluster. Fix internal TestCluster.SetRootToken, which wasn't updating the builtin clients' token.
This commit is contained in:
		
							
								
								
									
										3
									
								
								changelog/25329.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								changelog/25329.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | ```release-note:improvement | ||||||
|  | sdk/helper/testcluster: add some new helpers, improve some error messages. | ||||||
|  | ``` | ||||||
| @@ -433,30 +433,6 @@ func RekeyCluster(t testing.T, cluster *vault.TestCluster, recovery bool) [][]by | |||||||
| 	return newKeys | 	return newKeys | ||||||
| } | } | ||||||
|  |  | ||||||
| func RaftClusterJoinNodes(t testing.T, cluster *vault.TestCluster) { |  | ||||||
| 	leader := cluster.Cores[0] |  | ||||||
|  |  | ||||||
| 	leaderInfos := []*raft.LeaderJoinInfo{ |  | ||||||
| 		{ |  | ||||||
| 			LeaderAPIAddr: leader.Client.Address(), |  | ||||||
| 			TLSConfig:     leader.TLSConfig(), |  | ||||||
| 		}, |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Join followers |  | ||||||
| 	for i := 1; i < len(cluster.Cores); i++ { |  | ||||||
| 		core := cluster.Cores[i] |  | ||||||
| 		_, err := core.JoinRaftCluster(namespace.RootContext(context.Background()), leaderInfos, false) |  | ||||||
| 		if err != nil { |  | ||||||
| 			t.Fatal(err) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		cluster.UnsealCore(t, core) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	WaitForNCoresUnsealed(t, cluster, len(cluster.Cores)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // HardcodedServerAddressProvider is a ServerAddressProvider that uses | // HardcodedServerAddressProvider is a ServerAddressProvider that uses | ||||||
| // a hardcoded map of raft node addresses. | // a hardcoded map of raft node addresses. | ||||||
| // | // | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ | |||||||
| package teststorage | package teststorage | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| 	"math/rand" | 	"math/rand" | ||||||
| @@ -18,7 +19,7 @@ import ( | |||||||
| 	auditSyslog "github.com/hashicorp/vault/builtin/audit/syslog" | 	auditSyslog "github.com/hashicorp/vault/builtin/audit/syslog" | ||||||
| 	logicalDb "github.com/hashicorp/vault/builtin/logical/database" | 	logicalDb "github.com/hashicorp/vault/builtin/logical/database" | ||||||
| 	"github.com/hashicorp/vault/builtin/plugin" | 	"github.com/hashicorp/vault/builtin/plugin" | ||||||
| 	"github.com/hashicorp/vault/helper/testhelpers" | 	"github.com/hashicorp/vault/helper/namespace" | ||||||
| 	"github.com/hashicorp/vault/helper/testhelpers/corehelpers" | 	"github.com/hashicorp/vault/helper/testhelpers/corehelpers" | ||||||
| 	vaulthttp "github.com/hashicorp/vault/http" | 	vaulthttp "github.com/hashicorp/vault/http" | ||||||
| 	"github.com/hashicorp/vault/internalshared/configutil" | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| @@ -233,6 +234,28 @@ func FileBackendSetup(conf *vault.CoreConfig, opts *vault.TestClusterOptions) { | |||||||
| 	opts.PhysicalFactory = SharedPhysicalFactory(MakeFileBackend) | 	opts.PhysicalFactory = SharedPhysicalFactory(MakeFileBackend) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func RaftClusterJoinNodes(t testing.T, cluster *vault.TestCluster) { | ||||||
|  | 	leader := cluster.Cores[0] | ||||||
|  |  | ||||||
|  | 	leaderInfos := []*raft.LeaderJoinInfo{ | ||||||
|  | 		{ | ||||||
|  | 			LeaderAPIAddr: leader.Client.Address(), | ||||||
|  | 			TLSConfig:     leader.TLSConfig(), | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Join followers | ||||||
|  | 	for i := 1; i < len(cluster.Cores); i++ { | ||||||
|  | 		core := cluster.Cores[i] | ||||||
|  | 		_, err := core.JoinRaftCluster(namespace.RootContext(context.Background()), leaderInfos, false) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatal(err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		cluster.UnsealCore(t, core) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func RaftBackendSetup(conf *vault.CoreConfig, opts *vault.TestClusterOptions) { | func RaftBackendSetup(conf *vault.CoreConfig, opts *vault.TestClusterOptions) { | ||||||
| 	opts.KeepStandbysSealed = true | 	opts.KeepStandbysSealed = true | ||||||
| 	var bridge *raft.ClusterAddrBridge | 	var bridge *raft.ClusterAddrBridge | ||||||
| @@ -252,7 +275,7 @@ func RaftBackendSetup(conf *vault.CoreConfig, opts *vault.TestClusterOptions) { | |||||||
| 	} | 	} | ||||||
| 	opts.SetupFunc = func(t testing.T, c *vault.TestCluster) { | 	opts.SetupFunc = func(t testing.T, c *vault.TestCluster) { | ||||||
| 		if opts.NumCores != 1 { | 		if opts.NumCores != 1 { | ||||||
| 			testhelpers.RaftClusterJoinNodes(t, c) | 			RaftClusterJoinNodes(t, c) | ||||||
| 			time.Sleep(15 * time.Second) | 			time.Sleep(15 * time.Second) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -42,12 +42,12 @@ func EnablePerfPrimary(ctx context.Context, pri VaultCluster) error { | |||||||
| 	client := pri.Nodes()[0].APIClient() | 	client := pri.Nodes()[0].APIClient() | ||||||
| 	_, err := client.Logical().WriteWithContext(ctx, "sys/replication/performance/primary/enable", nil) | 	_, err := client.Logical().WriteWithContext(ctx, "sys/replication/performance/primary/enable", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return fmt.Errorf("error enabling perf primary: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = WaitForPerfReplicationState(ctx, pri, consts.ReplicationPerformancePrimary) | 	err = WaitForPerfReplicationState(ctx, pri, consts.ReplicationPerformancePrimary) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return fmt.Errorf("error waiting for perf primary to have the correct state: %w", err) | ||||||
| 	} | 	} | ||||||
| 	return WaitForActiveNodeAndPerfStandbys(ctx, pri) | 	return WaitForActiveNodeAndPerfStandbys(ctx, pri) | ||||||
| } | } | ||||||
| @@ -108,6 +108,10 @@ func EnablePerformanceSecondary(ctx context.Context, perfToken string, pri, sec | |||||||
| } | } | ||||||
|  |  | ||||||
| func WaitForMatchingMerkleRoots(ctx context.Context, endpoint string, pri, sec VaultCluster) error { | func WaitForMatchingMerkleRoots(ctx context.Context, endpoint string, pri, sec VaultCluster) error { | ||||||
|  | 	return WaitForMatchingMerkleRootsClients(ctx, endpoint, pri.Nodes()[0].APIClient(), sec.Nodes()[0].APIClient()) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func WaitForMatchingMerkleRootsClients(ctx context.Context, endpoint string, pri, sec *api.Client) error { | ||||||
| 	getRoot := func(mode string, cli *api.Client) (string, error) { | 	getRoot := func(mode string, cli *api.Client) (string, error) { | ||||||
| 		status, err := cli.Logical().Read(endpoint + "status") | 		status, err := cli.Logical().Read(endpoint + "status") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| @@ -122,16 +126,19 @@ func WaitForMatchingMerkleRoots(ctx context.Context, endpoint string, pri, sec V | |||||||
| 		return status.Data["merkle_root"].(string), nil | 		return status.Data["merkle_root"].(string), nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	secClient := sec.Nodes()[0].APIClient() | 	var priRoot, secRoot string | ||||||
| 	priClient := pri.Nodes()[0].APIClient() | 	var err error | ||||||
| 	for i := 0; i < 30; i++ { | 	genRet := func() error { | ||||||
| 		secRoot, err := getRoot("secondary", secClient) | 		return fmt.Errorf("unequal merkle roots, pri=%s sec=%s, err=%w", priRoot, secRoot, err) | ||||||
|  | 	} | ||||||
|  | 	for ctx.Err() == nil { | ||||||
|  | 		secRoot, err = getRoot("secondary", sec) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return genRet() | ||||||
| 		} | 		} | ||||||
| 		priRoot, err := getRoot("primary", priClient) | 		priRoot, err = getRoot("primary", pri) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return genRet() | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if reflect.DeepEqual(priRoot, secRoot) { | 		if reflect.DeepEqual(priRoot, secRoot) { | ||||||
| @@ -281,15 +288,18 @@ func WaitForPerfReplicationWorking(ctx context.Context, pri, sec VaultCluster) e | |||||||
|  |  | ||||||
| func SetupTwoClusterPerfReplication(ctx context.Context, pri, sec VaultCluster) error { | func SetupTwoClusterPerfReplication(ctx context.Context, pri, sec VaultCluster) error { | ||||||
| 	if err := EnablePerfPrimary(ctx, pri); err != nil { | 	if err := EnablePerfPrimary(ctx, pri); err != nil { | ||||||
| 		return err | 		return fmt.Errorf("failed to enable perf primary: %w", err) | ||||||
| 	} | 	} | ||||||
| 	perfToken, err := GetPerformanceToken(pri, sec.ClusterID(), "") | 	perfToken, err := GetPerformanceToken(pri, sec.ClusterID(), "") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return fmt.Errorf("failed to get performance token from perf primary: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	_, err = EnablePerformanceSecondary(ctx, perfToken, pri, sec, false, false) | 	_, err = EnablePerformanceSecondary(ctx, perfToken, pri, sec, false, false) | ||||||
| 	return err | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("failed to enable perf secondary: %w", err) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // PassiveWaitForActiveNodeAndPerfStandbys should be used instead of | // PassiveWaitForActiveNodeAndPerfStandbys should be used instead of | ||||||
|   | |||||||
| @@ -281,7 +281,7 @@ func WaitForActiveNodeAndPerfStandbys(ctx context.Context, cluster VaultCluster) | |||||||
| 	// this call to WaitForActiveNode by reworking the logic in this method. | 	// this call to WaitForActiveNode by reworking the logic in this method. | ||||||
| 	leaderIdx, err := WaitForActiveNode(ctx, cluster) | 	leaderIdx, err := WaitForActiveNode(ctx, cluster) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return fmt.Errorf("did not find leader: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(cluster.Nodes()) == 1 { | 	if len(cluster.Nodes()) == 1 { | ||||||
| @@ -307,7 +307,7 @@ func WaitForActiveNodeAndPerfStandbys(ctx context.Context, cluster VaultCluster) | |||||||
| 		time.Sleep(1 * time.Second) | 		time.Sleep(1 * time.Second) | ||||||
| 	} | 	} | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("unable to mount KV engine: %v", err) | 		return fmt.Errorf("unable to mount KV engine: %w", err) | ||||||
| 	} | 	} | ||||||
| 	path := mountPoint + "/waitforactivenodeandperfstandbys" | 	path := mountPoint + "/waitforactivenodeandperfstandbys" | ||||||
| 	var standbys, actives int64 | 	var standbys, actives int64 | ||||||
| @@ -381,11 +381,19 @@ func WaitForActiveNodeAndPerfStandbys(ctx context.Context, cluster VaultCluster) | |||||||
| 		time.Sleep(time.Second) | 		time.Sleep(time.Second) | ||||||
| 	} | 	} | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("unable to unmount KV engine on primary") | 		return fmt.Errorf("unable to unmount KV engine: %w", err) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func Clients(vc VaultCluster) []*api.Client { | ||||||
|  | 	var ret []*api.Client | ||||||
|  | 	for _, n := range vc.Nodes() { | ||||||
|  | 		ret = append(ret, n.APIClient()) | ||||||
|  | 	} | ||||||
|  | 	return ret | ||||||
|  | } | ||||||
|  |  | ||||||
| type GenerateRootKind int | type GenerateRootKind int | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
|   | |||||||
| @@ -717,6 +717,9 @@ type TestCluster struct { | |||||||
|  |  | ||||||
| func (c *TestCluster) SetRootToken(token string) { | func (c *TestCluster) SetRootToken(token string) { | ||||||
| 	c.RootToken = token | 	c.RootToken = token | ||||||
|  | 	for _, c := range c.Cores { | ||||||
|  | 		c.Client.SetToken(token) | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *TestCluster) Start() { | func (c *TestCluster) Start() { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Nick Cabatoff
					Nick Cabatoff