Skip to content

Commit

Permalink
add secret sync tests
Browse files Browse the repository at this point in the history
  • Loading branch information
miagilepner committed Jan 8, 2024
1 parent 62da123 commit 48be56c
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 4 deletions.
4 changes: 4 additions & 0 deletions vault/activity/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ type CountsRecord struct {
SecretSyncs int `json:"secret_syncs"`
}

func (c *CountsRecord) HasCounts() bool {
return c.EntityClients+c.NonEntityClients+c.SecretSyncs != 0
}

type NewClientRecord struct {
Counts *CountsRecord `json:"counts"`
Namespaces []*MonthlyNamespaceRecord `json:"namespaces"`
Expand Down
11 changes: 7 additions & 4 deletions vault/activity_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -1582,6 +1582,9 @@ type ResponseCounts struct {
}

func (existingRecord *ResponseCounts) Add(newRecord *ResponseCounts) {
if newRecord == nil {
return
}
existingRecord.EntityClients += newRecord.EntityClients
existingRecord.Clients += newRecord.Clients
existingRecord.DistinctEntities += newRecord.DistinctEntities
Expand Down Expand Up @@ -2658,7 +2661,7 @@ func (a *ActivityLog) prepareMonthsResponseForQuery(ctx context.Context, byMonth
months := make([]*ResponseMonth, 0, len(byMonth))
for _, monthsRecord := range byMonth {
newClientsResponse := &ResponseNewClients{}
if int(monthsRecord.NewClients.Counts.EntityClients+monthsRecord.NewClients.Counts.NonEntityClients) != 0 {
if monthsRecord.NewClients.Counts.HasCounts() {
newClientsNSResponse, err := a.prepareNamespaceResponse(ctx, monthsRecord.NewClients.Namespaces)
if err != nil {
return nil, err
Expand All @@ -2670,7 +2673,7 @@ func (a *ActivityLog) prepareMonthsResponseForQuery(ctx context.Context, byMonth
monthResponse := &ResponseMonth{
Timestamp: time.Unix(monthsRecord.Timestamp, 0).UTC().Format(time.RFC3339),
}
if int(monthsRecord.Counts.EntityClients+monthsRecord.Counts.NonEntityClients) != 0 {
if monthsRecord.Counts.HasCounts() {
nsResponse, err := a.prepareNamespaceResponse(ctx, monthsRecord.Namespaces)
if err != nil {
return nil, err
Expand All @@ -2693,7 +2696,7 @@ func (a *ActivityLog) prepareNamespaceResponse(ctx context.Context, nsRecords []
}
nsResponse := make([]*ResponseNamespace, 0, len(nsRecords))
for _, nsRecord := range nsRecords {
if int(nsRecord.Counts.EntityClients) == 0 && int(nsRecord.Counts.NonEntityClients) == 0 {
if !nsRecord.Counts.HasCounts() {
continue
}

Expand All @@ -2704,7 +2707,7 @@ func (a *ActivityLog) prepareNamespaceResponse(ctx context.Context, nsRecords []
if a.includeInResponse(queryNS, ns) {
mountResponse := make([]*ResponseMount, 0, len(nsRecord.Mounts))
for _, mountRecord := range nsRecord.Mounts {
if int(mountRecord.Counts.EntityClients) == 0 && int(mountRecord.Counts.NonEntityClients) == 0 {
if !mountRecord.Counts.HasCounts() {
continue
}

Expand Down
128 changes: 128 additions & 0 deletions vault/external_tests/activity_testonly/activity_testonly_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package activity_testonly

import (
"context"
"encoding/json"
"testing"
"time"

Expand Down Expand Up @@ -237,3 +238,130 @@ func getMonthsData(t *testing.T, resp *api.Secret) []vault.ResponseMonth {
require.NoError(t, err)
return monthsResponse
}

func getNamespaceData(t *testing.T, resp *api.Secret) []vault.ResponseNamespace {
t.Helper()
nsRaw, ok := resp.Data["by_namespace"]
require.True(t, ok)
nsResponse := make([]vault.ResponseNamespace, 0)
err := mapstructure.Decode(nsRaw, &nsResponse)
require.NoError(t, err)
return nsResponse
}

func getTotals(t *testing.T, resp *api.Secret) vault.ResponseCounts {
t.Helper()
totalRaw, ok := resp.Data["total"]
require.True(t, ok)
total := vault.ResponseCounts{}
err := mapstructure.Decode(totalRaw, &total)
require.NoError(t, err)
return total
}

// Test_ActivityLog_SecretSyncResponse creates 10 secret sync clients and
// verifies that the activity log query response returns 10 secret sync clients
// at every level of the response hierarchy
func Test_ActivityLog_SecretSyncResponse(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",
})
_, err = clientcountutil.NewActivityLogData(client).
NewCurrentMonthData().
NewClientsSeen(10, clientcountutil.WithClientType("secret-sync")).
Write(context.Background(), generation.WriteOptions_WRITE_ENTITIES)
require.NoError(t, err)

now := time.Now().UTC()
resp, err := client.Logical().ReadWithData("sys/internal/counters/activity", map[string][]string{
"end_time": {timeutil.EndOfMonth(now).Format(time.RFC3339)},
"start_time": {timeutil.StartOfMonth(now).Format(time.RFC3339)},
})
require.NoError(t, err)

total := getTotals(t, resp)
require.Equal(t, 10, total.SecretSyncs)

byNamespace := getNamespaceData(t, resp)
require.Equal(t, 10, byNamespace[0].Counts.SecretSyncs)
require.Equal(t, 10, byNamespace[0].Mounts[0].Counts.SecretSyncs)

byMonth := getMonthsData(t, resp)
require.Equal(t, 10, byMonth[0].NewClients.Counts.SecretSyncs)
require.Equal(t, 10, byMonth[0].Counts.SecretSyncs)
require.Equal(t, 10, byMonth[0].Namespaces[0].Counts.SecretSyncs)
require.Equal(t, 10, byMonth[0].Namespaces[0].Mounts[0].Counts.SecretSyncs)
}

// Test_ActivityLogCurrentMonth_SecretSyncResponse creates 10 secret sync
// clients and verifies that the activity log partial month response returns
// 10 secret sync clients at every level of the response hierarchy
func Test_ActivityLogCurrentMonth_SecretSyncResponse(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",
})
_, err = clientcountutil.NewActivityLogData(client).
NewCurrentMonthData().
NewClientsSeen(10, clientcountutil.WithClientType("secret-sync")).
Write(context.Background(), generation.WriteOptions_WRITE_ENTITIES)
require.NoError(t, err)

resp, err := client.Logical().Read("sys/internal/counters/activity/monthly")
require.NoError(t, err)

secretSyncs, ok := resp.Data["secret_syncs"]
require.True(t, ok)
require.Equal(t, json.Number("10"), secretSyncs)

byNamespace := getNamespaceData(t, resp)
require.Equal(t, 10, byNamespace[0].Counts.SecretSyncs)
require.Equal(t, 10, byNamespace[0].Mounts[0].Counts.SecretSyncs)

byMonth := getMonthsData(t, resp)
require.Equal(t, 10, byMonth[0].NewClients.Counts.SecretSyncs)
require.Equal(t, 10, byMonth[0].Counts.SecretSyncs)
require.Equal(t, 10, byMonth[0].Namespaces[0].Counts.SecretSyncs)
require.Equal(t, 10, byMonth[0].Namespaces[0].Mounts[0].Counts.SecretSyncs)
}

// Test_SecretSync_Deduplication verifies that secret sync clients are
// deduplicated across months. The test creates 10 secret sync clients and
// repeats those clients in later months, then also registers 3 and then 2 new
// secret sync clients. The test verifies that the total number of secret sync
// clients is 15 (10 + 2 + 3), ensuring that the duplicates are not included
func Test_SecretSync_Deduplication(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",
})
_, err = clientcountutil.NewActivityLogData(client).
NewPreviousMonthData(3).
NewClientsSeen(10, clientcountutil.WithClientType("secret-sync")).
NewPreviousMonthData(2).
RepeatedClientsSeen(4, clientcountutil.WithClientType("secret-sync")).
NewClientsSeen(3, clientcountutil.WithClientType("secret-sync")).
NewPreviousMonthData(1).
RepeatedClientsSeen(5, clientcountutil.WithClientType("secret-sync")).
NewClientsSeen(2, clientcountutil.WithClientType("secret-sync")).
Write(context.Background(), generation.WriteOptions_WRITE_PRECOMPUTED_QUERIES)
require.NoError(t, err)

now := time.Now().UTC()
resp, err := client.Logical().ReadWithData("sys/internal/counters/activity", map[string][]string{
"end_time": {timeutil.StartOfMonth(now).Format(time.RFC3339)},
"start_time": {timeutil.StartOfMonth(timeutil.MonthsPreviousTo(4, now)).Format(time.RFC3339)},
},
)
require.NoError(t, err)

total := getTotals(t, resp)
require.Equal(t, 15, total.SecretSyncs)
}

0 comments on commit 48be56c

Please sign in to comment.