From b509d9e6a764389ef3beae21ea983a48bb711c46 Mon Sep 17 00:00:00 2001 From: Kay Craig Date: Fri, 15 Dec 2023 13:28:26 -0500 Subject: [PATCH] update happy path to allow configuration --- builtin/credential/ldap/backend.go | 26 ++++++++++++++------------ builtin/credential/ldap/path_config.go | 20 ++++++++++++++++++++ sdk/framework/backend.go | 6 +++++- sdk/framework/schedule.go | 4 ++++ 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/builtin/credential/ldap/backend.go b/builtin/credential/ldap/backend.go index b25e0ada73..c4a9a925dd 100644 --- a/builtin/credential/ldap/backend.go +++ b/builtin/credential/ldap/backend.go @@ -9,7 +9,6 @@ import ( "fmt" "strings" "sync" - "time" goldap "github.com/go-ldap/ldap/v3" @@ -65,17 +64,18 @@ func Backend() *backend { BackendType: logical.TypeCredential, // dummy implementation RotatePasswordGetSchedule: func(ctx context.Context, req *logical.Request) (*framework.RootSchedule, error) { - d := &framework.DefaultSchedule{} - cron, err := d.Parse("10 * * * *") - if err != nil { - return nil, err - } - return &framework.RootSchedule{ - Schedule: cron, - RotationWindow: 15 * time.Second, - RotationSchedule: "10 * * * *", - NextVaultRotation: cron.Next(time.Now()), - }, nil + //d := &framework.DefaultSchedule{} + //cron, err := d.Parse("10 * * * *") + //if err != nil { + // return nil, err + //} + //return &framework.RootSchedule{ + // Schedule: cron, + // RotationWindow: 15 * time.Second, + // RotationSchedule: "10 * * * *", + // NextVaultRotation: cron.Next(time.Now()), + //}, nil + return b.rootSchedule, nil }, RotatePassword: func(ctx context.Context, req *logical.Request) error { // lock the backend's state - really just the config state - for mutating @@ -156,6 +156,8 @@ type backend struct { *framework.Backend mu sync.RWMutex + + rootSchedule *framework.RootSchedule } func (b *backend) Login(ctx context.Context, req *logical.Request, username string, password string, usernameAsAlias bool) (string, []string, *logical.Response, []string, error) { diff --git a/builtin/credential/ldap/path_config.go b/builtin/credential/ldap/path_config.go index e24d04b295..7c7ad90cbb 100644 --- a/builtin/credential/ldap/path_config.go +++ b/builtin/credential/ldap/path_config.go @@ -6,6 +6,7 @@ package ldap import ( "context" "strings" + "time" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/consts" @@ -54,6 +55,11 @@ func pathConfig(b *backend) *framework.Path { Description: "Password policy to use to rotate the root password", } + p.Fields["schedule"] = &framework.FieldSchema{ + Type: framework.TypeString, + Description: "Cron style schedule for rotating the root password", + } + return p } @@ -210,6 +216,19 @@ func (b *backend) pathConfigWrite(ctx context.Context, req *logical.Request, d * if passwordPolicy, ok := d.GetOk("password_policy"); ok { cfg.PasswordPolicy = passwordPolicy.(string) } + if schedule, ok := d.GetOk("schedule"); ok { + cfg.Schedule = schedule.(string) + sched, err := framework.Parse(cfg.Schedule) + if err != nil { + logical.ErrorResponse("invalid schedule: %q", err) + } + b.rootSchedule = &framework.RootSchedule{ + Schedule: sched, + RotationWindow: 10 * time.Second, // TODO: hardcode for now + RotationSchedule: cfg.Schedule, + } + b.rootSchedule.NextVaultRotation = b.rootSchedule.NextRotationTime() + } entry, err := logical.StorageEntryJSON("config", cfg) if err != nil { @@ -253,6 +272,7 @@ type ldapConfigEntry struct { *ldaputil.ConfigEntry PasswordPolicy string `json:"password_policy"` + Schedule string `json:"schedule"` } const pathConfigHelpSyn = ` diff --git a/sdk/framework/backend.go b/sdk/framework/backend.go index 6057282a36..1dd14f8f52 100644 --- a/sdk/framework/backend.go +++ b/sdk/framework/backend.go @@ -147,6 +147,10 @@ func (b *Backend) CheckQueue(ctx context.Context, req *logical.Request) error { // this indicates that there is no rotation schedule set, which should mean we can just end return nil } + if rs == nil { + b.logger.Info("no schedule") + return nil + } b.logger.Info("got schedule") b.logger.Info("checking time", "priority", time.Unix(b.Priority, 0).Format(time.RFC3339), "target", rs.NextVaultRotation.Format(time.RFC3339), "window", rs.RotationWindow/time.Second) @@ -162,7 +166,7 @@ func (b *Backend) CheckQueue(ctx context.Context, req *logical.Request) error { next := rs.NextRotationTime() b.Priority = next.Unix() rs.NextVaultRotation = next - b.logger.Info("updating", "priority", b.Priority) + b.logger.Info("updating", "priority", time.Unix(b.Priority, 0).Format(time.RFC3339)) } } diff --git a/sdk/framework/schedule.go b/sdk/framework/schedule.go index 6b2b77498a..c30f30dd59 100644 --- a/sdk/framework/schedule.go +++ b/sdk/framework/schedule.go @@ -31,6 +31,10 @@ type Scheduler interface { var defaultScheduler Scheduler = &DefaultSchedule{} +func Parse(rotationSchedule string) (*cron.SpecSchedule, error) { + return defaultScheduler.Parse(rotationSchedule) +} + type DefaultSchedule struct{} func (d *DefaultSchedule) Parse(rotationSchedule string) (*cron.SpecSchedule, error) {