Vishal Nayak 9f980ade31
Seal migration with Raft (#8103)
* Seal migration after unsealing

* Refactor migration fields migrationInformation in core

* Perform seal migration as part of postUnseal

* Remove the sleep logic

* Use proper seal in the unseal function

* Fix migration from Auto to Shamir

* Fix the recovery config missing issue

* Address the non-ha migration case

* Fix the multi cluster case

* Avoid re-running seal migration

* Run the post migration code in new leaders

* Fix the issue of wrong recovery being set

* Address review feedback

* Add more complete testing coverage for seal migrations.   (#8247)

* Add more complete testing coverage for seal migrations.  Also remove VAULT_ACC gate from some tests that just depend on docker, cleanup dangling recovery config in storage after migration, and fix a call in adjustCoreForSealMigration that seems broken.

* Fix the issue of wrong recovery key being set

* Adapt tests to work with multiple cores.

* Add missing line to disable raft join.

Co-authored-by: Vishal Nayak <vishalnayak@users.noreply.github.com>

* Fix all known issues

* Remove warning

* Review feedback.

* Revert my previous change that broke raft tests.  We'll need to come back and at least comment
this once we better understand why it's needed.

* Don't allow migration between same types for now

* Disable auto to auto tests for now since it uses migration between same types which is not allowed

* Update vault/core.go

Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>

* Add migration logs

* Address review comments

* Add the recovery config check back

* Skip a few steps if migration is already done

* Return from waitForLeadership if migration fails

Co-authored-by: ncabatoff <nick.cabatoff@gmail.com>
Co-authored-by: Brian Kassouf <briankassouf@users.noreply.github.com>
2020-02-13 16:27:31 -05:00

186 lines
4.9 KiB
Go

package teststorage
import (
"fmt"
"io/ioutil"
"os"
realtesting "testing"
"time"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/helper/testhelpers"
"github.com/hashicorp/vault/helper/testhelpers/consul"
vaulthttp "github.com/hashicorp/vault/http"
physConsul "github.com/hashicorp/vault/physical/consul"
"github.com/hashicorp/vault/physical/raft"
"github.com/hashicorp/vault/sdk/physical"
physFile "github.com/hashicorp/vault/sdk/physical/file"
"github.com/hashicorp/vault/sdk/physical/inmem"
"github.com/hashicorp/vault/vault"
"github.com/mitchellh/go-testing-interface"
)
func MakeInmemBackend(t testing.T, logger hclog.Logger) *vault.PhysicalBackendBundle {
inm, err := inmem.NewTransactionalInmem(nil, logger)
if err != nil {
t.Fatal(err)
}
inmha, err := inmem.NewInmemHA(nil, logger)
if err != nil {
t.Fatal(err)
}
return &vault.PhysicalBackendBundle{
Backend: inm,
HABackend: inmha.(physical.HABackend),
}
}
func MakeInmemNonTransactionalBackend(t testing.T, logger hclog.Logger) *vault.PhysicalBackendBundle {
inm, err := inmem.NewInmem(nil, logger)
if err != nil {
t.Fatal(err)
}
inmha, err := inmem.NewInmemHA(nil, logger)
if err != nil {
t.Fatal(err)
}
return &vault.PhysicalBackendBundle{
Backend: inm,
HABackend: inmha.(physical.HABackend),
}
}
func MakeFileBackend(t testing.T, logger hclog.Logger) *vault.PhysicalBackendBundle {
path, err := ioutil.TempDir("", "vault-integ-file-")
if err != nil {
t.Fatal(err)
}
fileConf := map[string]string{
"path": path,
}
fileBackend, err := physFile.NewTransactionalFileBackend(fileConf, logger)
if err != nil {
t.Fatal(err)
}
inmha, err := inmem.NewInmemHA(nil, logger)
if err != nil {
t.Fatal(err)
}
return &vault.PhysicalBackendBundle{
Backend: fileBackend,
HABackend: inmha.(physical.HABackend),
Cleanup: func() {
err := os.RemoveAll(path)
if err != nil {
t.Fatal(err)
}
},
}
}
func MakeConsulBackend(t testing.T, logger hclog.Logger) *vault.PhysicalBackendBundle {
cleanup, consulAddress, consulToken := consul.PrepareTestContainer(t.(*realtesting.T), "1.4.0-rc1")
consulConf := map[string]string{
"address": consulAddress,
"token": consulToken,
"max_parallel": "32",
}
consulBackend, err := physConsul.NewConsulBackend(consulConf, logger)
if err != nil {
t.Fatal(err)
}
return &vault.PhysicalBackendBundle{
Backend: consulBackend,
Cleanup: cleanup,
}
}
func MakeRaftBackend(t testing.T, coreIdx int, logger hclog.Logger) *vault.PhysicalBackendBundle {
nodeID := fmt.Sprintf("core-%d", coreIdx)
raftDir, err := ioutil.TempDir("", "vault-raft-")
if err != nil {
t.Fatal(err)
}
t.Logf("raft dir: %s", raftDir)
cleanupFunc := func() {
os.RemoveAll(raftDir)
}
logger.Info("raft dir", "dir", raftDir)
conf := map[string]string{
"path": raftDir,
"node_id": nodeID,
"performance_multiplier": "8",
}
backend, err := raft.NewRaftBackend(conf, logger)
if err != nil {
cleanupFunc()
t.Fatal(err)
}
return &vault.PhysicalBackendBundle{
Backend: backend,
Cleanup: cleanupFunc,
}
}
type ClusterSetupMutator func(conf *vault.CoreConfig, opts *vault.TestClusterOptions)
func SharedPhysicalFactory(f func(t testing.T, logger hclog.Logger) *vault.PhysicalBackendBundle) func(t testing.T, coreIdx int, logger hclog.Logger) *vault.PhysicalBackendBundle {
return func(t testing.T, coreIdx int, logger hclog.Logger) *vault.PhysicalBackendBundle {
if coreIdx == 0 {
return f(t, logger)
}
return nil
}
}
func InmemBackendSetup(conf *vault.CoreConfig, opts *vault.TestClusterOptions) {
opts.PhysicalFactory = SharedPhysicalFactory(MakeInmemBackend)
}
func InmemNonTransactionalBackendSetup(conf *vault.CoreConfig, opts *vault.TestClusterOptions) {
opts.PhysicalFactory = SharedPhysicalFactory(MakeInmemNonTransactionalBackend)
}
func FileBackendSetup(conf *vault.CoreConfig, opts *vault.TestClusterOptions) {
opts.PhysicalFactory = SharedPhysicalFactory(MakeFileBackend)
}
func ConsulBackendSetup(conf *vault.CoreConfig, opts *vault.TestClusterOptions) {
opts.PhysicalFactory = SharedPhysicalFactory(MakeConsulBackend)
}
func RaftBackendSetup(conf *vault.CoreConfig, opts *vault.TestClusterOptions) {
conf.DisablePerformanceStandby = true
opts.KeepStandbysSealed = true
opts.PhysicalFactory = MakeRaftBackend
opts.SetupFunc = func(t testing.T, c *vault.TestCluster) {
if opts.NumCores != 1 {
testhelpers.RaftClusterJoinNodes(t, c)
time.Sleep(15 * time.Second)
}
}
}
func ClusterSetup(conf *vault.CoreConfig, opts *vault.TestClusterOptions, setup ClusterSetupMutator) (*vault.CoreConfig, *vault.TestClusterOptions) {
var localConf vault.CoreConfig
if conf != nil {
localConf = *conf
}
localOpts := vault.TestClusterOptions{
HandlerFunc: vaulthttp.Handler,
}
if opts != nil {
localOpts = *opts
}
if setup == nil {
setup = InmemBackendSetup
}
setup(&localConf, &localOpts)
return &localConf, &localOpts
}