Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adv ttl mgmt: Ensure initialization sets appropriate rotation schedule #22341

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 28 additions & 10 deletions builtin/logical/database/path_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,9 @@ func (b *databaseBackend) pathStaticRoleRead(ctx context.Context, req *logical.R
}

// only return one of the mutually exclusive fields in the response
if role.StaticAccount.RotationPeriod != 0 {
if role.StaticAccount.UsesRotationPeriod() {
data["rotation_period"] = role.StaticAccount.RotationPeriod.Seconds()
} else if role.StaticAccount.RotationSchedule != "" {
} else if role.StaticAccount.UsesRotationSchedule() {
data["rotation_schedule"] = role.StaticAccount.RotationSchedule
// rotation_window is only valid with rotation_schedule
if role.StaticAccount.RotationWindow != 0 {
Expand Down Expand Up @@ -579,16 +579,18 @@ func (b *databaseBackend) pathStaticRoleCreateUpdate(ctx context.Context, req *l
return logical.ErrorResponse(fmt.Sprintf("rotation_period must be %d seconds or more", defaultQueueTickSeconds)), nil
}
role.StaticAccount.RotationPeriod = time.Duration(rotationPeriodSeconds) * time.Second
// Unset rotation schedule if rotation period is set
role.StaticAccount.RotationSchedule = ""

if rotationWindowOk {
return logical.ErrorResponse("rotation_window is invalid with use of rotation_period"), nil
}

// Unset rotation schedule and window if rotation period is set since
// these are mutually exclusive
role.StaticAccount.RotationSchedule = ""
role.StaticAccount.RotationWindow = 0
}

if rotationScheduleOk {
// TODO(JM): validate this isn't less than defaultQueueTickSeconds?
schedule, err := b.scheduleParser.Parse(rotationSchedule)
if err != nil {
return logical.ErrorResponse("could not parse rotation_schedule", "error", err), nil
Expand All @@ -599,8 +601,6 @@ func (b *databaseBackend) pathStaticRoleCreateUpdate(ctx context.Context, req *l
return logical.ErrorResponse("could not parse rotation_schedule"), nil
}
role.StaticAccount.Schedule = *sched
// Unset rotation period if rotation schedule is set
role.StaticAccount.RotationPeriod = 0

if rotationWindowOk {
rotationWindowSeconds := rotationWindowSecondsRaw.(int)
Expand All @@ -609,6 +609,10 @@ func (b *databaseBackend) pathStaticRoleCreateUpdate(ctx context.Context, req *l
}
role.StaticAccount.RotationWindow = time.Duration(rotationWindowSeconds) * time.Second
}

// Unset rotation period if rotation schedule is set since these are
// mutually exclusive
role.StaticAccount.RotationPeriod = 0
}

if rotationStmtsRaw, ok := data.GetOk("rotation_statements"); ok {
Expand Down Expand Up @@ -689,8 +693,7 @@ func (b *databaseBackend) pathStaticRoleCreateUpdate(ctx context.Context, req *l
item.Priority = lvr.Add(role.StaticAccount.RotationPeriod).Unix()
} else if rotationScheduleChanged {
next := role.StaticAccount.Schedule.Next(lvr)
b.logger.Debug("init priority for Schedule", "lvr", lvr)
b.logger.Debug("init priority for Schedule", "next", next)
b.logger.Debug("init priority for Schedule", "lvr", lvr, "next", next)
item.Priority = role.StaticAccount.Schedule.Next(lvr).Unix()
}

Expand Down Expand Up @@ -829,7 +832,22 @@ type staticAccount struct {
// NextRotationTime calculates the next rotation by adding the Rotation Period
// to the last known vault rotation
func (s *staticAccount) NextRotationTime() time.Time {
return s.LastVaultRotation.Add(s.RotationPeriod)
if s.UsesRotationPeriod() {
return s.LastVaultRotation.Add(s.RotationPeriod)
}
return s.Schedule.Next(s.LastVaultRotation)
}

// UsesRotationSchedule returns true if the given static account has been
// configured to rotate credentials on a schedule (i.e. NOT on a rotation period).
func (s *staticAccount) UsesRotationSchedule() bool {
return s.RotationSchedule != "" && s.RotationPeriod == 0
}

// UsesRotationPeriod returns true if the given static account has been
// configured to rotate credentials on a period (i.e. NOT on a rotation schedule).
func (s *staticAccount) UsesRotationPeriod() bool {
return s.RotationPeriod != 0 && s.RotationSchedule == ""
Comment on lines +842 to +851
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}

// CredentialTTL calculates the approximate time remaining until the credential is
Expand Down
20 changes: 8 additions & 12 deletions builtin/logical/database/rotation.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,19 +267,15 @@ func (b *databaseBackend) rotateCredential(ctx context.Context, s logical.Storag
}

// Update priority and push updated Item to the queue
if role.StaticAccount.RotationSchedule != "" {
schedule, err := b.scheduleParser.Parse(role.StaticAccount.RotationSchedule)
if err != nil {
b.logger.Error("could not parse rotation_schedule", "error", err)
return true
}
next := schedule.Next(lvr)
b.logger.Debug("update priority for Schedule", "lvr", lvr)
b.logger.Debug("update priority for Schedule", "next", next)
item.Priority = schedule.Next(lvr).Unix()
} else {
b.logger.Debug("update priority for RotationPeriod", "lvr", lvr, "next", lvr.Add(role.StaticAccount.RotationPeriod))
if role.StaticAccount.UsesRotationSchedule() {
next := role.StaticAccount.Schedule.Next(lvr)
logger.Debug("update priority for Schedule", "next", next)
item.Priority = role.StaticAccount.Schedule.Next(lvr).Unix()
} else if role.StaticAccount.UsesRotationPeriod() {
logger.Debug("update priority for RotationPeriod", "lvr", lvr, "next", lvr.Add(role.StaticAccount.RotationPeriod))
item.Priority = lvr.Add(role.StaticAccount.RotationPeriod).Unix()
} else {
logger.Error("rotation has not been properly configured")
}

if err := b.pushItem(item); err != nil {
Expand Down