mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-30 18:17:55 +00:00
Remove the Seal HA beta feature flag (#23820)
This commit is contained in:
@@ -436,7 +436,7 @@ func (c *OperatorDiagnoseCommand) offlineDiagnostics(ctx context.Context) error
|
||||
var setSealResponse *SetSealResponse
|
||||
existingSealGenerationInfo, err := vault.PhysicalSealGenInfo(sealcontext, *backend)
|
||||
if err != nil {
|
||||
diagnose.Fail(sealcontext, fmt.Sprintf("Unable to get Seal genration information from storage: %s.", err.Error()))
|
||||
diagnose.Fail(sealcontext, fmt.Sprintf("Unable to get Seal generation information from storage: %s.", err.Error()))
|
||||
goto SEALFAIL
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/command/server"
|
||||
|
||||
"github.com/hashicorp/vault/vault/diagnose"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
@@ -172,6 +174,138 @@ func TestOperatorDiagnoseCommand_Run(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"diagnose_ok_multiseal",
|
||||
[]string{
|
||||
"-config", "./server/test-fixtures/config_diagnose_ok.hcl",
|
||||
},
|
||||
[]*diagnose.Result{
|
||||
{
|
||||
Name: "Parse Configuration",
|
||||
Status: diagnose.OkStatus,
|
||||
},
|
||||
{
|
||||
Name: "Start Listeners",
|
||||
Status: diagnose.WarningStatus,
|
||||
Children: []*diagnose.Result{
|
||||
{
|
||||
Name: "Create Listeners",
|
||||
Status: diagnose.OkStatus,
|
||||
},
|
||||
{
|
||||
Name: "Check Listener TLS",
|
||||
Status: diagnose.WarningStatus,
|
||||
Warnings: []string{
|
||||
"TLS is disabled in a listener config stanza.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Check Storage",
|
||||
Status: diagnose.OkStatus,
|
||||
Children: []*diagnose.Result{
|
||||
{
|
||||
Name: "Create Storage Backend",
|
||||
Status: diagnose.OkStatus,
|
||||
},
|
||||
{
|
||||
Name: "Check Consul TLS",
|
||||
Status: diagnose.SkippedStatus,
|
||||
},
|
||||
{
|
||||
Name: "Check Consul Direct Storage Access",
|
||||
Status: diagnose.OkStatus,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Check Service Discovery",
|
||||
Status: diagnose.OkStatus,
|
||||
Children: []*diagnose.Result{
|
||||
{
|
||||
Name: "Check Consul Service Discovery TLS",
|
||||
Status: diagnose.SkippedStatus,
|
||||
},
|
||||
{
|
||||
Name: "Check Consul Direct Service Discovery",
|
||||
Status: diagnose.OkStatus,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Create Vault Server Configuration Seals",
|
||||
// We can't load from storage the existing seal generation info during the test, so we expect an error.
|
||||
Status: diagnose.ErrorStatus,
|
||||
},
|
||||
{
|
||||
Name: "Create Core Configuration",
|
||||
Status: diagnose.OkStatus,
|
||||
Children: []*diagnose.Result{
|
||||
{
|
||||
Name: "Initialize Randomness for Core",
|
||||
Status: diagnose.OkStatus,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "HA Storage",
|
||||
Status: diagnose.OkStatus,
|
||||
Children: []*diagnose.Result{
|
||||
{
|
||||
Name: "Create HA Storage Backend",
|
||||
Status: diagnose.OkStatus,
|
||||
},
|
||||
{
|
||||
Name: "Check HA Consul Direct Storage Access",
|
||||
Status: diagnose.OkStatus,
|
||||
},
|
||||
{
|
||||
Name: "Check Consul TLS",
|
||||
Status: diagnose.SkippedStatus,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Determine Redirect Address",
|
||||
Status: diagnose.OkStatus,
|
||||
},
|
||||
{
|
||||
Name: "Check Cluster Address",
|
||||
Status: diagnose.OkStatus,
|
||||
},
|
||||
{
|
||||
Name: "Check Core Creation",
|
||||
Status: diagnose.OkStatus,
|
||||
},
|
||||
{
|
||||
Name: "Start Listeners",
|
||||
Status: diagnose.WarningStatus,
|
||||
Children: []*diagnose.Result{
|
||||
{
|
||||
Name: "Create Listeners",
|
||||
Status: diagnose.OkStatus,
|
||||
},
|
||||
{
|
||||
Name: "Check Listener TLS",
|
||||
Status: diagnose.WarningStatus,
|
||||
Warnings: []string{
|
||||
"TLS is disabled in a listener config stanza.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Check Autounseal Encryption",
|
||||
Status: diagnose.ErrorStatus,
|
||||
Message: "Diagnose could not create a barrier seal object.",
|
||||
},
|
||||
{
|
||||
Name: "Check Server Before Runtime",
|
||||
Status: diagnose.OkStatus,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"diagnose_raft_problems",
|
||||
[]string{
|
||||
@@ -478,17 +612,23 @@ func TestOperatorDiagnoseCommand_Run(t *testing.T) {
|
||||
for _, tc := range cases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
cmd := testOperatorDiagnoseCommand(t)
|
||||
cmd.client = client
|
||||
if tc.name == "diagnose_ok" && server.IsMultisealSupported() {
|
||||
t.Skip("Test not valid in ENT")
|
||||
} else if tc.name == "diagnose_ok_multiseal" && !server.IsMultisealSupported() {
|
||||
t.Skip("Test not valid in community edition")
|
||||
} else {
|
||||
t.Parallel()
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
cmd := testOperatorDiagnoseCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
cmd.Run(tc.args)
|
||||
result := cmd.diagnose.Finalize(context.Background())
|
||||
cmd.Run(tc.args)
|
||||
result := cmd.diagnose.Finalize(context.Background())
|
||||
|
||||
if err := compareResults(tc.expected, result.Children); err != nil {
|
||||
t.Fatalf("Did not find expected test results: %v", err)
|
||||
if err := compareResults(tc.expected, result.Children); err != nil {
|
||||
t.Fatalf("Did not find expected test results: %v", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2626,11 +2626,6 @@ func setSeal(c *ServerCommand, config *server.Config, infoKeys []string, info ma
|
||||
}
|
||||
sealWrapperInfoKeysMap := make(map[string]infoKeysAndMap)
|
||||
|
||||
sealHaBetaEnabled, err := server.IsSealHABetaEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
configuredSeals := 0
|
||||
for _, configSeal := range config.Seals {
|
||||
sealTypeEnvVarName := "VAULT_SEAL_TYPE"
|
||||
@@ -2655,20 +2650,18 @@ func setSeal(c *ServerCommand, config *server.Config, infoKeys []string, info ma
|
||||
wrapper = aeadwrapper.NewShamirWrapper()
|
||||
}
|
||||
configuredSeals++
|
||||
} else if server.IsMultisealSupported() {
|
||||
recordSealConfigWarning(fmt.Errorf("error configuring seal: %v", wrapperConfigError))
|
||||
} else {
|
||||
if sealHaBetaEnabled {
|
||||
recordSealConfigWarning(fmt.Errorf("error configuring seal: %v", wrapperConfigError))
|
||||
// It seems that we are checking for this particular error here is to distinguish between a
|
||||
// mis-configured seal vs one that fails for another reason. Apparently the only other reason is
|
||||
// a key not found error. It seems the intention is for the key not found error to be returned
|
||||
// as a seal specific error later
|
||||
if !errwrap.ContainsType(wrapperConfigError, new(logical.KeyNotFoundError)) {
|
||||
return nil, fmt.Errorf("error parsing Seal configuration: %s", wrapperConfigError)
|
||||
} else {
|
||||
// It seems that we are checking for this particular error here is to distinguish between a
|
||||
// mis-configured seal vs one that fails for another reason. Apparently the only other reason is
|
||||
// a key not found error. It seems the intention is for the key not found error to be returned
|
||||
// as a seal specific error later
|
||||
if !errwrap.ContainsType(wrapperConfigError, new(logical.KeyNotFoundError)) {
|
||||
return nil, fmt.Errorf("error parsing Seal configuration: %s", wrapperConfigError)
|
||||
} else {
|
||||
sealLogger.Error("error configuring seal", "name", configSeal.Name, "err", wrapperConfigError)
|
||||
recordSealConfigError(wrapperConfigError)
|
||||
}
|
||||
sealLogger.Error("error configuring seal", "name", configSeal.Name, "err", wrapperConfigError)
|
||||
recordSealConfigError(wrapperConfigError)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2725,7 +2718,7 @@ func setSeal(c *ServerCommand, config *server.Config, infoKeys []string, info ma
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compute seal generation
|
||||
sealGenerationInfo, err := c.computeSealGenerationInfo(existingSealGenerationInfo, allSealKmsConfigs, hasPartiallyWrappedPaths, sealHaBetaEnabled)
|
||||
sealGenerationInfo, err := c.computeSealGenerationInfo(existingSealGenerationInfo, allSealKmsConfigs, hasPartiallyWrappedPaths)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -2767,8 +2760,8 @@ func setSeal(c *ServerCommand, config *server.Config, infoKeys []string, info ma
|
||||
barrierSeal = vault.NewAutoSeal(vaultseal.NewAccess(sealLogger, sealGenerationInfo, enabledSealWrappers))
|
||||
unwrapSeal = vault.NewDefaultSeal(vaultseal.NewAccess(sealLogger, sealGenerationInfo, disabledSealWrappers))
|
||||
|
||||
case sealHaBetaEnabled:
|
||||
// We know we are not using Shamir seal, that we are not migrating away from one, and seal HA is enabled,
|
||||
case server.IsMultisealSupported():
|
||||
// We know we are not using Shamir seal, that we are not migrating away from one, and multi seal is supported,
|
||||
// so just put enabled and disabled wrappers on the same seal Access
|
||||
allSealWrappers := append(enabledSealWrappers, disabledSealWrappers...)
|
||||
barrierSeal = vault.NewAutoSeal(vaultseal.NewAccess(sealLogger, sealGenerationInfo, allSealWrappers))
|
||||
@@ -2783,7 +2776,7 @@ func setSeal(c *ServerCommand, config *server.Config, infoKeys []string, info ma
|
||||
}
|
||||
|
||||
default:
|
||||
// We know there are multiple enabled seals and that the seal HA beta is not enabled
|
||||
// We know there are multiple enabled seals but multi seal is not supported.
|
||||
return nil, errors.Join(sealConfigWarning, errors.New("error: more than one enabled seal found"))
|
||||
}
|
||||
|
||||
@@ -2795,7 +2788,7 @@ func setSeal(c *ServerCommand, config *server.Config, infoKeys []string, info ma
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *ServerCommand) computeSealGenerationInfo(existingSealGenInfo *vaultseal.SealGenerationInfo, sealConfigs []*configutil.KMS, hasPartiallyWrappedPaths bool, sealHaBetaEnabled bool) (*vaultseal.SealGenerationInfo, error) {
|
||||
func (c *ServerCommand) computeSealGenerationInfo(existingSealGenInfo *vaultseal.SealGenerationInfo, sealConfigs []*configutil.KMS, hasPartiallyWrappedPaths bool) (*vaultseal.SealGenerationInfo, error) {
|
||||
generation := uint64(1)
|
||||
|
||||
if existingSealGenInfo != nil {
|
||||
@@ -2817,7 +2810,7 @@ func (c *ServerCommand) computeSealGenerationInfo(existingSealGenInfo *vaultseal
|
||||
Seals: sealConfigs,
|
||||
}
|
||||
|
||||
if sealHaBetaEnabled {
|
||||
if server.IsMultisealSupported() {
|
||||
err := newSealGenInfo.Validate(existingSealGenInfo, hasPartiallyWrappedPaths)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -7,6 +7,6 @@ package server
|
||||
|
||||
//go:generate go run github.com/hashicorp/vault/tools/stubmaker
|
||||
|
||||
func IsSealHABetaEnabled() (bool, error) {
|
||||
return false, nil
|
||||
func IsMultisealSupported() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1,909 +0,0 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package command
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/helper/testhelpers/corehelpers"
|
||||
|
||||
"github.com/hashicorp/vault/vault/seal"
|
||||
|
||||
"github.com/hashicorp/vault/internalshared/configutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if signed := os.Getenv("VAULT_LICENSE_CI"); signed != "" {
|
||||
os.Setenv(EnvVaultLicense, signed)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiSealCases(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
existingSealGenInfo *seal.SealGenerationInfo
|
||||
allSealKmsConfigs []*configutil.KMS
|
||||
expectedSealGenInfo *seal.SealGenerationInfo
|
||||
isRewrapped bool
|
||||
hasPartiallyWrappedPaths bool
|
||||
sealHaBetaEnabled bool
|
||||
isErrorExpected bool
|
||||
expectedErrorMsg string
|
||||
}{
|
||||
// none_to_shamir
|
||||
{
|
||||
name: "none_to_shamir",
|
||||
existingSealGenInfo: nil,
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "shamir",
|
||||
Name: "shamirSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
expectedSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "shamir",
|
||||
Name: "shamirSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
sealHaBetaEnabled: true,
|
||||
},
|
||||
// none_to_auto
|
||||
{
|
||||
name: "none_to_auto",
|
||||
existingSealGenInfo: nil,
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
expectedSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
sealHaBetaEnabled: true,
|
||||
},
|
||||
// none_to_multi
|
||||
{
|
||||
name: "none_to_multi",
|
||||
existingSealGenInfo: nil,
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
isErrorExpected: true,
|
||||
expectedErrorMsg: "Initializing a cluster or enabling multi-seal on an existing cluster must occur with a single seal before adding additional seals",
|
||||
sealHaBetaEnabled: true,
|
||||
},
|
||||
// none_to_multi_with_disabled_seals_with_beta
|
||||
{
|
||||
name: "none_to_multi_with_disabled_seals_with_beta",
|
||||
existingSealGenInfo: nil,
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
Disabled: true,
|
||||
},
|
||||
},
|
||||
isErrorExpected: true,
|
||||
expectedErrorMsg: "Initializing a cluster or enabling multi-seal on an existing cluster must occur with a single seal before adding additional seals",
|
||||
sealHaBetaEnabled: true,
|
||||
},
|
||||
// none_to_multi_with_disabled_seals_no_beta
|
||||
{
|
||||
name: "none_to_multi_with_disabled_seals_no_beta",
|
||||
existingSealGenInfo: nil,
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
Disabled: true,
|
||||
},
|
||||
},
|
||||
isErrorExpected: false,
|
||||
sealHaBetaEnabled: false,
|
||||
expectedSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
Disabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// shamir_to_auto
|
||||
{
|
||||
name: "shamir_to_auto",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 2,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "shamir",
|
||||
Name: "shamirSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
expectedSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 3,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: false,
|
||||
sealHaBetaEnabled: true,
|
||||
},
|
||||
// shamir_to_multi
|
||||
{
|
||||
name: "shamir_to_multi",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "shamir",
|
||||
Name: "shamirSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 2,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 3,
|
||||
},
|
||||
},
|
||||
isRewrapped: false,
|
||||
sealHaBetaEnabled: true,
|
||||
isErrorExpected: true,
|
||||
expectedErrorMsg: "cannot add more than one seal",
|
||||
},
|
||||
// auto_to_shamir_no_common_seal
|
||||
{
|
||||
name: "auto_to_shamir_no_common_seal",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "shamir",
|
||||
Name: "shamirSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
sealHaBetaEnabled: true,
|
||||
isErrorExpected: true,
|
||||
expectedErrorMsg: "must have at least one seal in common with the old generation",
|
||||
},
|
||||
// auto_to_shamir_with_common_seal
|
||||
{
|
||||
name: "auto_to_shamir_with_common_seal",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "shamir",
|
||||
Name: "shamirSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
Disabled: true,
|
||||
},
|
||||
},
|
||||
expectedSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 2,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "shamir",
|
||||
Name: "shamirSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
Disabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
sealHaBetaEnabled: true,
|
||||
},
|
||||
// auto_to_auto_no_common_seal
|
||||
{
|
||||
name: "auto_to_auto_no_common_seal",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
sealHaBetaEnabled: true,
|
||||
isErrorExpected: true,
|
||||
expectedErrorMsg: "must have at least one seal in common with the old generation",
|
||||
},
|
||||
// auto_to_auto_with_common_seal
|
||||
{
|
||||
name: "auto_to_auto_with_common_seal",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
Disabled: true,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
expectedSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 2,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
Disabled: true,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
sealHaBetaEnabled: true,
|
||||
},
|
||||
// auto_to_multi_add_one
|
||||
{
|
||||
name: "auto_to_multi_add_one",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
expectedSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 2,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
sealHaBetaEnabled: true,
|
||||
},
|
||||
// auto_to_multi_add_two
|
||||
{
|
||||
name: "auto_to_multi_add_two",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal3",
|
||||
Priority: 3,
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
sealHaBetaEnabled: true,
|
||||
isErrorExpected: true,
|
||||
expectedErrorMsg: "cannot add more than one seal",
|
||||
},
|
||||
// multi_to_auto_delete_one
|
||||
{
|
||||
name: "multi_to_auto_delete_one",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
expectedSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 2,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
sealHaBetaEnabled: true,
|
||||
},
|
||||
// multi_to_auto_delete_two
|
||||
{
|
||||
name: "multi_to_auto_delete_two",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal3",
|
||||
Priority: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
sealHaBetaEnabled: true,
|
||||
isErrorExpected: true,
|
||||
expectedErrorMsg: "cannot delete more than one seal",
|
||||
},
|
||||
// disable_two_auto
|
||||
{
|
||||
name: "disable_two_auto",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal3",
|
||||
Priority: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
allSealKmsConfigs: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
Disabled: true,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal3",
|
||||
Priority: 3,
|
||||
Disabled: true,
|
||||
},
|
||||
},
|
||||
expectedSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 2,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
Disabled: true,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal3",
|
||||
Priority: 3,
|
||||
Disabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
sealHaBetaEnabled: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
cmd := &ServerCommand{}
|
||||
cmd.logger = corehelpers.NewTestLogger(t)
|
||||
if tc.existingSealGenInfo != nil {
|
||||
tc.existingSealGenInfo.SetRewrapped(tc.isRewrapped)
|
||||
}
|
||||
sealGenInfo, err := cmd.computeSealGenerationInfo(tc.existingSealGenInfo, tc.allSealKmsConfigs, tc.hasPartiallyWrappedPaths, tc.sealHaBetaEnabled)
|
||||
switch {
|
||||
case tc.isErrorExpected:
|
||||
require.Error(t, err)
|
||||
require.ErrorContains(t, err, tc.expectedErrorMsg)
|
||||
require.Nil(t, sealGenInfo)
|
||||
default:
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tc.expectedSealGenInfo, sealGenInfo)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
cases2 := []struct {
|
||||
name string
|
||||
existingSealGenInfo *seal.SealGenerationInfo
|
||||
newSealGenInfo *seal.SealGenerationInfo
|
||||
isRewrapped bool
|
||||
hasPartiallyWrappedPaths bool
|
||||
isErrorExpected bool
|
||||
expectedErrorMsg string
|
||||
}{
|
||||
// same_generation_different_seals
|
||||
{
|
||||
name: "same_generation_different_seals",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
newSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal3",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
isErrorExpected: true,
|
||||
expectedErrorMsg: "existing seal generation is the same, but the configured seals are different",
|
||||
},
|
||||
|
||||
// same_generation_same_seals
|
||||
{
|
||||
name: "same_generation_same_seals",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
newSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
isErrorExpected: false,
|
||||
},
|
||||
// existing seal gen info rewrapped is set to false
|
||||
{
|
||||
name: "existing_sgi_rewrapped_false",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 2,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
newSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: false,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
isErrorExpected: true,
|
||||
expectedErrorMsg: "cannot make seal config changes while seal re-wrap is in progress, please revert any seal configuration changes",
|
||||
},
|
||||
// single seal migration use-case
|
||||
{
|
||||
name: "single_seal_migration",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 2,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "transit",
|
||||
Name: "transit",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
newSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "transit",
|
||||
Name: "transit-disabled",
|
||||
Priority: 1,
|
||||
Disabled: true,
|
||||
},
|
||||
{
|
||||
Type: "shamir",
|
||||
Name: "shamir",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
isErrorExpected: false,
|
||||
},
|
||||
// migrate from non-beta single seal to single seal
|
||||
{
|
||||
name: "none_to_single_seal",
|
||||
existingSealGenInfo: nil,
|
||||
newSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "shamir",
|
||||
Name: "shamir",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
isErrorExpected: false,
|
||||
},
|
||||
// migrate from non-beta single seal to multi seal, with one disabled, so perform an old style migration
|
||||
// we do not support this use-case at this time so trap the error
|
||||
{
|
||||
name: "none_to_multiple_seals_one_disabled",
|
||||
existingSealGenInfo: nil,
|
||||
newSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal",
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal",
|
||||
Disabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
isErrorExpected: true,
|
||||
expectedErrorMsg: "Initializing a cluster or enabling multi-seal on an existing cluster must occur with a single seal before adding additional seals",
|
||||
},
|
||||
// migrate from non-beta single seal to multi seal
|
||||
{
|
||||
name: "none_to_multiple_seals",
|
||||
existingSealGenInfo: nil,
|
||||
newSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
isErrorExpected: true,
|
||||
expectedErrorMsg: "Initializing a cluster or enabling multi-seal on an existing cluster must occur with a single seal before adding additional seals",
|
||||
},
|
||||
// have partially wrapped paths
|
||||
{
|
||||
name: "have_partially_wrapped_paths",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 2,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
newSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: true,
|
||||
isErrorExpected: true,
|
||||
expectedErrorMsg: "cannot make seal config changes while seal re-wrap is in progress, please revert any seal configuration changes",
|
||||
},
|
||||
// no partially wrapped paths
|
||||
{
|
||||
name: "no_partially_wrapped_paths",
|
||||
existingSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 2,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal2",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
newSealGenInfo: &seal.SealGenerationInfo{
|
||||
Generation: 1,
|
||||
Seals: []*configutil.KMS{
|
||||
{
|
||||
Type: "pkcs11",
|
||||
Name: "autoSeal1",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
isRewrapped: true,
|
||||
hasPartiallyWrappedPaths: false,
|
||||
isErrorExpected: false,
|
||||
},
|
||||
}
|
||||
for _, tc := range cases2 {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if tc.existingSealGenInfo != nil {
|
||||
tc.existingSealGenInfo.SetRewrapped(tc.isRewrapped)
|
||||
}
|
||||
err := tc.newSealGenInfo.Validate(tc.existingSealGenInfo, tc.hasPartiallyWrappedPaths)
|
||||
switch {
|
||||
case tc.isErrorExpected:
|
||||
require.Error(t, err)
|
||||
require.ErrorContains(t, err, tc.expectedErrorMsg)
|
||||
default:
|
||||
require.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -2454,13 +2454,9 @@ func (s standardUnsealStrategy) unseal(ctx context.Context, logger log.Logger, c
|
||||
return err
|
||||
}
|
||||
|
||||
sealHaEnabled, err := server.IsSealHABetaEnabled()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sealHaEnabled && !sealGenerationInfo.IsRewrapped() {
|
||||
// Flag migration performed for seal-rewrap later
|
||||
// Note that in the case where seal HA is not enabled, Core.migrateSeal() takes care of
|
||||
if server.IsMultisealSupported() && !sealGenerationInfo.IsRewrapped() {
|
||||
// Set the migration done flag so that a seal-rewrap gets triggered later.
|
||||
// Note that in the case where multi seal is not supported, Core.migrateSeal() takes care of
|
||||
// triggering the rewrap when necessary.
|
||||
c.logger.Trace("seal generation information indicates that a seal-rewrap is needed", "generation", sealGenerationInfo.Generation, "rewrapped", sealGenerationInfo.IsRewrapped())
|
||||
atomic.StoreUint32(c.sealMigrationDone, 1)
|
||||
@@ -2880,23 +2876,17 @@ func (c *Core) adjustForSealMigration(unwrapSeal Seal) error {
|
||||
return err
|
||||
}
|
||||
unwrapSeal = NewDefaultSeal(sealAccess)
|
||||
case configuredType == SealConfigTypeMultiseal && server.IsMultisealSupported():
|
||||
// We are going from a single non-shamir seal to multiseal, and multi seal is supported.
|
||||
// This scenario is not considered a migration in the sense of requiring an unwrapSeal,
|
||||
// but we will update the stored SealConfig later (see Core.migrateMultiSealConfig).
|
||||
|
||||
return nil
|
||||
case configuredType == SealConfigTypeMultiseal:
|
||||
// The configured seal is multiseal and we know the stored type is not shamir, thus
|
||||
// we are going from auto seal to multiseal.
|
||||
betaEnabled, err := server.IsSealHABetaEnabled()
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case !betaEnabled:
|
||||
return fmt.Errorf("cannot seal migrate from %q to %q, Seal High Availability beta is not enabled",
|
||||
existBarrierSealConfig.Type, c.seal.BarrierSealConfigType())
|
||||
default:
|
||||
// We are going from a single non-shamir seal to multiseal, and the seal HA beta is enabled.
|
||||
// This scenario is not considered a migration in the sense of requiring an unwrapSeal,
|
||||
// but we will update the stored SealConfig later (see Core.migrateMultiSealConfig).
|
||||
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("cannot seal migrate from %q to %q, multiple seals are not supported",
|
||||
existBarrierSealConfig.Type, c.seal.BarrierSealConfigType())
|
||||
case storedType == SealConfigTypeMultiseal:
|
||||
// The stored type is multiseal and we know the type the configured type is not shamir,
|
||||
// thus we are going from multiseal to autoseal.
|
||||
|
||||
@@ -342,9 +342,7 @@ func readStoredKeys(ctx context.Context, storage physical.Backend, encryptor sea
|
||||
}
|
||||
|
||||
func (c *Core) SetPhysicalSealGenInfo(ctx context.Context, sealGenInfo *seal.SealGenerationInfo) error {
|
||||
if enabled, err := server.IsSealHABetaEnabled(); err != nil {
|
||||
return err
|
||||
} else if !enabled {
|
||||
if !server.IsMultisealSupported() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -372,9 +370,7 @@ func (c *Core) SetPhysicalSealGenInfo(ctx context.Context, sealGenInfo *seal.Sea
|
||||
}
|
||||
|
||||
func PhysicalSealGenInfo(ctx context.Context, storage physical.Backend) (*seal.SealGenerationInfo, error) {
|
||||
if enabled, err := server.IsSealHABetaEnabled(); err != nil {
|
||||
return nil, err
|
||||
} else if !enabled {
|
||||
if !server.IsMultisealSupported() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user