mirror of
https://github.com/hashicorp/vault.git
synced 2026-06-09 08:55:13 -04:00
Backport [VAULT-41316] Consumption billing external CA cert units into release/2.x.x+ent into ce/release/2.x.x (#14805)
* no-op commit * add external ca cert billing * add changelog * add another test --------- Co-authored-by: Jenny Deng <jenny.deng@hashicorp.com>
This commit is contained in:
parent
75523ed702
commit
8e2f967a98
8 changed files with 91 additions and 1 deletions
3
changelog/_14685.txt
Normal file
3
changelog/_14685.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
```release-note:improvement
|
||||
consumption-billing: Added consumption billing metrics for PKI External CA certificates.
|
||||
```
|
||||
|
|
@ -39,6 +39,7 @@ const (
|
|||
SSHCertificateMetric = "ssh/normalized-certs-issued"
|
||||
SSHOTPMetric = "ssh/credential-count"
|
||||
OidcDurationAdjustedCountPrefix = "oidcNormalizedTokenUnits/"
|
||||
ExternalCaDurationAdjustedCountPrefix = "externalCaNormalizedCertsIssued/"
|
||||
|
||||
BillingWriteInterval = 10 * time.Minute
|
||||
// pluginCountsSendTimeout is the timeout for sending plugin counts to the active node
|
||||
|
|
@ -62,6 +63,9 @@ type ConsumptionBilling struct {
|
|||
KmipSeenEnabledThisMonth atomic.Bool
|
||||
|
||||
IdentityTokenUnits IdentityTokenUnits
|
||||
|
||||
// ExternalCaCertUnits tracks duration-adjusted PKI external CA certificate units
|
||||
ExternalCaCertUnits *uberatomic.Float64
|
||||
}
|
||||
|
||||
type BillingConfig struct {
|
||||
|
|
@ -145,6 +149,15 @@ func (s *ConsumptionBilling) WriteBillingData(ctx context.Context, mountType str
|
|||
}
|
||||
|
||||
s.DataProtectionCallCounts.GcpKms.Add(val)
|
||||
case "external-ca":
|
||||
// External CA uses float64 for duration-adjusted units
|
||||
val, ok := data["units"].(float64)
|
||||
if !ok {
|
||||
err := fmt.Errorf("invalid value type for external-ca")
|
||||
return err
|
||||
}
|
||||
|
||||
s.ExternalCaCertUnits.Add(val)
|
||||
default:
|
||||
err := fmt.Errorf("unknown metric type: %s", mountType)
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ func (c *Core) setupConsumptionBilling(ctx context.Context) error {
|
|||
OidcTokenDuration: uberAtomic.NewFloat64(0),
|
||||
SpiffeJwt: uberAtomic.NewFloat64(0),
|
||||
},
|
||||
Logger: logger,
|
||||
ExternalCaCertUnits: uberAtomic.NewFloat64(0),
|
||||
Logger: logger,
|
||||
}
|
||||
if c.systemBarrierView != nil {
|
||||
c.consumptionBillingSubView = c.systemBarrierView.SubView(billing.BillingSubPath)
|
||||
|
|
@ -186,6 +187,7 @@ func (c *Core) resetInMemoryBillingMetrics() error {
|
|||
c.consumptionBilling.DataProtectionCallCounts.GcpKms.Store(0)
|
||||
c.consumptionBilling.KmipSeenEnabledThisMonth.Store(false)
|
||||
c.consumptionBilling.IdentityTokenUnits.OidcTokenDuration.Store(0)
|
||||
c.consumptionBilling.ExternalCaCertUnits.Store(0)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -294,5 +296,8 @@ func (c *Core) UpdateLocalAggregatedMetrics(ctx context.Context, currentMonth ti
|
|||
if _, err := c.UpdateGcpKmsCallCounts(ctx, currentMonth); err != nil {
|
||||
return fmt.Errorf("could not store GCP KMS data protection call counts: %w", err)
|
||||
}
|
||||
if _, err := c.UpdateExternalCaCertUnits(ctx, currentMonth); err != nil {
|
||||
return fmt.Errorf("could not store external CA certificate units: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -248,3 +248,34 @@ func CreateMockOSHost(ctx context.Context, storage logical.Storage, hostName str
|
|||
func DeleteMockOSHost(ctx context.Context, storage logical.Storage, hostName string) error {
|
||||
return storage.Delete(ctx, "hosts/"+hostName)
|
||||
}
|
||||
|
||||
func (c *Core) ResetInMemoryExternalCaCertUnits() {
|
||||
c.consumptionBillingLock.RLock()
|
||||
cb := c.consumptionBilling
|
||||
c.consumptionBillingLock.RUnlock()
|
||||
|
||||
if cb != nil {
|
||||
cb.ExternalCaCertUnits.Store(0)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Core) GetInMemoryExternalCaCertUnits() float64 {
|
||||
c.consumptionBillingLock.RLock()
|
||||
cb := c.consumptionBilling
|
||||
c.consumptionBillingLock.RUnlock()
|
||||
|
||||
if cb != nil {
|
||||
return cb.ExternalCaCertUnits.Load()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *Core) SetInMemoryExternalCaCertUnits(count float64) {
|
||||
c.consumptionBillingLock.RLock()
|
||||
cb := c.consumptionBilling
|
||||
c.consumptionBillingLock.RUnlock()
|
||||
|
||||
if cb != nil {
|
||||
cb.ExternalCaCertUnits.Store(count)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,3 +28,13 @@ func (c *Core) UpdateSpiffeJwtTokenUnits(ctx context.Context, currentMonth time.
|
|||
// No-op in OSS
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (c *Core) GetStoredExternalCaCertUnits(ctx context.Context, currentMonth time.Time) (float64, error) {
|
||||
// No-op in OSS
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (c *Core) UpdateExternalCaCertUnits(ctx context.Context, currentMonth time.Time) (float64, error) {
|
||||
// No-op in OSS
|
||||
return 0, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@ func Test_BillingOverview_EmptyCluster(t *testing.T) {
|
|||
"managed_keys": false,
|
||||
"ssh_units": false,
|
||||
"id_token_units": false,
|
||||
"external_ca_pki_units": false,
|
||||
}
|
||||
|
||||
for _, metric := range currentMonth.UsageMetrics {
|
||||
|
|
|
|||
|
|
@ -287,6 +287,12 @@ func (b *SystemBackend) buildMonthBillingData(ctx context.Context, month time.Ti
|
|||
}
|
||||
usageMetrics = append(usageMetrics, idTokenUnitsMetric)
|
||||
|
||||
externalCaMetric, err := b.buildExternalCaBillingMetric(ctx, month)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
usageMetrics = append(usageMetrics, externalCaMetric)
|
||||
|
||||
// Round all float64 values in usageMetrics to 4 decimal places.
|
||||
// Rounding time for usage metrics is insignificant, so we can keep it centralized here.
|
||||
// This prevents us from having to do it in each individual metric.
|
||||
|
|
@ -519,6 +525,21 @@ func (b *SystemBackend) buildIdTokenUnitsBillingMetric(ctx context.Context, mont
|
|||
}, nil
|
||||
}
|
||||
|
||||
// buildExternalCaBillingMetric creates the billing metric for external CA certificate counts.
|
||||
func (b *SystemBackend) buildExternalCaBillingMetric(ctx context.Context, month time.Time) (map[string]interface{}, error) {
|
||||
count, err := b.Core.GetStoredExternalCaCertUnits(ctx, month)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error retrieving external CA certificate units for month: %w", err)
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"metric_name": "external_ca_pki_units",
|
||||
"metric_data": map[string]interface{}{
|
||||
"total": count,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// getRoleCounts retrieves and combines role and managed key counts from replicated and local storage
|
||||
func (c *Core) getRoleAndManagedKeyCounts(ctx context.Context, month time.Time) (*RoleCounts, *ManagedKeyCounts, error) {
|
||||
var replicatedRoleCounts *RoleCounts
|
||||
|
|
|
|||
|
|
@ -769,6 +769,7 @@ func TestSystemBackend_BillingOverview_EmptyMetrics(t *testing.T) {
|
|||
"managed_keys": false,
|
||||
"ssh_units": false,
|
||||
"id_token_units": false,
|
||||
"external_ca_pki_units": false,
|
||||
}
|
||||
|
||||
for _, metric := range usageMetrics {
|
||||
|
|
@ -888,6 +889,11 @@ func TestSystemBackend_BillingOverview_EmptyMetrics(t *testing.T) {
|
|||
for typeName, found := range expectedTypes {
|
||||
require.True(t, found, "type %s should be present", typeName)
|
||||
}
|
||||
|
||||
case "external_ca_pki_units":
|
||||
total, ok := metricData["total"].(float64)
|
||||
require.True(t, ok, "external_ca_pki_units total should be float64")
|
||||
require.Equal(t, float64(0), total, "external_ca_pki_units total should be 0")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue