You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
boundary/testing/controller/controller.go

222 lines
5.9 KiB

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package controller
import (
"context"
"fmt"
"testing"
"github.com/hashicorp/boundary/internal/cmd/config"
"github.com/hashicorp/boundary/internal/daemon/controller"
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
_ "github.com/hashicorp/boundary/internal/daemon/controller/handlers/targets/tcp"
)
type option struct {
tcOptions *controller.TestControllerOpts
setWithConfigFile bool
setWithConfigText bool
setDisableAuthMethodCreation bool
setDisableDatabaseCreation bool
setDisableDatabaseDestruction bool
setDefaultPasswordAuthMethodId bool
setDefaultOidcAuthMethodId bool
setDefaultLoginName bool
setDefaultPassword bool
setRootKms bool
setWorkerAuthKms bool
setRecoveryKms bool
setDatabaseUrl bool
setEnableTemplatedDatabase bool
}
type Option func(*option) error
func getOpts(opt ...Option) (*controller.TestControllerOpts, error) {
opts := &option{
tcOptions: &controller.TestControllerOpts{},
}
for _, o := range opt {
if err := o(opts); err != nil {
return nil, err
}
}
opts.tcOptions.DisableDatabaseTemplate = !opts.setEnableTemplatedDatabase
if opts.setWithConfigFile && opts.setWithConfigText {
return nil, fmt.Errorf("Cannot provide both WithConfigFile and WithConfigText")
}
var setDbParams bool
if opts.setDefaultPasswordAuthMethodId ||
opts.setDefaultOidcAuthMethodId ||
opts.setDefaultLoginName ||
opts.setDefaultPassword {
setDbParams = true
}
if opts.setDisableAuthMethodCreation {
if setDbParams {
return nil, fmt.Errorf("Cannot both disable auth method creation and provide auth method parameters")
}
}
if opts.setDisableDatabaseCreation {
if setDbParams {
return nil, fmt.Errorf("Cannot both disable database creation and provide auth method parameters")
}
}
return opts.tcOptions, nil
}
// WithConfigFile provides the given ConfigFile to the built TestController.
// This option cannot be used if WithConfigText is used.
func WithConfigFile(f string) Option {
return func(c *option) error {
if c.setWithConfigFile {
return fmt.Errorf("WithConfigFile provided more than once.")
}
c.setWithConfigFile = true
cfg, err := config.Load(context.Background(), []string{f}, "")
if err != nil {
return err
}
c.tcOptions.Config = cfg
return nil
}
}
// WithConfigText configures the TestController sets up the Controller using the
// provided config text. This option cannot be used if WithConfigFile is used.
func WithConfigText(ct string) Option {
return func(c *option) error {
if c.setWithConfigText {
return fmt.Errorf("WithConfigText provided more than once.")
}
c.setWithConfigText = true
cfg, err := config.Parse(ct)
if err != nil {
return err
}
c.tcOptions.Config = cfg
return nil
}
}
// DisableAuthMethodCreation skips creating a default auth method
func DisableAuthMethodCreation() Option {
return func(c *option) error {
c.setDisableAuthMethodCreation = true
c.tcOptions.DisableAuthMethodCreation = true
return nil
}
}
// DisableDatabaseCreation skips creating a database in docker and allows one to
// be provided through a tcOptions.
func DisableDatabaseCreation() Option {
return func(c *option) error {
c.setDisableDatabaseCreation = true
c.tcOptions.DisableDatabaseCreation = true
return nil
}
}
// DisableDatabaseCreation skips creating a database in docker and allows one to
// be provided through a tcOptions.
func DisableDatabaseDestruction() Option {
return func(c *option) error {
c.setDisableDatabaseDestruction = true
c.tcOptions.DisableDatabaseDestruction = true
return nil
}
}
func WithDefaultPasswordAuthMethodId(id string) Option {
return func(c *option) error {
c.setDefaultPasswordAuthMethodId = true
c.tcOptions.DefaultPasswordAuthMethodId = id
return nil
}
}
func WithDefaultOidcAuthMethodId(id string) Option {
return func(c *option) error {
c.setDefaultOidcAuthMethodId = true
c.tcOptions.DefaultOidcAuthMethodId = id
return nil
}
}
func WithDefaultLoginName(ln string) Option {
return func(c *option) error {
c.setDefaultLoginName = true
c.tcOptions.DefaultLoginName = ln
return nil
}
}
func WithDefaultPassword(pw string) Option {
return func(c *option) error {
c.setDefaultPassword = true
c.tcOptions.DefaultPassword = pw
return nil
}
}
func WithRootKms(wrapper wrapping.Wrapper) Option {
return func(c *option) error {
c.setRootKms = true
c.tcOptions.RootKms = wrapper
return nil
}
}
func WithWorkerAuthKms(wrapper wrapping.Wrapper) Option {
return func(c *option) error {
c.setWorkerAuthKms = true
c.tcOptions.WorkerAuthKms = wrapper
return nil
}
}
func WithRecoveryKms(wrapper wrapping.Wrapper) Option {
return func(c *option) error {
c.setRecoveryKms = true
c.tcOptions.RecoveryKms = wrapper
return nil
}
}
func WithDatabaseUrl(url string) Option {
return func(c *option) error {
c.setDatabaseUrl = true
c.tcOptions.DatabaseUrl = url
return nil
}
}
// WithEnableTemplatedDatabase enables usage of a local database test instance
// with a template. Generally outside tests will probably want to use the
// non-templated database, so this defaults to enabling instead of disabling.
func WithEnableTemplatedDatabase(enable bool) Option {
return func(c *option) error {
c.setEnableTemplatedDatabase = enable
return nil
}
}
type TestController struct {
*controller.TestController
}
// NewTestController blocks until a new TestController is created, returns the url for the TestController and a function
// that can be called to tear down the controller after it has been used for testing.
func NewTestController(t *testing.T, opt ...Option) *TestController {
conf, err := getOpts(opt...)
if err != nil {
t.Fatalf("Couldn't create TestController: %v", err)
}
tc := controller.NewTestController(t, conf)
return &TestController{TestController: tc}
}