vault/api/sys_billing_test.go
Vault Automation d34cb72e68
Add counting for SSH certs and OTPs (#12368) (#12755)
* add cert counting for ssh

* add system view and fix errors

* add otp counting and change units for certs

* add storage tests

* fix census errors

* run make fmt

* use incrementer and change storage to match rfc

* run make fmt

* fix interface and remove parameter

* fix errors

* Update builtin/logical/ssh/path_creds_create.go



* remove error check

* add ssh counts to billing endpoint

* fix error

* add test case

* add ssh metric to test

* add get functions and tests

* fix format

* create function for ssh metrics

* refactoring and add test cases

* replace test check

* add ssh to billing overview test

---------

Co-authored-by: Rachel Culpepper <84159930+rculpepper@users.noreply.github.com>
Co-authored-by: Victor Rodriguez Rizo <vrizo@hashicorp.com>
2026-03-11 10:30:48 -04:00

244 lines
6.4 KiB
Go

// Copyright IBM Corp. 2016, 2025
// SPDX-License-Identifier: MPL-2.0
package api
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/require"
)
// TestSys_BillingOverview tests the BillingOverview API client method and structure of the response
func TestSys_BillingOverview(t *testing.T) {
mockVaultServer := httptest.NewServer(http.HandlerFunc(mockVaultBillingHandler))
defer mockVaultServer.Close()
// Create API client pointing to mock server
cfg := DefaultConfig()
cfg.Address = mockVaultServer.URL
client, err := NewClient(cfg)
require.NoError(t, err)
resp, err := client.Sys().BillingOverview(false)
require.NoError(t, err)
require.NotNil(t, resp)
// Verify we have 2 months (current and previous)
require.Len(t, resp.Months, 2)
// Verify current month structure
currentMonth := resp.Months[0]
require.Equal(t, "2026-01", currentMonth.Month)
require.Equal(t, "2026-01-14T10:49:00Z", currentMonth.UpdatedAt)
require.Len(t, currentMonth.UsageMetrics, 9, "should have all 9 metrics")
// Create a map to verify all expected metrics are present
metricsMap := make(map[string]UsageMetric)
for _, metric := range currentMonth.UsageMetrics {
metricsMap[metric.MetricName] = metric
}
// Verify all expected metrics are present
expectedMetrics := []string{
"static_secrets",
"dynamic_roles",
"auto_rotated_roles",
"kmip",
"external_plugins",
"data_protection_calls",
"pki_units",
"managed_keys",
"ssh_units",
}
for _, metricName := range expectedMetrics {
metric, exists := metricsMap[metricName]
require.True(t, exists, "metric %s should be present", metricName)
require.NotNil(t, metric.MetricData, "metric_data should not be nil for %s", metricName)
}
// Verify specific metric structures
staticSecretsMetric := metricsMap["static_secrets"]
require.Contains(t, staticSecretsMetric.MetricData, "total")
require.Contains(t, staticSecretsMetric.MetricData, "metric_details")
kmipMetric := metricsMap["kmip"]
require.Contains(t, kmipMetric.MetricData, "used_in_month")
require.Equal(t, true, kmipMetric.MetricData["used_in_month"])
pkiMetric := metricsMap["pki_units"]
require.Contains(t, pkiMetric.MetricData, "total")
managedKeysMetric := metricsMap["managed_keys"]
require.Contains(t, managedKeysMetric.MetricData, "total")
require.Contains(t, managedKeysMetric.MetricData, "metric_details")
// Verify previous month structure
previousMonth := resp.Months[1]
require.Equal(t, "2025-12", previousMonth.Month)
require.Equal(t, "2025-12-31T23:59:59Z", previousMonth.UpdatedAt)
require.Len(t, previousMonth.UsageMetrics, 1)
// Verify external_plugins metric in previous month
externalPluginsMetric := previousMonth.UsageMetrics[0]
require.Equal(t, "external_plugins", externalPluginsMetric.MetricName)
require.NotNil(t, externalPluginsMetric.MetricData)
require.Contains(t, externalPluginsMetric.MetricData, "total")
sshMetric := metricsMap["ssh_units"]
require.Contains(t, sshMetric.MetricData, "total")
require.Contains(t, sshMetric.MetricData, "metric_details")
}
func mockVaultBillingHandler(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(billingOverviewResponse))
}
const billingOverviewResponse = `{
"request_id": "d8d3e6e1-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"lease_id": "",
"renewable": false,
"lease_duration": 0,
"data": {
"months": [
{
"month": "2026-01",
"updated_at": "2026-01-14T10:49:00Z",
"usage_metrics": [
{
"metric_name": "static_secrets",
"metric_data": {
"total": 10,
"metric_details": [
{
"type": "kv",
"count": 10
}
]
}
},
{
"metric_name": "dynamic_roles",
"metric_data": {
"total": 15,
"metric_details": [
{
"type": "aws_dynamic",
"count": 5
},
{
"type": "azure_dynamic",
"count": 5
},
{
"type": "database_dynamic",
"count": 5
}
]
}
},
{
"metric_name": "auto_rotated_roles",
"metric_data": {
"total": 10,
"metric_details": [
{
"type": "aws_static",
"count": 5
},
{
"type": "azure_static",
"count": 5
}
]
}
},
{
"metric_name": "kmip",
"metric_data": {
"used_in_month": true
}
},
{
"metric_name": "external_plugins",
"metric_data": {
"total": 3
}
},
{
"metric_name": "data_protection_calls",
"metric_data": {
"total": 100,
"metric_details": [
{
"type": "transit",
"count": 50
},
{
"type": "transform",
"count": 50
}
]
}
},
{
"metric_name": "pki_units",
"metric_data": {
"total": 100.5
}
},
{
"metric_name": "managed_keys",
"metric_data": {
"total": 10,
"metric_details": [
{
"type": "totp",
"count": 5
},
{
"type": "kmse",
"count": 5
}
]
}
},
{
"metric_name": "ssh_units",
"metric_data": {
"total": 8.4,
"metric_details": [
{
"type": "otp_units",
"count": 5
},
{
"type": "certificate_units",
"count": 3.4
}
]
}
}
]
},
{
"month": "2025-12",
"updated_at": "2025-12-31T23:59:59Z",
"usage_metrics": [
{
"metric_name": "external_plugins",
"metric_data": {
"total": 5
}
}
]
}
]
},
"wrap_info": null,
"warnings": null,
"auth": null
}`