Merge remote-tracking branch 'remotes/from/ce/main'

This commit is contained in:
hc-github-team-secure-vault-core 2026-02-09 18:14:12 +00:00
commit 2cebe05425
9 changed files with 111 additions and 84 deletions

12
go.mod
View file

@ -168,7 +168,7 @@ require (
github.com/hashicorp/vault/api v1.22.0
github.com/hashicorp/vault/api/auth/approle v0.1.0
github.com/hashicorp/vault/api/auth/userpass v0.1.0
github.com/hashicorp/vault/sdk v0.21.0
github.com/hashicorp/vault/sdk v0.23.0
github.com/hashicorp/vault/vault/hcp_link/proto v0.0.0-20230201201504-b741fa893d77
github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab
github.com/jackc/pgx/v4 v4.18.3
@ -209,7 +209,7 @@ require (
github.com/sethvargo/go-limiter v0.7.1
github.com/shirou/gopsutil/v3 v3.22.6
github.com/stretchr/testify v1.11.1
github.com/tink-crypto/tink-go/v2 v2.4.0
github.com/tink-crypto/tink-go/v2 v2.5.0
go.etcd.io/bbolt v1.4.0
go.etcd.io/etcd/client/pkg/v3 v3.6.0
go.etcd.io/etcd/client/v2 v2.305.17
@ -231,7 +231,7 @@ require (
golang.org/x/tools v0.39.0
google.golang.org/api v0.251.0
google.golang.org/grpc v1.75.1
google.golang.org/protobuf v1.36.9
google.golang.org/protobuf v1.36.10
gopkg.in/ory-am/dockertest.v3 v3.3.4
k8s.io/apimachinery v0.34.1
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
@ -352,7 +352,7 @@ require (
github.com/couchbase/gocbcoreps v0.1.4 // indirect
github.com/couchbase/goprotostellar v1.0.2 // indirect
github.com/couchbaselabs/gocbconnstr/v2 v2.0.0 // indirect
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
github.com/cyphar/filepath-securejoin v0.5.1 // indirect
github.com/danieljoos/wincred v1.2.2 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
@ -415,7 +415,7 @@ require (
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
github.com/hashicorp/cronexpr v1.1.2 // indirect
github.com/hashicorp/go-discover/provider/gce v0.0.0-20241120163552-5eb1507d16b4 // indirect
github.com/hashicorp/go-hmac-drbg v0.0.0-20210916214228-a6e5a68489f6 // indirect
github.com/hashicorp/go-hmac-drbg v0.0.0-20210916214228-a6e5a68489f6
github.com/hashicorp/go-immutable-radix v1.3.1
github.com/hashicorp/go-metrics v0.5.4 // indirect
github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect
@ -499,7 +499,7 @@ require (
github.com/oklog/ulid v1.3.1 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/opencontainers/runc v1.2.6 // indirect
github.com/opencontainers/runc v1.2.8 // indirect
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
github.com/oracle/oci-go-sdk/v59 v59.0.0 // indirect
github.com/oracle/oci-go-sdk/v60 v60.0.0 // indirect

16
go.sum
View file

@ -980,8 +980,8 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48=
github.com/cyphar/filepath-securejoin v0.5.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0=
github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -1949,8 +1949,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
github.com/opencontainers/runc v1.2.6 h1:P7Hqg40bsMvQGCS4S7DJYhUZOISMLJOB2iGX5COWiPk=
github.com/opencontainers/runc v1.2.6/go.mod h1:dOQeFo29xZKBNeRBI0B19mJtfHv68YgCTh1X+YphA+4=
github.com/opencontainers/runc v1.2.8 h1:RnEICeDReapbZ5lZEgHvj7E9Q3Eex9toYmaGBsbvU5Q=
github.com/opencontainers/runc v1.2.8/go.mod h1:cC0YkmZcuvr+rtBZ6T7NBoVbMGNAdLa/21vIElJDOzI=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A=
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU=
@ -2174,8 +2174,8 @@ github.com/testcontainers/testcontainers-go/modules/postgres v0.37.0/go.mod h1:Q
github.com/tilinna/clock v1.0.2/go.mod h1:ZsP7BcY7sEEz7ktc0IVy8Us6boDrK8VradlKRUGfOao=
github.com/tilinna/clock v1.1.0 h1:6IQQQCo6KoBxVudv6gwtY8o4eDfhHo8ojA5dP0MfhSs=
github.com/tilinna/clock v1.1.0/go.mod h1:ZsP7BcY7sEEz7ktc0IVy8Us6boDrK8VradlKRUGfOao=
github.com/tink-crypto/tink-go/v2 v2.4.0 h1:8VPZeZI4EeZ8P/vB6SIkhlStrJfivTJn+cQ4dtyHNh0=
github.com/tink-crypto/tink-go/v2 v2.4.0/go.mod h1:l//evrF2Y3MjdbpNDNGnKgCpo5zSmvUvnQ4MU+yE2sw=
github.com/tink-crypto/tink-go/v2 v2.5.0 h1:B8KLF6AofxdBIE4UJIaFbmoj5/1ehEtt7/MmzfI4Zpw=
github.com/tink-crypto/tink-go/v2 v2.5.0/go.mod h1:2WbBA6pfNsAfBwDCggboaHeB2X29wkU8XHtGwh2YIk8=
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
@ -3074,8 +3074,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View file

@ -15,14 +15,15 @@ import (
)
const (
BillingSubPath = "billing/"
ReplicatedPrefix = "replicated/"
RoleHWMCountsHWM = "maxRoleCounts/"
KvHWMCountsHWM = "maxKvCounts/"
TransitDataProtectionCallCountsPrefix = "transitDataProtectionCallCounts/"
LocalPrefix = "local/"
ThirdPartyPluginsPrefix = "thirdPartyPluginCounts/"
KmipEnabledPrefix = "kmipEnabled/"
BillingSubPath = "billing/"
ReplicatedPrefix = "replicated/"
RoleHWMCountsHWM = "maxRoleCounts/"
KvHWMCountsHWM = "maxKvCounts/"
TransitDataProtectionCallCountsPrefix = "transitDataProtectionCallCounts/"
TransformDataProtectionCallCountsPrefix = "transformDataProtectionCallCounts/"
LocalPrefix = "local/"
ThirdPartyPluginsPrefix = "thirdPartyPluginCounts/"
KmipEnabledPrefix = "kmipEnabled/"
BillingWriteInterval = 10 * time.Minute
)
@ -57,9 +58,8 @@ func GetMonthlyBillingPath(localPrefix string, now time.Time, billingMetric stri
}
type DataProtectionCallCounts struct {
Transit *atomic.Uint64 `json:"transit,omitempty"`
// TODO: Uncomment when we add support for Transform tracking (VAULT-41205)
// Transform atomic.int64 `json:"transform,omitempty"`
Transit *atomic.Uint64 `json:"transit,omitempty"`
Transform *atomic.Uint64 `json:"transform,omitempty"`
}
var _ logical.ConsumptionBillingManager = (*ConsumptionBilling)(nil)
@ -74,6 +74,14 @@ func (s *ConsumptionBilling) WriteBillingData(ctx context.Context, mountType str
}
s.DataProtectionCallCounts.Transit.Add(val)
case "transform":
val, ok := data["count"].(uint64)
if !ok {
err := fmt.Errorf("invalid value type for transform")
return err
}
s.DataProtectionCallCounts.Transform.Add(val)
default:
err := fmt.Errorf("unknown metric type: %s", mountType)
return err

View file

@ -22,7 +22,8 @@ func (c *Core) setupConsumptionBilling(ctx context.Context) error {
c.consumptionBilling = &billing.ConsumptionBilling{
BillingConfig: c.billingConfig,
DataProtectionCallCounts: billing.DataProtectionCallCounts{
Transit: &atomic.Uint64{},
Transit: &atomic.Uint64{},
Transform: &atomic.Uint64{},
},
Logger: logger,
}
@ -139,9 +140,11 @@ func (c *Core) UpdateLocalHWMMetrics(ctx context.Context, currentMonth time.Time
// UpdateLocalAggregatedMetrics updates local metrics that are aggregated across all replicated clusters
func (c *Core) UpdateLocalAggregatedMetrics(ctx context.Context, currentMonth time.Time) error {
// Update aggregrated count of data protection calls
if _, err := c.UpdateDataProtectionCallCounts(ctx, currentMonth); err != nil {
if _, err := c.UpdateTransitCallCounts(ctx, currentMonth); err != nil {
return fmt.Errorf("could not store transit data protection call counts: %w", err)
}
if _, err := c.UpdateTransformCallCounts(ctx, currentMonth); err != nil {
return fmt.Errorf("could not store transform data protection call counts: %w", err)
}
return nil
}

View file

@ -3,10 +3,18 @@
package vault
func (c *Core) ResetInMemoryDataProtectionCallCounts() {
func (c *Core) ResetInMemoryTransitDataProtectionCallCounts() {
c.consumptionBilling.DataProtectionCallCounts.Transit.Store(0)
}
func (c *Core) GetInMemoryTransitDataProtectionCallCounts() uint64 {
return c.consumptionBilling.DataProtectionCallCounts.Transit.Load()
}
func (c *Core) ResetInMemoryTransformDataProtectionCallCounts() {
c.consumptionBilling.DataProtectionCallCounts.Transform.Store(0)
}
func (c *Core) GetInMemoryTransformDataProtectionCallCounts() uint64 {
return c.consumptionBilling.DataProtectionCallCounts.Transform.Load()
}

View file

@ -6,7 +6,6 @@ package vault
import (
"context"
"strconv"
"sync/atomic"
"time"
"github.com/hashicorp/vault/sdk/logical"
@ -265,11 +264,10 @@ func (c *Core) GetBillingSubView() *BarrierView {
return c.systemBarrierView.SubView(billing.BillingSubPath)
}
// storeDataProtectionCallCountsLocked must be called with BillingStorageLock held
func (c *Core) storeDataProtectionCallCountsLocked(ctx context.Context, maxCounts *billing.DataProtectionCallCounts, localPathPrefix string, month time.Time) error {
// storeTransitCallCountsLocked must be called with BillingStorageLock held
func (c *Core) storeTransitCallCountsLocked(ctx context.Context, transitCount uint64, localPathPrefix string, month time.Time) error {
// Store count for each data protection type separately because they are atomic counters
billingPath := billing.GetMonthlyBillingPath(localPathPrefix, month, billing.TransitDataProtectionCallCountsPrefix)
transitCount := maxCounts.Transit.Load()
entry := &logical.StorageEntry{
Key: billingPath,
Value: []byte(strconv.FormatUint(transitCount, 10)),
@ -277,57 +275,48 @@ func (c *Core) storeDataProtectionCallCountsLocked(ctx context.Context, maxCount
return c.GetBillingSubView().Put(ctx, entry)
}
// getStoredDataProtectionCallCountsLocked must be called with BillingStorageLock held
func (c *Core) getStoredDataProtectionCallCountsLocked(ctx context.Context, localPathPrefix string, month time.Time) (*billing.DataProtectionCallCounts, error) {
// getStoredTransitCallCountsLocked must be called with BillingStorageLock held
func (c *Core) getStoredTransitCallCountsLocked(ctx context.Context, localPathPrefix string, month time.Time) (uint64, error) {
// Retrieve count for each data protection type separately because they are atomic counters
ret := &billing.DataProtectionCallCounts{
Transit: &atomic.Uint64{},
}
billingPath := billing.GetMonthlyBillingPath(localPathPrefix, month, billing.TransitDataProtectionCallCountsPrefix)
entry, err := c.GetBillingSubView().Get(ctx, billingPath)
if err != nil {
return nil, err
return 0, err
}
if entry == nil {
return ret, nil
return 0, nil
}
transitCount, err := strconv.ParseUint(string(entry.Value), 10, 64)
if err != nil {
return nil, err
return 0, err
}
ret.Transit.Store(transitCount)
return ret, nil
return transitCount, nil
}
func (c *Core) GetStoredDataProtectionCallCounts(ctx context.Context, month time.Time) (*billing.DataProtectionCallCounts, error) {
func (c *Core) GetStoredTransitCallCounts(ctx context.Context, month time.Time) (uint64, error) {
c.consumptionBilling.BillingStorageLock.RLock()
defer c.consumptionBilling.BillingStorageLock.RUnlock()
return c.getStoredDataProtectionCallCountsLocked(ctx, billing.LocalPrefix, month)
return c.getStoredTransitCallCountsLocked(ctx, billing.LocalPrefix, month)
}
func (c *Core) UpdateDataProtectionCallCounts(ctx context.Context, currentMonth time.Time) (*billing.DataProtectionCallCounts, error) {
func (c *Core) UpdateTransitCallCounts(ctx context.Context, currentMonth time.Time) (uint64, error) {
c.consumptionBilling.BillingStorageLock.Lock()
defer c.consumptionBilling.BillingStorageLock.Unlock()
storedDataProtectionCallCounts, err := c.getStoredDataProtectionCallCountsLocked(ctx, billing.LocalPrefix, currentMonth)
storedTransitCount, err := c.getStoredTransitCallCountsLocked(ctx, billing.LocalPrefix, currentMonth)
if err != nil {
return nil, err
}
if storedDataProtectionCallCounts == nil {
storedDataProtectionCallCounts = &billing.DataProtectionCallCounts{}
return 0, err
}
// Sum the current count with the stored count
transitCount := c.consumptionBilling.DataProtectionCallCounts.Transit.Swap(0)
storedDataProtectionCallCounts.Transit.Add(transitCount)
// TODO: Update Transform call counts (VAULT-41205)
transitCount := c.consumptionBilling.DataProtectionCallCounts.Transit.Swap(0) + storedTransitCount
err = c.storeDataProtectionCallCountsLocked(ctx, storedDataProtectionCallCounts, billing.LocalPrefix, currentMonth)
err = c.storeTransitCallCountsLocked(ctx, transitCount, billing.LocalPrefix, currentMonth)
if err != nil {
return nil, err
return 0, err
}
return storedDataProtectionCallCounts, nil
return transitCount, nil
}
func (c *Core) storeKmipEnabledLocked(ctx context.Context, localPathPrefix string, currentMonth time.Time, kmipEnabled bool) error {

View file

@ -0,0 +1,20 @@
//go:build !enterprise
// Copyright IBM Corp. 2016, 2025
// SPDX-License-Identifier: MPL-2.0
package vault
import (
"context"
"time"
)
func (c *Core) UpdateTransformCallCounts(ctx context.Context, currentMonth time.Time) (uint64, error) {
// No-op in OSS
return 0, nil
}
func (c *Core) GetStoredTransformCallCounts(ctx context.Context, month time.Time) (uint64, error) {
return 0, nil
}

View file

@ -398,8 +398,8 @@ func TestHWMKvSecretsCounts(t *testing.T) {
require.Equal(t, 5, counts)
}
// TestDataProtectionCallCounts tests that we correctly store and track the data protection call counts
func TestDataProtectionCallCounts(t *testing.T) {
// TestTransitDataProtectionCallCounts tests that we correctly store and track the transit data protection call counts
func TestTransitDataProtectionCallCounts(t *testing.T) {
t.Parallel()
coreConfig := &CoreConfig{
LogicalBackends: map[string]logical.Factory{
@ -568,19 +568,17 @@ func TestDataProtectionCallCounts(t *testing.T) {
// Now test persisting the summed counts - store and retrieve counts
// First, update the data protection call counts (this will sum current counter with stored value)
summedCounts, err := core.UpdateDataProtectionCallCounts(ctx, time.Now())
summedCounts, err := core.UpdateTransitCallCounts(ctx, time.Now())
require.NoError(t, err)
require.NotNil(t, summedCounts)
require.Equal(t, currentCount, summedCounts.Transit.Load())
require.Equal(t, currentCount, summedCounts)
// Verify the counter was reset after update
require.Equal(t, uint64(0), core.GetInMemoryTransitDataProtectionCallCounts(), "Counter should be reset after update")
// Retrieve the stored counts
storedCounts, err := core.GetStoredDataProtectionCallCounts(ctx, time.Now())
storedCounts, err := core.GetStoredTransitCallCounts(ctx, time.Now())
require.NoError(t, err)
require.NotNil(t, storedCounts)
require.Equal(t, currentCount, storedCounts.Transit.Load())
require.Equal(t, currentCount, storedCounts)
// Perform more operations to increase the counter
req = logical.TestRequest(t, logical.UpdateOperation, "transit/encrypt/foo")
@ -593,18 +591,18 @@ func TestDataProtectionCallCounts(t *testing.T) {
require.Equal(t, uint64(1), core.GetInMemoryTransitDataProtectionCallCounts())
// Update counts again - should sum the new count (1) with the stored count (currentCount)
summedCounts, err = core.UpdateDataProtectionCallCounts(ctx, time.Now())
summedCounts, err = core.UpdateTransitCallCounts(ctx, time.Now())
require.NoError(t, err)
expectedSum := currentCount + 1
require.Equal(t, expectedSum, summedCounts.Transit.Load(), "Count should be sum of stored and current")
require.Equal(t, expectedSum, summedCounts, "Count should be sum of stored and current")
// Verify the counter was reset after update
require.Equal(t, uint64(0), core.GetInMemoryTransitDataProtectionCallCounts(), "Counter should be reset after update")
// Verify stored counts are now the sum
storedCounts, err = core.GetStoredDataProtectionCallCounts(ctx, time.Now())
storedCounts, err = core.GetStoredTransitCallCounts(ctx, time.Now())
require.NoError(t, err)
require.Equal(t, expectedSum, storedCounts.Transit.Load())
require.Equal(t, expectedSum, storedCounts)
// Add more operations without manually resetting
for i := 0; i < 3; i++ {
@ -619,29 +617,29 @@ func TestDataProtectionCallCounts(t *testing.T) {
require.Equal(t, uint64(3), core.GetInMemoryTransitDataProtectionCallCounts())
// Update counts - should sum 3 with the previous stored sum
summedCounts, err = core.UpdateDataProtectionCallCounts(ctx, time.Now())
summedCounts, err = core.UpdateTransitCallCounts(ctx, time.Now())
require.NoError(t, err)
expectedSum = expectedSum + 3
require.Equal(t, expectedSum, summedCounts.Transit.Load(), "Count should continue to sum")
require.Equal(t, expectedSum, summedCounts, "Count should continue to sum")
// Verify the counter was reset after update
require.Equal(t, uint64(0), core.GetInMemoryTransitDataProtectionCallCounts(), "Counter should be reset after update")
// Verify stored counts
storedCounts, err = core.GetStoredDataProtectionCallCounts(ctx, time.Now())
storedCounts, err = core.GetStoredTransitCallCounts(ctx, time.Now())
require.NoError(t, err)
require.Equal(t, expectedSum, storedCounts.Transit.Load())
require.Equal(t, expectedSum, storedCounts)
// Update again without any new operations
// This verifies we don't double-count
summedCounts, err = core.UpdateDataProtectionCallCounts(ctx, time.Now())
summedCounts, err = core.UpdateTransitCallCounts(ctx, time.Now())
require.NoError(t, err)
require.Equal(t, expectedSum, summedCounts.Transit.Load(), "Count should remain the same when no new operations occurred")
require.Equal(t, expectedSum, summedCounts, "Count should remain the same when no new operations occurred")
// Verify stored counts haven't changed
storedCounts, err = core.GetStoredDataProtectionCallCounts(ctx, time.Now())
storedCounts, err = core.GetStoredTransitCallCounts(ctx, time.Now())
require.NoError(t, err)
require.Equal(t, expectedSum, storedCounts.Transit.Load(), "Stored count should remain the same")
require.Equal(t, expectedSum, storedCounts, "Stored count should remain the same")
// Verify counter is still at 0
require.Equal(t, uint64(0), core.GetInMemoryTransitDataProtectionCallCounts(), "Counter should still be 0")

View file

@ -87,7 +87,7 @@ func (b *SystemBackend) handleUseCaseConsumption(ctx context.Context, req *logic
// Data protection call counts are stored to local path only
// Each cluster tracks its own total requests to avoid double counting
localDataProtectionCallCounts, err := b.Core.UpdateDataProtectionCallCounts(ctx, currentMonth)
localDataProtectionCallCounts, err := b.Core.UpdateTransitCallCounts(ctx, currentMonth)
if err != nil {
return nil, fmt.Errorf("error retrieving local max data protection call counts: %w", err)
}
@ -121,7 +121,7 @@ func (b *SystemBackend) handleUseCaseConsumption(ctx context.Context, req *logic
}
// Data protection counts for previous month
localPreviousMonthDataProtectionCallCounts, err := b.Core.GetStoredDataProtectionCallCounts(ctx, previousMonth)
localPreviousMonthTransitCallCounts, err := b.Core.GetStoredTransitCallCounts(ctx, previousMonth)
if err != nil {
return nil, fmt.Errorf("error retrieving local max data protection call counts for previous month: %w", err)
}
@ -129,7 +129,7 @@ func (b *SystemBackend) handleUseCaseConsumption(ctx context.Context, req *logic
combinedPreviousMonthRoleCounts := combineRoleCounts(replicatedPreviousMonthRoleCounts, localPreviousMonthRoleCounts)
combinedPreviousMonthKvHWMCounts := replicatedPreviousMonthKvHWMCounts + localPreviousMonthKvHWMCounts
// Data protection counts are not combined - each cluster reports its own total
combinedPreviousMonthDataProtectionCallCounts := localPreviousMonthDataProtectionCallCounts
combinedPreviousMonthTransitCallCounts := localPreviousMonthTransitCallCounts
resp := map[string]interface{}{
"current_month": map[string]interface{}{
@ -139,10 +139,11 @@ func (b *SystemBackend) handleUseCaseConsumption(ctx context.Context, req *logic
"data_protection_call_counts": combinedMaxDataProtectionCallCounts,
},
"previous_month": map[string]interface{}{
"timestamp": previousMonth,
"maximum_role_counts": combinedPreviousMonthRoleCounts,
"maximum_kv_counts": combinedPreviousMonthKvHWMCounts,
"data_protection_call_counts": combinedPreviousMonthDataProtectionCallCounts,
"timestamp": previousMonth,
"maximum_role_counts": combinedPreviousMonthRoleCounts,
"maximum_kv_counts": combinedPreviousMonthKvHWMCounts,
// TODO: Add transform data protection call counts
"data_protection_call_counts": combinedPreviousMonthTransitCallCounts,
},
}