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:
Jeff Mitchell authored and GitHub committed 2020-08-26 23:27:46 -04:00
1 parent 490be8a7e4
commit b53812a5c1
6 files changed
+111 -56

No files matched your search

+11 -2
View File
@@ -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
}
}
+24 -14
View File
@@ -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 }
+18 -10
View File
@@ -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
}
+18 -10
View File
@@ -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
}