mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-22 15:11:07 +02:00
115 lines
2.8 KiB
Go
115 lines
2.8 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package rotation
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/robfig/cron/v3"
|
|
)
|
|
|
|
const (
|
|
PerformedRegistration = "registration"
|
|
PerformedDeregistration = "deregistration"
|
|
)
|
|
|
|
// RotationOptions is an embeddable struct to capture common rotation
|
|
// settings between a Secret and Auth
|
|
type RotationOptions struct {
|
|
// Schedule holds the info for the framework.Schedule
|
|
Schedule *RotationSchedule
|
|
}
|
|
|
|
// RotationJob represents the secret part of a response.
|
|
type RotationJob struct {
|
|
RotationOptions
|
|
|
|
// RotationID is the ID returned to the user to manage this secret.
|
|
// This is generated by Vault core. Any set value will be ignored.
|
|
// For requests, this will always be blank.
|
|
RotationID string `sentinel:""`
|
|
Path string
|
|
MountPoint string
|
|
Name string
|
|
}
|
|
|
|
type RotationJobConfigureRequest struct {
|
|
Name string
|
|
MountPoint string
|
|
ReqPath string
|
|
RotationSchedule string
|
|
RotationWindow time.Duration
|
|
RotationPeriod time.Duration
|
|
}
|
|
|
|
type RotationJobDeregisterRequest struct {
|
|
MountPoint string
|
|
ReqPath string
|
|
}
|
|
|
|
func (s *RotationJob) Validate() error {
|
|
if s.MountPoint == "" {
|
|
return fmt.Errorf("MountPoint is required")
|
|
}
|
|
|
|
if s.Path == "" {
|
|
return fmt.Errorf("ReqPath is required")
|
|
}
|
|
|
|
if s.Schedule.RotationSchedule == "" && s.Schedule.RotationPeriod.Seconds() == 0 {
|
|
return fmt.Errorf("RotationSchedule or RotationPeriod is required to set up rotation job")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func newRotationJob(configRequest *RotationJobConfigureRequest) (*RotationJob, error) {
|
|
var cronSc *cron.SpecSchedule
|
|
if configRequest.RotationSchedule != "" {
|
|
var err error
|
|
cronSc, err = DefaultScheduler.Parse(configRequest.RotationSchedule)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
rs := &RotationSchedule{
|
|
Schedule: cronSc,
|
|
RotationSchedule: configRequest.RotationSchedule,
|
|
RotationWindow: configRequest.RotationWindow,
|
|
RotationPeriod: configRequest.RotationPeriod,
|
|
NextVaultRotation: time.Time{},
|
|
LastVaultRotation: time.Time{},
|
|
}
|
|
|
|
return &RotationJob{
|
|
RotationOptions: RotationOptions{
|
|
Schedule: rs,
|
|
},
|
|
MountPoint: configRequest.MountPoint,
|
|
Path: configRequest.ReqPath,
|
|
Name: configRequest.Name,
|
|
}, nil
|
|
}
|
|
|
|
// ConfigureRotationJob builds and returns a configured RotationJob for the mount and request with the given schedule.
|
|
func ConfigureRotationJob(configRequest *RotationJobConfigureRequest) (*RotationJob, error) {
|
|
rotationJob, err := newRotationJob(configRequest)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := rotationJob.Validate(); err != nil {
|
|
return nil, fmt.Errorf("error validating rotation job: %s", err)
|
|
}
|
|
|
|
// Expect rotation job to exist here
|
|
if rotationJob == nil {
|
|
return nil, fmt.Errorf("rotation credential was nil; expected non-nil value")
|
|
}
|
|
|
|
return rotationJob, nil
|
|
}
|