Skip to content

Commit

Permalink
Backport 1.17.x auto rolling (#27880)
Browse files Browse the repository at this point in the history
* Prepare CE changes for [census.Agent] SetMetadata (#27577)

(cherry picked from commit 93682b0)

* Add CE plumbing for CensusManager reload (#27664)

This PR adds the CE plumbing and stubs for forcing agent instantiation
whenever the Vault license changes.

Resolves: VAULT-28583
Enterprise PR: hashicorp/vault-enterprise#6168

(cherry picked from commit 3229cf1)

* Add auto-roll billing start date changes CE changes (#27656)

* add NormalizeToYear function and test

* add ent changelog

* test name typo

(cherry picked from commit 01f78f5)

---------

Co-authored-by: akshya96 <87045294+akshya96@users.noreply.github.com>
  • Loading branch information
mpalmi and akshya96 authored Jul 26, 2024
1 parent 7ca8a20 commit 2bbfc49
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 21 deletions.
3 changes: 3 additions & 0 deletions changelog/27656.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
license utilization reporting (enterprise): Auto-roll billing start date.
```
2 changes: 1 addition & 1 deletion command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1703,7 +1703,7 @@ func (c *ServerCommand) Run(args []string) int {
sr.NotifyConfigurationReload(srConfig)
}

if err := core.ReloadCensus(); err != nil {
if err := core.ReloadCensusManager(false); err != nil {
c.UI.Error(err.Error())
}

Expand Down
4 changes: 4 additions & 0 deletions command/server_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ func (c *ServerCommand) ReloadedCh() chan struct{} {
return c.reloadedCh
}

func (c *ServerCommand) LicenseReloadedCh() chan error {
return c.licenseReloadedCh
}

func testServerCommand(tb testing.TB) (*cli.MockUi, *ServerCommand) {
tb.Helper()

Expand Down
10 changes: 10 additions & 0 deletions helper/timeutil/timeutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,13 @@ func (_ DefaultClock) NewTicker(d time.Duration) *time.Ticker {
func (_ DefaultClock) NewTimer(d time.Duration) *time.Timer {
return time.NewTimer(d)
}

// NormalizeToYear returns date normalized to the latest date
// within one year of normal. Assumes the date argument is
// some date before normal.
func NormalizeToYear(date, normal time.Time) time.Time {
for date.AddDate(1, 0, 0).Compare(normal) <= 0 {
date = date.AddDate(1, 0, 0)
}
return date
}
93 changes: 93 additions & 0 deletions helper/timeutil/timeutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"reflect"
"testing"
"time"

"github.com/stretchr/testify/require"
)

func TestTimeutil_StartOfPreviousMonth(t *testing.T) {
Expand Down Expand Up @@ -367,3 +369,94 @@ func TestTimeUtil_ParseTimeFromPath(t *testing.T) {
}
}
}

// TestTimeUtil_NormalizeToYear tests NormalizeToYear function which returns the normalized input date wrt to the normal.
func TestTimeUtil_NormalizeToYear(t *testing.T) {
testCases := []struct {
inputDate time.Time
normalDate time.Time
expectedNormalizedDate time.Time
}{
{
inputDate: time.Date(2024, 9, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2024, 10, 1, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2024, 9, 29, 0, 0, 0, 0, time.UTC),
},
{
inputDate: time.Date(2024, 9, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2025, 9, 29, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2025, 9, 29, 0, 0, 0, 0, time.UTC),
},
{
inputDate: time.Date(2024, 9, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2025, 10, 1, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2025, 9, 29, 0, 0, 0, 0, time.UTC),
},
// inputDate more than 2 years prior to normal date
{
inputDate: time.Date(2022, 9, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2024, 6, 15, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2023, 9, 29, 0, 0, 0, 0, time.UTC),
},
{
inputDate: time.Date(2022, 9, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2024, 9, 28, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2023, 9, 29, 0, 0, 0, 0, time.UTC),
},
{
inputDate: time.Date(2022, 9, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2024, 9, 29, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2024, 9, 29, 0, 0, 0, 0, time.UTC),
},
{
inputDate: time.Date(2022, 9, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2024, 9, 30, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2024, 9, 29, 0, 0, 0, 0, time.UTC),
},
{
inputDate: time.Date(2020, 9, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2024, 12, 1, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2024, 9, 29, 0, 0, 0, 0, time.UTC),
},
// leap year test cases
{
inputDate: time.Date(2020, 9, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2024, 9, 28, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2023, 9, 29, 0, 0, 0, 0, time.UTC),
},
{
inputDate: time.Date(2024, 2, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2025, 2, 28, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2024, 2, 29, 0, 0, 0, 0, time.UTC),
},
{
inputDate: time.Date(2024, 2, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2025, 3, 1, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2025, 3, 1, 0, 0, 0, 0, time.UTC),
},
{
inputDate: time.Date(2024, 2, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2025, 3, 2, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2025, 3, 1, 0, 0, 0, 0, time.UTC),
},
{
inputDate: time.Date(2024, 2, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2028, 2, 28, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2027, 3, 1, 0, 0, 0, 0, time.UTC),
},
{
inputDate: time.Date(2024, 2, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2028, 2, 29, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2027, 3, 1, 0, 0, 0, 0, time.UTC),
},
{
inputDate: time.Date(2024, 2, 29, 0, 0, 0, 0, time.UTC),
normalDate: time.Date(2028, 3, 1, 0, 0, 0, 0, time.UTC),
expectedNormalizedDate: time.Date(2028, 3, 1, 0, 0, 0, 0, time.UTC),
},
}
for _, tc := range testCases {
normalizedDate := NormalizeToYear(tc.inputDate, tc.normalDate)
require.Equal(t, tc.expectedNormalizedDate, normalizedDate)
}
}
3 changes: 2 additions & 1 deletion vault/activity_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,8 @@ func (a *ActivityLog) SetConfigInit(config activityConfig) {
a.defaultReportMonths = config.DefaultReportMonths
a.retentionMonths = config.RetentionMonths

if a.retentionMonths < a.configOverrides.MinimumRetentionMonths {
// Let tests override the minimum if they want to.
if a.configOverrides.MinimumRetentionMonths > 0 {
a.retentionMonths = a.configOverrides.MinimumRetentionMonths
}

Expand Down
1 change: 0 additions & 1 deletion vault/census.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ func (c *Core) setupCensusManager() error { return nil }
func (c *Core) BillingStart() time.Time { return time.Time{} }
func (c *Core) AutomatedLicenseReportingEnabled() bool { return false }
func (c *Core) CensusAgent() CensusReporter { return nil }
func (c *Core) ReloadCensus() error { return nil }
func (c *Core) teardownCensusManager() error { return nil }
func (c *Core) StartManualCensusSnapshots() {}
func (c *Core) ManualLicenseReportingEnabled() bool { return false }
Expand Down
5 changes: 3 additions & 2 deletions vault/census_stubs_oss.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ import "context"

//go:generate go run github.com/hashicorp/vault/tools/stubmaker

func (c *Core) StartCensusReports(ctx context.Context) {}
func (c *Core) ReloadCensusActivityLog() error { return nil }
func (c *Core) StartCensusReports(ctx context.Context) {}
func (c *Core) SetRetentionMonths(months int) error { return nil }
func (c *Core) ReloadCensusManager(licenseChange bool) error { return nil }
14 changes: 5 additions & 9 deletions vault/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -2458,16 +2458,13 @@ func (s standardUnsealStrategy) unseal(ctx context.Context, logger log.Logger, c
return err
}

if !c.perfStandby {
if err := c.setupCensusManager(); err != nil {
logger.Error("failed to instantiate the license reporting agent", "error", err)
}

c.StartCensusReports(ctx)

c.StartManualCensusSnapshots()
if err := c.setupCensusManager(); err != nil {
logger.Error("failed to instantiate the license reporting agent", "error", err)
}

c.StartCensusReports(ctx)
c.StartManualCensusSnapshots()

} else {
brokerLogger := logger.Named("audit")
broker, err := audit.NewBroker(brokerLogger)
Expand Down Expand Up @@ -2861,7 +2858,6 @@ func (c *Core) preSeal() error {
if err := c.teardownCensusManager(); err != nil {
result = multierror.Append(result, fmt.Errorf("error tearing down reporting agent: %w", err))
}

if err := c.teardownCredentials(context.Background()); err != nil {
result = multierror.Append(result, fmt.Errorf("error tearing down credentials: %w", err))
}
Expand Down
11 changes: 4 additions & 7 deletions vault/logical_system_activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,9 +411,6 @@ func (b *SystemBackend) handleActivityConfigUpdate(ctx context.Context, req *log
}
}

a.core.activityLogLock.RLock()
minimumRetentionMonths := a.configOverrides.MinimumRetentionMonths
a.core.activityLogLock.RUnlock()
enabled := config.Enabled == "enable"
if !enabled && config.Enabled == "default" {
enabled = activityLogEnabledDefault
Expand All @@ -424,8 +421,8 @@ func (b *SystemBackend) handleActivityConfigUpdate(ctx context.Context, req *log
}

// if manual license reporting is enabled, retention months must at least be 48 months
if a.core.ManualLicenseReportingEnabled() && config.RetentionMonths < minimumRetentionMonths {
return logical.ErrorResponse("retention_months must be at least %d while Reporting is enabled", minimumRetentionMonths), logical.ErrInvalidRequest
if a.core.ManualLicenseReportingEnabled() && config.RetentionMonths < ActivityLogMinimumRetentionMonths {
return logical.ErrorResponse("retention_months must be at least %d while Reporting is enabled", ActivityLogMinimumRetentionMonths), logical.ErrInvalidRequest
}

// Store the config
Expand All @@ -440,9 +437,9 @@ func (b *SystemBackend) handleActivityConfigUpdate(ctx context.Context, req *log
// Set the new config on the activity log
a.SetConfig(ctx, config)

// reload census agent if retention months change during update when reporting is enabled
// Update Census agent's metadata if retention months change
if prevRetentionMonths != config.RetentionMonths {
if err := a.core.ReloadCensusActivityLog(); err != nil {
if err := b.Core.SetRetentionMonths(config.RetentionMonths); err != nil {
return nil, err
}
}
Expand Down

0 comments on commit 2bbfc49

Please sign in to comment.