Add ability to skip automatic auth method creation (#306)
This is useful if you, for instance, want Terraform to be 100% responsible for creation of resources (outside of the static ones that cannot be removed or modified, like u_anon). This will mean using the recovery mechanism for initial setup, but that isn't an issue once TF supports that :-)
This commit is contained in:
1 parent
490be8a7e4
commit
b53812a5c1
6 files changed
+111
-56
No files matched your search
@@ -14,8 +14,9 @@ type Option func(*Options)
|
||||
|
||||
// Options - how Options are represented.
|
||||
type Options struct {
|
||||
withNoTokenScope bool
|
||||
withNoTokenValue bool
|
||||
withNoTokenScope bool
|
||||
withNoTokenValue bool
|
||||
withSkipAuthMethodCreation bool
|
||||
}
|
||||
|
||||
func getDefaultOptions() Options {
|
||||
@@ -39,3 +40,11 @@ func WithNoTokenValue() Option {
|
||||
o.withNoTokenValue = true
|
||||
}
|
||||
}
|
||||
|
||||
// WithSkipAuthMethodCreation tells the command not to instantiate an auth
|
||||
// method on first run.
|
||||
func WithSkipAuthMethodCreation() Option {
|
||||
return func(o *Options) {
|
||||
o.withSkipAuthMethodCreation = true
|
||||
}
|
||||
}
|
||||
@@ -421,7 +421,9 @@ func (b *Server) ConnectToDatabase(dialect string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Server) CreateDevDatabase(dialect string) error {
|
||||
func (b *Server) CreateDevDatabase(dialect string, opt ...Option) error {
|
||||
opts := getOpts(opt...)
|
||||
|
||||
c, url, container, err := db.InitDbInDocker(dialect)
|
||||
// In case of an error, run the cleanup function. If we pass all errors, c should be set to a noop
|
||||
// function before returning from this method
|
||||
@@ -467,11 +469,6 @@ func (b *Server) CreateDevDatabase(dialect string) error {
|
||||
return fmt.Errorf("error adding config keys to kms: %w", err)
|
||||
}
|
||||
|
||||
repo, err := iam.NewRepository(rw, rw, kmsCache, iam.WithRandomReader(b.SecureRandomReader))
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create repo for org id: %w", err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
<-b.ShutdownCh
|
||||
@@ -487,6 +484,13 @@ func (b *Server) CreateDevDatabase(dialect string) error {
|
||||
return fmt.Errorf("error saving global scope root key: %w", err)
|
||||
}
|
||||
|
||||
if opts.withSkipAuthMethodCreation {
|
||||
// now that we have passed all the error cases, reset c to be a noop so the
|
||||
// defer doesn't do anything.
|
||||
c = func() error { return nil }
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create the dev auth method
|
||||
pwRepo, err := password.NewRepository(rw, rw, kmsCache)
|
||||
if err != nil {
|
||||
@@ -504,6 +508,8 @@ func (b *Server) CreateDevDatabase(dialect string) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("error saving auth method to the db: %w", err)
|
||||
}
|
||||
b.InfoKeys = append(b.InfoKeys, "dev auth method id")
|
||||
b.Info["dev auth method id"] = amId
|
||||
|
||||
// Create the dev user
|
||||
acctLoginName := b.DevLoginName
|
||||
@@ -521,6 +527,9 @@ func (b *Server) CreateDevDatabase(dialect string) error {
|
||||
return fmt.Errorf("unable to generate dev password: %w", err)
|
||||
}
|
||||
}
|
||||
b.InfoKeys = append(b.InfoKeys, "dev password")
|
||||
b.Info["dev password"] = pw
|
||||
|
||||
acct, err := password.NewAccount(amId, password.WithLoginName(acctLoginName))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating new in memory auth account: %w", err)
|
||||
@@ -529,30 +538,31 @@ func (b *Server) CreateDevDatabase(dialect string) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("error saving auth account to the db: %w", err)
|
||||
}
|
||||
b.InfoKeys = append(b.InfoKeys, "dev login name")
|
||||
b.Info["dev login name"] = acct.GetLoginName()
|
||||
|
||||
// Create a role tying them together
|
||||
iamRepo, err := iam.NewRepository(rw, rw, kmsCache, iam.WithRandomReader(b.SecureRandomReader))
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create repo for org id: %w", err)
|
||||
}
|
||||
pr, err := iam.NewRole(scope.Global.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating in memory role for default dev grants: %w", err)
|
||||
}
|
||||
pr.Name = "Dev Mode Global Scope Admin Role"
|
||||
pr.Description = `Provides admin grants to all authenticated users within the "global" scope`
|
||||
defPermsRole, err := repo.CreateRole(ctx, pr)
|
||||
defPermsRole, err := iamRepo.CreateRole(ctx, pr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating role for default dev grants: %w", err)
|
||||
}
|
||||
if _, err := repo.AddRoleGrants(ctx, defPermsRole.PublicId, defPermsRole.Version, []string{"id=*;actions=*"}); err != nil {
|
||||
if _, err := iamRepo.AddRoleGrants(ctx, defPermsRole.PublicId, defPermsRole.Version, []string{"id=*;actions=*"}); err != nil {
|
||||
return fmt.Errorf("error creating grant for default dev grants: %w", err)
|
||||
}
|
||||
if _, err := repo.AddPrincipalRoles(ctx, defPermsRole.PublicId, defPermsRole.Version+1, []string{"u_auth"}, nil); err != nil {
|
||||
if _, err := iamRepo.AddPrincipalRoles(ctx, defPermsRole.PublicId, defPermsRole.Version+1, []string{"u_auth"}, nil); err != nil {
|
||||
return fmt.Errorf("error adding principal to role for default dev grants: %w", err)
|
||||
}
|
||||
|
||||
b.InfoKeys = append(b.InfoKeys, "dev auth method id", "dev login name", "dev password")
|
||||
b.Info["dev auth method id"] = amId
|
||||
b.Info["dev login name"] = acct.GetLoginName()
|
||||
b.Info["dev password"] = pw
|
||||
|
||||
// now that we have passed all the error cases, reset c to be a noop so the
|
||||
// defer doesn't do anything.
|
||||
c = func() error { return nil }
|
||||
|
||||
@@ -44,8 +44,8 @@ type Command struct {
|
||||
flagDevPassword string
|
||||
flagDevControllerAPIListenAddr string
|
||||
flagDevControllerClusterListenAddr string
|
||||
flagDevOrgId string
|
||||
flagDevAuthMethodId string
|
||||
flagDevSkipAuthMethodCreation bool
|
||||
}
|
||||
|
||||
func (c *Command) Synopsis() string {
|
||||
@@ -108,14 +108,6 @@ func (c *Command) Flags() *base.FlagSets {
|
||||
"production.",
|
||||
})
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "dev-org-id",
|
||||
Target: &c.flagDevOrgId,
|
||||
EnvVar: "WATCHTWER_DEV_ORG_ID",
|
||||
Usage: "Auto-created org ID. This only applies when running in \"dev\" " +
|
||||
"mode.",
|
||||
})
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "dev-auth-method-id",
|
||||
Target: &c.flagDevAuthMethodId,
|
||||
@@ -124,6 +116,12 @@ func (c *Command) Flags() *base.FlagSets {
|
||||
"mode.",
|
||||
})
|
||||
|
||||
f.BoolVar(&base.BoolVar{
|
||||
Name: "dev-skip-auth-method-creation",
|
||||
Target: &c.flagDevSkipAuthMethodCreation,
|
||||
Usage: "If set, an auth method will not be created as part of the dev instance. The recovery KMS will be needed to perform any actions.",
|
||||
})
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "dev-password",
|
||||
Target: &c.flagDevPassword,
|
||||
@@ -275,7 +273,17 @@ func (c *Command) Run(args []string) int {
|
||||
}
|
||||
|
||||
if c.flagDev {
|
||||
if err := c.CreateDevDatabase("postgres"); err != nil {
|
||||
var opts []base.Option
|
||||
if c.flagDevSkipAuthMethodCreation {
|
||||
opts = append(opts, base.WithSkipAuthMethodCreation())
|
||||
switch {
|
||||
case c.flagDevAuthMethodId != "",
|
||||
c.flagDevLoginName != "",
|
||||
c.flagDevPassword != "":
|
||||
c.UI.Warn("-dev-skip-auth-method-creation set, skipping any auth-method related flags")
|
||||
}
|
||||
}
|
||||
if err := c.CreateDevDatabase("postgres", opts...); err != nil {
|
||||
c.UI.Error(fmt.Errorf("Error creating dev database container: %s", err.Error()).Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -31,10 +31,10 @@ type Command struct {
|
||||
flagCombineLogs bool
|
||||
flagDevLoginName string
|
||||
flagDevPassword string
|
||||
flagDevOrgId string
|
||||
flagDevAuthMethodId string
|
||||
flagDevControllerAPIListenAddr string
|
||||
flagDevControllerClusterListenAddr string
|
||||
flagDevSkipAuthMethodCreation bool
|
||||
}
|
||||
|
||||
func (c *Command) Synopsis() string {
|
||||
@@ -80,14 +80,6 @@ func (c *Command) Flags() *base.FlagSets {
|
||||
|
||||
f = set.NewFlagSet("Dev Options")
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "dev-org-id",
|
||||
Target: &c.flagDevOrgId,
|
||||
EnvVar: "WATCHTWER_DEV_ORG_ID",
|
||||
Usage: "Auto-created org ID. This only applies when running in \"dev\" " +
|
||||
"mode.",
|
||||
})
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "dev-auth-method-id",
|
||||
Target: &c.flagDevAuthMethodId,
|
||||
@@ -126,6 +118,12 @@ func (c *Command) Flags() *base.FlagSets {
|
||||
Usage: "Address to bind to for controller \"cluster\" purpose.",
|
||||
})
|
||||
|
||||
f.BoolVar(&base.BoolVar{
|
||||
Name: "dev-skip-auth-method-creation",
|
||||
Target: &c.flagDevSkipAuthMethodCreation,
|
||||
Usage: "If set, an auth method will not be created as part of the dev instance. The recovery KMS will be needed to perform any actions.",
|
||||
})
|
||||
|
||||
f.BoolVar(&base.BoolVar{
|
||||
Name: "combine-logs",
|
||||
Target: &c.flagCombineLogs,
|
||||
@@ -254,7 +252,17 @@ func (c *Command) Run(args []string) int {
|
||||
}
|
||||
}()
|
||||
|
||||
if err := c.CreateDevDatabase("postgres"); err != nil {
|
||||
var opts []base.Option
|
||||
if c.flagDevSkipAuthMethodCreation {
|
||||
opts = append(opts, base.WithSkipAuthMethodCreation())
|
||||
switch {
|
||||
case c.flagDevAuthMethodId != "",
|
||||
c.flagDevLoginName != "",
|
||||
c.flagDevPassword != "":
|
||||
c.UI.Warn("-dev-skip-auth-method-creation set, skipping any auth-method related flags")
|
||||
}
|
||||
}
|
||||
if err := c.CreateDevDatabase("postgres", opts...); err != nil {
|
||||
c.UI.Error(fmt.Errorf("Error creating dev database container: %w", err).Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -180,6 +180,10 @@ type TestControllerOpts struct {
|
||||
// DefaultPassword is the password used when creating the default account.
|
||||
DefaultPassword string
|
||||
|
||||
// DisableAuthMethodCreation can be set true to disable creating an auth
|
||||
// method automatically.
|
||||
DisableAuthMethodCreation bool
|
||||
|
||||
// DisableDatabaseCreation can be set true to disable creating a dev
|
||||
// database
|
||||
DisableDatabaseCreation bool
|
||||
@@ -302,7 +306,11 @@ func NewTestController(t *testing.T, opts *TestControllerOpts) *TestController {
|
||||
t.Fatal(err)
|
||||
}
|
||||
} else if !opts.DisableDatabaseCreation {
|
||||
if err := tc.b.CreateDevDatabase("postgres"); err != nil {
|
||||
var createOpts []base.Option
|
||||
if opts.DisableAuthMethodCreation {
|
||||
createOpts = append(createOpts, base.WithSkipAuthMethodCreation())
|
||||
}
|
||||
if err := tc.b.CreateDevDatabase("postgres", createOpts...); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,17 +20,32 @@ func getOpts(opt ...Option) (*controller.TestControllerOpts, error) {
|
||||
if opts.setWithConfigFile && opts.setWithConfigText {
|
||||
return nil, fmt.Errorf("Cannot provide both WithConfigFile and WithConfigText")
|
||||
}
|
||||
var setDbParams bool
|
||||
if opts.setDefaultAuthMethodId || 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
|
||||
}
|
||||
|
||||
type option struct {
|
||||
tcOptions *controller.TestControllerOpts
|
||||
setWithConfigFile bool
|
||||
setWithConfigText bool
|
||||
setDisableDatabaseCreation bool
|
||||
setDefaultAuthMethodId bool
|
||||
setDefaultLoginName bool
|
||||
setDefaultPassword bool
|
||||
tcOptions *controller.TestControllerOpts
|
||||
setWithConfigFile bool
|
||||
setWithConfigText bool
|
||||
setDisableAuthMethodCreation bool
|
||||
setDisableDatabaseCreation bool
|
||||
setDefaultAuthMethodId bool
|
||||
setDefaultLoginName bool
|
||||
setDefaultPassword bool
|
||||
}
|
||||
|
||||
type Option func(*option) error
|
||||
@@ -69,13 +84,19 @@ func WithConfigText(ct string) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
if c.setDisableDatabaseCreation {
|
||||
return fmt.Errorf("DisableDatabaseCreation provided more than once.")
|
||||
}
|
||||
c.setDisableDatabaseCreation = true
|
||||
c.tcOptions.DisableDatabaseCreation = true
|
||||
return nil
|
||||
@@ -84,9 +105,6 @@ func DisableDatabaseCreation() Option {
|
||||
|
||||
func WithDefaultAuthMethodId(id string) Option {
|
||||
return func(c *option) error {
|
||||
if c.setDefaultAuthMethodId {
|
||||
return fmt.Errorf("WithDefaultAuthMethodId provided more than once.")
|
||||
}
|
||||
c.setDefaultAuthMethodId = true
|
||||
c.tcOptions.DefaultAuthMethodId = id
|
||||
return nil
|
||||
@@ -95,9 +113,6 @@ func WithDefaultAuthMethodId(id string) Option {
|
||||
|
||||
func WithDefaultLoginName(ln string) Option {
|
||||
return func(c *option) error {
|
||||
if c.setDefaultLoginName {
|
||||
return fmt.Errorf("WithDefaultLoginName provided more than once.")
|
||||
}
|
||||
c.setDefaultLoginName = true
|
||||
c.tcOptions.DefaultLoginName = ln
|
||||
return nil
|
||||
@@ -106,9 +121,6 @@ func WithDefaultLoginName(ln string) Option {
|
||||
|
||||
func WithDefaultPassword(pw string) Option {
|
||||
return func(c *option) error {
|
||||
if c.setDefaultPassword {
|
||||
return fmt.Errorf("WithDefaultPassword provided more than once.")
|
||||
}
|
||||
c.setDefaultPassword = true
|
||||
c.tcOptions.DefaultPassword = pw
|
||||
return nil
|
||||
|
||||
Reference in new issue
Block a user