Skip to content

Commit

Permalink
Show Current Month When Future Month Start Date is Provided (#28042)
Browse files Browse the repository at this point in the history
* Show current month data

* Added changelog

* Edited changelog
  • Loading branch information
divyaac authored and miagilepner committed Aug 15, 2024
1 parent 181b375 commit 05ff33f
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 5 deletions.
3 changes: 3 additions & 0 deletions changelog/28042.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
activity: The sys/internal/counters/activity endpoint will return current month data when the end_date parameter is set to a future date.
```
18 changes: 13 additions & 5 deletions vault/activity_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -1769,12 +1769,20 @@ func (a *ActivityLog) handleQuery(ctx context.Context, startTime, endTime time.T
startTime = timeutil.StartOfMonth(startTime)
endTime = timeutil.EndOfMonth(endTime)

// At the max, we only want to return data up until the end of the current month.
// Adjust the end time be the current month if a future date has been provided.
endOfCurrentMonth := timeutil.EndOfMonth(a.clock.Now().UTC())
adjustedEndTime := endTime
if endTime.After(endOfCurrentMonth) {
adjustedEndTime = endOfCurrentMonth
}

// If the endTime of the query is the current month, request data from the queryStore
// with the endTime equal to the end of the last month, and add in the current month
// data.
precomputedQueryEndTime := endTime
if timeutil.IsCurrentMonth(endTime, a.clock.Now().UTC()) {
precomputedQueryEndTime = timeutil.EndOfMonth(timeutil.MonthsPreviousTo(1, timeutil.StartOfMonth(endTime)))
precomputedQueryEndTime := adjustedEndTime
if timeutil.IsCurrentMonth(adjustedEndTime, a.clock.Now().UTC()) {
precomputedQueryEndTime = timeutil.EndOfMonth(timeutil.MonthsPreviousTo(1, timeutil.StartOfMonth(adjustedEndTime)))
computePartial = true
}

Expand Down Expand Up @@ -1817,7 +1825,7 @@ func (a *ActivityLog) handleQuery(ctx context.Context, startTime, endTime time.T

// Estimate the current month totals. These record contains is complete with all the
// current month data, grouped by namespace and mounts
currentMonth, err := a.computeCurrentMonthForBillingPeriod(ctx, partialByMonth, startTime, endTime)
currentMonth, err := a.computeCurrentMonthForBillingPeriod(ctx, partialByMonth, startTime, adjustedEndTime)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1867,7 +1875,7 @@ func (a *ActivityLog) handleQuery(ctx context.Context, startTime, endTime time.T
a.sortActivityLogMonthsResponse(months)

// Modify the final month output to make response more consumable based on API request
months = a.modifyResponseMonths(months, startTime, endTime)
months = a.modifyResponseMonths(months, startTime, adjustedEndTime)
responseData["months"] = months

return responseData, nil
Expand Down
39 changes: 39 additions & 0 deletions vault/external_tests/activity_testonly/activity_testonly_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,45 @@ func Test_ActivityLog_EmptyDataMonths(t *testing.T) {
}
}

// Test_ActivityLog_FutureEndDate queries a start time from the past
// and an end date in the future. The test
// verifies that the current month is returned in the response.
func Test_ActivityLog_FutureEndDate(t *testing.T) {
t.Parallel()
cluster := minimal.NewTestSoloCluster(t, nil)
client := cluster.Cores[0].Client
_, err := client.Logical().Write("sys/internal/counters/config", map[string]interface{}{
"enabled": "enable",
})
require.NoError(t, err)
_, err = clientcountutil.NewActivityLogData(client).
NewPreviousMonthData(1).
NewClientsSeen(10).
NewCurrentMonthData().
NewClientsSeen(10).
Write(context.Background(), generation.WriteOptions_WRITE_PRECOMPUTED_QUERIES, generation.WriteOptions_WRITE_ENTITIES)
require.NoError(t, err)

now := time.Now().UTC()
// query from the beginning of 3 months ago to beginning of next month
resp, err := client.Logical().ReadWithData("sys/internal/counters/activity", map[string][]string{
"end_time": {timeutil.StartOfNextMonth(now).Format(time.RFC3339)},
"start_time": {timeutil.StartOfMonth(timeutil.MonthsPreviousTo(3, now)).Format(time.RFC3339)},
})
require.NoError(t, err)
monthsResponse := getMonthsData(t, resp)

require.Len(t, monthsResponse, 4)

// Get the last month of data in the slice
expectedCurrentMonthData := monthsResponse[3]
expectedTime, err := time.Parse(time.RFC3339, expectedCurrentMonthData.Timestamp)
require.NoError(t, err)
if !timeutil.IsCurrentMonth(expectedTime, now) {
t.Fatalf("final month data is not current month")
}
}

func getMonthsData(t *testing.T, resp *api.Secret) []vault.ResponseMonth {
t.Helper()
monthsRaw, ok := resp.Data["months"]
Expand Down

0 comments on commit 05ff33f

Please sign in to comment.