* feature (db): add Db.UnderlyingDB() This is needed to allow for integration with bits that need a *dbw.DB * feature (kms): add new go-kms-wrapping/extras/kms dependency * refactor (kms): schema changes required to adopt extras/kms pkg * refactor (kms/iam): rename to DeprecateCreateKeysTx(...) * refactor (kms): remove deprecated test * refactor (kms): refactor Kms type This refactor includes renaming the existing type to DeprecatedKms and then refactoring the Kms type to become a wrapper of go-kms-wrapping/extras/kms * refactor (kms): delete all the unneeded bits All this stuff is not needed now that we're using go-kms-wrapping/extras/kms * refactor (db): fixup tests after kms refactor * refactor (kms/tests): use testing.TB for test helpers Our test helper packages were not possible to use with benchmarks. This refactor switches to testing.TB to allow both tests and benchmarks to use the helpers. * tests (session benchmarks): refactor to use new Kms type * refactor (schema): rm test which relies on deprecated Kms code * refactor (kms): post rebase on main changes required * chore (kms refactor): re-add unit test from main * refactor (kms): uses migrations that don't include KMS schema changes
226 lines
5.6 KiB
Go
226 lines
5.6 KiB
Go
package controller
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/boundary/internal/cmd/base"
|
|
"github.com/hashicorp/boundary/internal/iam"
|
|
"github.com/hashicorp/boundary/internal/kms"
|
|
"github.com/hashicorp/boundary/internal/types/scope"
|
|
"github.com/hashicorp/go-secure-stdlib/listenerutil"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestController_New(t *testing.T) {
|
|
t.Run("ReconcileKeys", func(t *testing.T) {
|
|
assert, require := assert.New(t), require.New(t)
|
|
testCtx := context.Background()
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
tc := &TestController{
|
|
t: t,
|
|
ctx: ctx,
|
|
cancel: cancel,
|
|
opts: nil,
|
|
}
|
|
|
|
// TestControllerConfig(...) will create initial scopes
|
|
conf := TestControllerConfig(t, ctx, tc, nil)
|
|
org, _ := iam.TestScopes(t, iam.TestRepo(t, conf.Server.Database, conf.RootKms))
|
|
|
|
// this tests a scenario where there is an audit DEK
|
|
_, err := New(testCtx, conf)
|
|
require.NoError(err)
|
|
|
|
verifyFn := func() {
|
|
// verify audit DEKs
|
|
kmsCache := kms.TestKms(t, conf.Server.Database, conf.RootKms)
|
|
w, err := kmsCache.GetWrapper(testCtx, scope.Global.String(), kms.KeyPurposeAudit)
|
|
require.NoError(err)
|
|
assert.NotNil(w)
|
|
w, err = kmsCache.GetWrapper(testCtx, scope.Global.String(), kms.KeyPurposeOidc)
|
|
require.NoError(err)
|
|
assert.NotNil(w)
|
|
w, err = kmsCache.GetWrapper(testCtx, org.PublicId, kms.KeyPurposeOidc)
|
|
require.NoError(err)
|
|
assert.NotNil(w)
|
|
}
|
|
|
|
verifyFn()
|
|
|
|
// this tests a scenario where there is NOT an audit DEK
|
|
kms.TestKmsDeleteKeyPurpose(t, conf.Database, kms.KeyPurposeAudit)
|
|
kms.TestKmsDeleteKeyPurpose(t, conf.Database, kms.KeyPurposeOidc)
|
|
|
|
// re-init an empty cache and assert that the DEKs are not there.
|
|
kmsCache := kms.TestKms(t, conf.Server.Database, conf.RootKms)
|
|
w, err := kmsCache.GetWrapper(testCtx, scope.Global.String(), kms.KeyPurposeAudit)
|
|
require.Error(err)
|
|
assert.Nil(w)
|
|
w, err = kmsCache.GetWrapper(testCtx, scope.Global.String(), kms.KeyPurposeOidc)
|
|
require.Error(err)
|
|
assert.Nil(w)
|
|
w, err = kmsCache.GetWrapper(testCtx, org.PublicId, kms.KeyPurposeOidc)
|
|
require.Error(err)
|
|
assert.Nil(w)
|
|
|
|
// New(...) will reconcile the keys
|
|
_, err = New(testCtx, conf)
|
|
require.NoError(err)
|
|
|
|
// verify audit DEKs
|
|
verifyFn()
|
|
})
|
|
}
|
|
|
|
func TestControllerNewListenerConfig(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
listeners []*base.ServerListener
|
|
assertions func(t *testing.T, c *Controller)
|
|
expErr bool
|
|
expErrMsg string
|
|
}{
|
|
{
|
|
name: "valid listener configuration",
|
|
listeners: []*base.ServerListener{
|
|
{
|
|
Config: &listenerutil.ListenerConfig{
|
|
Purpose: []string{"api"},
|
|
},
|
|
},
|
|
{
|
|
Config: &listenerutil.ListenerConfig{
|
|
Purpose: []string{"api"},
|
|
},
|
|
},
|
|
{
|
|
Config: &listenerutil.ListenerConfig{
|
|
Purpose: []string{"cluster"},
|
|
},
|
|
},
|
|
},
|
|
assertions: func(t *testing.T, c *Controller) {
|
|
require.Len(t, c.apiListeners, 2)
|
|
require.NotNil(t, c.clusterListener)
|
|
},
|
|
},
|
|
{
|
|
name: "listeners are required",
|
|
listeners: []*base.ServerListener{},
|
|
expErr: true,
|
|
expErrMsg: "no api listeners found",
|
|
},
|
|
{
|
|
name: "listeners are required - not nil",
|
|
listeners: []*base.ServerListener{nil, nil},
|
|
expErr: true,
|
|
expErrMsg: "no api listeners found",
|
|
},
|
|
{
|
|
name: "listeners are required - with config",
|
|
listeners: []*base.ServerListener{{}, {}},
|
|
expErr: true,
|
|
expErrMsg: "no api listeners found",
|
|
},
|
|
{
|
|
name: "listeners are required - with purposes",
|
|
listeners: []*base.ServerListener{
|
|
{
|
|
Config: &listenerutil.ListenerConfig{Purpose: nil},
|
|
},
|
|
{
|
|
Config: &listenerutil.ListenerConfig{Purpose: nil},
|
|
},
|
|
},
|
|
expErr: true,
|
|
expErrMsg: "no api listeners found",
|
|
},
|
|
{
|
|
name: "both api and cluster listeners are required",
|
|
listeners: []*base.ServerListener{
|
|
{
|
|
Config: &listenerutil.ListenerConfig{
|
|
Purpose: []string{"api"},
|
|
},
|
|
},
|
|
},
|
|
expErr: true,
|
|
expErrMsg: "exactly one cluster listener is required",
|
|
},
|
|
{
|
|
name: "both api and cluster listeners are required 2",
|
|
listeners: []*base.ServerListener{
|
|
{
|
|
Config: &listenerutil.ListenerConfig{
|
|
Purpose: []string{"cluster"},
|
|
},
|
|
},
|
|
},
|
|
expErr: true,
|
|
expErrMsg: "no api listeners found",
|
|
},
|
|
{
|
|
name: "only one cluster listener is allowed",
|
|
listeners: []*base.ServerListener{
|
|
{
|
|
Config: &listenerutil.ListenerConfig{
|
|
Purpose: []string{"api"},
|
|
},
|
|
},
|
|
{
|
|
Config: &listenerutil.ListenerConfig{
|
|
Purpose: []string{"cluster"},
|
|
},
|
|
},
|
|
{
|
|
Config: &listenerutil.ListenerConfig{
|
|
Purpose: []string{"cluster"},
|
|
},
|
|
},
|
|
},
|
|
expErr: true,
|
|
expErrMsg: "exactly one cluster listener is required",
|
|
},
|
|
{
|
|
name: "only one purpose is allowed per listener",
|
|
listeners: []*base.ServerListener{
|
|
{
|
|
Config: &listenerutil.ListenerConfig{
|
|
Purpose: []string{"api", "cluster"},
|
|
},
|
|
},
|
|
},
|
|
expErr: true,
|
|
expErrMsg: `found listener with multiple purposes "api,cluster"`,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
tc := &TestController{
|
|
t: t,
|
|
ctx: ctx,
|
|
cancel: cancel,
|
|
opts: nil,
|
|
}
|
|
conf := TestControllerConfig(t, ctx, tc, nil)
|
|
conf.Listeners = tt.listeners
|
|
|
|
c, err := New(ctx, conf)
|
|
if tt.expErr {
|
|
require.EqualError(t, err, tt.expErrMsg)
|
|
require.Nil(t, c)
|
|
return
|
|
}
|
|
|
|
require.NoError(t, err)
|
|
require.NotNil(t, c)
|
|
tt.assertions(t, c)
|
|
})
|
|
}
|
|
}
|