mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-06 22:57:02 +02:00
* add ce side code and stubs * add changelog * style refactor * try to use APIPath as mount point instead of request field * fix linter * return a response struct instead of a pure timestamp * add issue time to response * add ttl to GetRotationInformation response * rename field for clarity * update ttl to just seconds * rename next and last rotation time field; describe what they are * rename function * catch up to ent PR * fix patch merge mistake
134 lines
3.5 KiB
Go
134 lines
3.5 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
|
|
}
|
|
|
|
// RotationInfoRequest is the request struct used by SystemView.GetRotationInformation.
|
|
type RotationInfoRequest struct {
|
|
// ReqPath is the plugin-local path to the credential, and needs to match the ReqPath value that
|
|
// was supplied in schedule creation with RegisterRotationJob
|
|
ReqPath string
|
|
}
|
|
|
|
// RotationInfoResponse is the response struct returned by SystemView.GetRotationInformation.
|
|
type RotationInfoResponse struct {
|
|
// NextVaultRotation is the scheduled time of the next rotation.
|
|
NextVaultRotation time.Time
|
|
|
|
// LastVaultRotation is the time of the prior rotation.
|
|
LastVaultRotation time.Time
|
|
|
|
// TTL is integer seconds until next rotation, conventionally clamped to 0 (i.e., will not be negative)
|
|
TTL int64
|
|
}
|
|
|
|
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
|
|
}
|