mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-05 12:26:34 +02:00
Merge remote-tracking branch 'remotes/from/ce/main'
This commit is contained in:
commit
132ad9c2e0
@ -151,9 +151,8 @@ func (b *SystemBackend) buildMonthBillingData(ctx context.Context, month time.Ti
|
||||
// Build the usage metrics
|
||||
usageMetrics := []map[string]interface{}{}
|
||||
|
||||
kvDetails := []map[string]interface{}{}
|
||||
if combinedKvCounts > 0 {
|
||||
kvDetails = append(kvDetails, map[string]interface{}{"type": "kv", "count": combinedKvCounts})
|
||||
kvDetails := []map[string]interface{}{
|
||||
{"type": "kv", "count": combinedKvCounts},
|
||||
}
|
||||
usageMetrics = append(usageMetrics, map[string]interface{}{
|
||||
"metric_name": "static_secrets",
|
||||
@ -181,15 +180,10 @@ func (b *SystemBackend) buildMonthBillingData(ctx context.Context, month time.Ti
|
||||
},
|
||||
})
|
||||
|
||||
dataProtectionDetails := []map[string]interface{}{}
|
||||
if transitCounts > 0 {
|
||||
dataProtectionDetails = append(dataProtectionDetails, map[string]interface{}{"type": "transit", "count": transitCounts})
|
||||
}
|
||||
if transformCounts > 0 {
|
||||
dataProtectionDetails = append(dataProtectionDetails, map[string]interface{}{"type": "transform", "count": transformCounts})
|
||||
}
|
||||
if gcpKmsCounts > 0 {
|
||||
dataProtectionDetails = append(dataProtectionDetails, map[string]interface{}{"type": "gcpkms", "count": gcpKmsCounts})
|
||||
dataProtectionDetails := []map[string]interface{}{
|
||||
{"type": "transit", "count": transitCounts},
|
||||
{"type": "transform", "count": transformCounts},
|
||||
{"type": "gcpkms", "count": gcpKmsCounts},
|
||||
}
|
||||
|
||||
usageMetrics = append(usageMetrics, map[string]interface{}{
|
||||
@ -206,12 +200,9 @@ func (b *SystemBackend) buildMonthBillingData(ctx context.Context, month time.Ti
|
||||
}
|
||||
usageMetrics = append(usageMetrics, pkiMetric)
|
||||
|
||||
managedKeysDetails := []map[string]interface{}{}
|
||||
if combinedManagedKeyCounts.TotpKeys > 0 {
|
||||
managedKeysDetails = append(managedKeysDetails, map[string]interface{}{"type": "totp", "count": combinedManagedKeyCounts.TotpKeys})
|
||||
}
|
||||
if combinedManagedKeyCounts.KmseKeys > 0 {
|
||||
managedKeysDetails = append(managedKeysDetails, map[string]interface{}{"type": "kmse", "count": combinedManagedKeyCounts.KmseKeys})
|
||||
managedKeysDetails := []map[string]interface{}{
|
||||
{"type": "totp", "count": combinedManagedKeyCounts.TotpKeys},
|
||||
{"type": "kmse", "count": combinedManagedKeyCounts.KmseKeys},
|
||||
}
|
||||
usageMetrics = append(usageMetrics, map[string]interface{}{
|
||||
"metric_name": "managed_keys",
|
||||
@ -281,63 +272,54 @@ func (c *Core) computeUpdatedAt(ctx context.Context, month, currentMonth time.Ti
|
||||
// buildDynamicRolesMetric creates the dynamic_roles metric from role counts.
|
||||
func buildDynamicRolesMetric(counts *RoleCounts) map[string]interface{} {
|
||||
total := 0
|
||||
awsCount := 0
|
||||
azureCount := 0
|
||||
databaseCount := 0
|
||||
gcpCount := 0
|
||||
ldapCount := 0
|
||||
openldapCount := 0
|
||||
alicloudCount := 0
|
||||
rabbitmqCount := 0
|
||||
consulCount := 0
|
||||
nomadCount := 0
|
||||
kubernetesCount := 0
|
||||
mongodbatlasCount := 0
|
||||
terraformCount := 0
|
||||
|
||||
if counts != nil {
|
||||
total = counts.AWSDynamicRoles +
|
||||
counts.AzureDynamicRoles +
|
||||
counts.DatabaseDynamicRoles +
|
||||
counts.GCPRolesets +
|
||||
counts.LDAPDynamicRoles +
|
||||
counts.OpenLDAPDynamicRoles +
|
||||
counts.AlicloudDynamicRoles +
|
||||
counts.RabbitMQDynamicRoles +
|
||||
counts.ConsulDynamicRoles +
|
||||
counts.NomadDynamicRoles +
|
||||
counts.KubernetesDynamicRoles +
|
||||
counts.MongoDBAtlasDynamicRoles +
|
||||
counts.TerraformCloudDynamicRoles
|
||||
awsCount = counts.AWSDynamicRoles
|
||||
azureCount = counts.AzureDynamicRoles
|
||||
databaseCount = counts.DatabaseDynamicRoles
|
||||
gcpCount = counts.GCPRolesets
|
||||
ldapCount = counts.LDAPDynamicRoles
|
||||
openldapCount = counts.OpenLDAPDynamicRoles
|
||||
alicloudCount = counts.AlicloudDynamicRoles
|
||||
rabbitmqCount = counts.RabbitMQDynamicRoles
|
||||
consulCount = counts.ConsulDynamicRoles
|
||||
nomadCount = counts.NomadDynamicRoles
|
||||
kubernetesCount = counts.KubernetesDynamicRoles
|
||||
mongodbatlasCount = counts.MongoDBAtlasDynamicRoles
|
||||
terraformCount = counts.TerraformCloudDynamicRoles
|
||||
|
||||
total = awsCount + azureCount + databaseCount + gcpCount + ldapCount +
|
||||
openldapCount + alicloudCount + rabbitmqCount + consulCount +
|
||||
nomadCount + kubernetesCount + mongodbatlasCount + terraformCount
|
||||
}
|
||||
|
||||
details := []map[string]interface{}{}
|
||||
if counts != nil {
|
||||
if counts.AWSDynamicRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "aws_dynamic", "count": counts.AWSDynamicRoles})
|
||||
}
|
||||
if counts.AzureDynamicRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "azure_dynamic", "count": counts.AzureDynamicRoles})
|
||||
}
|
||||
if counts.DatabaseDynamicRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "database_dynamic", "count": counts.DatabaseDynamicRoles})
|
||||
}
|
||||
if counts.GCPRolesets > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "gcp_dynamic", "count": counts.GCPRolesets})
|
||||
}
|
||||
if counts.LDAPDynamicRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "ldap_dynamic", "count": counts.LDAPDynamicRoles})
|
||||
}
|
||||
if counts.OpenLDAPDynamicRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "openldap_dynamic", "count": counts.OpenLDAPDynamicRoles})
|
||||
}
|
||||
if counts.AlicloudDynamicRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "alicloud_dynamic", "count": counts.AlicloudDynamicRoles})
|
||||
}
|
||||
if counts.RabbitMQDynamicRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "rabbitmq_dynamic", "count": counts.RabbitMQDynamicRoles})
|
||||
}
|
||||
if counts.ConsulDynamicRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "consul_dynamic", "count": counts.ConsulDynamicRoles})
|
||||
}
|
||||
if counts.NomadDynamicRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "nomad_dynamic", "count": counts.NomadDynamicRoles})
|
||||
}
|
||||
if counts.KubernetesDynamicRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "kubernetes_dynamic", "count": counts.KubernetesDynamicRoles})
|
||||
}
|
||||
if counts.MongoDBAtlasDynamicRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "mongodbatlas_dynamic", "count": counts.MongoDBAtlasDynamicRoles})
|
||||
}
|
||||
if counts.TerraformCloudDynamicRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "terraform_dynamic", "count": counts.TerraformCloudDynamicRoles})
|
||||
}
|
||||
details := []map[string]interface{}{
|
||||
{"type": "aws_dynamic", "count": awsCount},
|
||||
{"type": "azure_dynamic", "count": azureCount},
|
||||
{"type": "database_dynamic", "count": databaseCount},
|
||||
{"type": "gcp_dynamic", "count": gcpCount},
|
||||
{"type": "ldap_dynamic", "count": ldapCount},
|
||||
{"type": "openldap_dynamic", "count": openldapCount},
|
||||
{"type": "alicloud_dynamic", "count": alicloudCount},
|
||||
{"type": "rabbitmq_dynamic", "count": rabbitmqCount},
|
||||
{"type": "consul_dynamic", "count": consulCount},
|
||||
{"type": "nomad_dynamic", "count": nomadCount},
|
||||
{"type": "kubernetes_dynamic", "count": kubernetesCount},
|
||||
{"type": "mongodbatlas_dynamic", "count": mongodbatlasCount},
|
||||
{"type": "terraform_dynamic", "count": terraformCount},
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
@ -352,39 +334,35 @@ func buildDynamicRolesMetric(counts *RoleCounts) map[string]interface{} {
|
||||
// buildAutoRotatedRolesMetric creates the auto_rotated_roles metric from role counts.
|
||||
func buildAutoRotatedRolesMetric(counts *RoleCounts) map[string]interface{} {
|
||||
total := 0
|
||||
awsCount := 0
|
||||
azureCount := 0
|
||||
databaseCount := 0
|
||||
gcpStaticCount := 0
|
||||
gcpImpersonatedCount := 0
|
||||
ldapCount := 0
|
||||
openldapCount := 0
|
||||
|
||||
if counts != nil {
|
||||
total = counts.AWSStaticRoles +
|
||||
counts.AzureStaticRoles +
|
||||
counts.DatabaseStaticRoles +
|
||||
counts.GCPStaticAccounts +
|
||||
counts.GCPImpersonatedAccounts +
|
||||
counts.LDAPStaticRoles +
|
||||
counts.OpenLDAPStaticRoles
|
||||
awsCount = counts.AWSStaticRoles
|
||||
azureCount = counts.AzureStaticRoles
|
||||
databaseCount = counts.DatabaseStaticRoles
|
||||
gcpStaticCount = counts.GCPStaticAccounts
|
||||
gcpImpersonatedCount = counts.GCPImpersonatedAccounts
|
||||
ldapCount = counts.LDAPStaticRoles
|
||||
openldapCount = counts.OpenLDAPStaticRoles
|
||||
|
||||
total = awsCount + azureCount + databaseCount + gcpStaticCount +
|
||||
gcpImpersonatedCount + ldapCount + openldapCount
|
||||
}
|
||||
|
||||
details := []map[string]interface{}{}
|
||||
if counts != nil {
|
||||
if counts.AWSStaticRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "aws_static", "count": counts.AWSStaticRoles})
|
||||
}
|
||||
if counts.AzureStaticRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "azure_static", "count": counts.AzureStaticRoles})
|
||||
}
|
||||
if counts.DatabaseStaticRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "database_static", "count": counts.DatabaseStaticRoles})
|
||||
}
|
||||
if counts.GCPStaticAccounts > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "gcp_static", "count": counts.GCPStaticAccounts})
|
||||
}
|
||||
if counts.GCPImpersonatedAccounts > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "gcp_impersonated", "count": counts.GCPImpersonatedAccounts})
|
||||
}
|
||||
if counts.LDAPStaticRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "ldap_static", "count": counts.LDAPStaticRoles})
|
||||
}
|
||||
if counts.OpenLDAPStaticRoles > 0 {
|
||||
details = append(details, map[string]interface{}{"type": "openldap_static", "count": counts.OpenLDAPStaticRoles})
|
||||
}
|
||||
details := []map[string]interface{}{
|
||||
{"type": "aws_static", "count": awsCount},
|
||||
{"type": "azure_static", "count": azureCount},
|
||||
{"type": "database_static", "count": databaseCount},
|
||||
{"type": "gcp_static", "count": gcpStaticCount},
|
||||
{"type": "gcp_impersonated", "count": gcpImpersonatedCount},
|
||||
{"type": "ldap_static", "count": ldapCount},
|
||||
{"type": "openldap_static", "count": openldapCount},
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
@ -415,16 +393,11 @@ func (b *SystemBackend) buildPkiBillingMetric(ctx context.Context, month time.Ti
|
||||
func (b *SystemBackend) buildIdTokenUnitsBillingMetric(ctx context.Context, month time.Time) (map[string]interface{}, error) {
|
||||
var totalTokens float64
|
||||
|
||||
idTokenDetails := []map[string]interface{}{}
|
||||
oidcTokenCount, err := b.Core.GetStoredOidcDurationAdjustedCount(ctx, month)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error retrieving OIDC duration-adjusted token count for month: %w", err)
|
||||
}
|
||||
|
||||
if oidcTokenCount > 0 {
|
||||
idTokenDetails = append(idTokenDetails, map[string]interface{}{"type": "oidc", "count": oidcTokenCount})
|
||||
}
|
||||
|
||||
totalTokens += oidcTokenCount
|
||||
|
||||
spiffeJwtUnits, err := b.Core.GetStoredSpiffeJwtTokenUnits(ctx, month)
|
||||
@ -432,12 +405,13 @@ func (b *SystemBackend) buildIdTokenUnitsBillingMetric(ctx context.Context, mont
|
||||
return nil, fmt.Errorf("error retrieving JWT Spiffe duration-adjusted token count for month: %w", err)
|
||||
}
|
||||
|
||||
if spiffeJwtUnits > 0 {
|
||||
idTokenDetails = append(idTokenDetails, map[string]interface{}{"type": "spiffe", "count": spiffeJwtUnits})
|
||||
}
|
||||
|
||||
totalTokens += spiffeJwtUnits
|
||||
|
||||
idTokenDetails := []map[string]interface{}{
|
||||
{"type": "oidc", "count": oidcTokenCount},
|
||||
{"type": "spiffe", "count": spiffeJwtUnits},
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"metric_name": "id_token_units",
|
||||
"metric_data": map[string]interface{}{
|
||||
|
||||
@ -618,14 +618,33 @@ func TestSystemBackend_BillingOverview_EmptyMetrics(t *testing.T) {
|
||||
|
||||
// Verify each metric has appropriate zero value
|
||||
switch metricName {
|
||||
case "static_secrets", "dynamic_roles", "auto_rotated_roles":
|
||||
case "static_secrets":
|
||||
total, ok := metricData["total"].(int)
|
||||
require.True(t, ok, "%s total should be int", metricName)
|
||||
require.Equal(t, 0, total, "%s total should be 0", metricName)
|
||||
|
||||
details, ok := metricData["metric_details"].([]map[string]interface{})
|
||||
require.True(t, ok, "%s metric_details should be array", metricName)
|
||||
require.Empty(t, details, "%s metric_details should be empty when total is 0", metricName)
|
||||
require.NotEmpty(t, details, "%s metric_details should always be present", metricName)
|
||||
// Verify kv type is present with zero count
|
||||
require.Len(t, details, 1)
|
||||
require.Equal(t, "kv", details[0]["type"])
|
||||
require.Equal(t, 0, details[0]["count"])
|
||||
|
||||
case "dynamic_roles", "auto_rotated_roles":
|
||||
total, ok := metricData["total"].(int)
|
||||
require.True(t, ok, "%s total should be int", metricName)
|
||||
require.Equal(t, 0, total, "%s total should be 0", metricName)
|
||||
|
||||
details, ok := metricData["metric_details"].([]map[string]interface{})
|
||||
require.True(t, ok, "%s metric_details should be array", metricName)
|
||||
require.NotEmpty(t, details, "%s metric_details should always be present", metricName)
|
||||
// Verify all role types are present with zero counts
|
||||
for _, detail := range details {
|
||||
require.Contains(t, detail, "type")
|
||||
require.Contains(t, detail, "count")
|
||||
require.Equal(t, 0, detail["count"])
|
||||
}
|
||||
|
||||
case "kmip":
|
||||
used, ok := metricData["used_in_month"].(bool)
|
||||
@ -644,7 +663,18 @@ func TestSystemBackend_BillingOverview_EmptyMetrics(t *testing.T) {
|
||||
|
||||
details, ok := metricData["metric_details"].([]map[string]interface{})
|
||||
require.True(t, ok, "data_protection_calls metric_details should be array")
|
||||
require.Empty(t, details, "data_protection_calls metric_details should be empty when total is 0")
|
||||
require.NotEmpty(t, details, "data_protection_calls metric_details should always be present")
|
||||
// Verify all data protection types are present with zero counts
|
||||
require.Len(t, details, 3)
|
||||
expectedTypes := map[string]bool{"transit": false, "transform": false, "gcpkms": false}
|
||||
for _, detail := range details {
|
||||
detailType := detail["type"].(string)
|
||||
expectedTypes[detailType] = true
|
||||
require.Equal(t, uint64(0), detail["count"])
|
||||
}
|
||||
for typeName, found := range expectedTypes {
|
||||
require.True(t, found, "type %s should be present", typeName)
|
||||
}
|
||||
|
||||
case "pki_units":
|
||||
total, ok := metricData["total"].(float64)
|
||||
@ -653,11 +683,22 @@ func TestSystemBackend_BillingOverview_EmptyMetrics(t *testing.T) {
|
||||
|
||||
case "managed_keys":
|
||||
total, ok := metricData["total"].(int)
|
||||
require.True(t, ok, "managed_keys total should be float64")
|
||||
require.True(t, ok, "managed_keys total should be int")
|
||||
require.Equal(t, int(0), total, "managed keys total should be 0")
|
||||
details, ok := metricData["metric_details"].([]map[string]interface{})
|
||||
require.True(t, ok, "%s metric_details should be array", metricName)
|
||||
require.Empty(t, details, "%s metric_details should be empty when total is 0", metricName)
|
||||
require.NotEmpty(t, details, "%s metric_details should always be present", metricName)
|
||||
// Verify both managed key types are present with zero counts
|
||||
require.Len(t, details, 2)
|
||||
expectedTypes := map[string]bool{"totp": false, "kmse": false}
|
||||
for _, detail := range details {
|
||||
detailType := detail["type"].(string)
|
||||
expectedTypes[detailType] = true
|
||||
require.Equal(t, 0, detail["count"])
|
||||
}
|
||||
for typeName, found := range expectedTypes {
|
||||
require.True(t, found, "type %s should be present", typeName)
|
||||
}
|
||||
|
||||
case "ssh_units":
|
||||
total, ok := metricData["total"].(float64)
|
||||
@ -668,6 +709,21 @@ func TestSystemBackend_BillingOverview_EmptyMetrics(t *testing.T) {
|
||||
total, ok := metricData["total"].(float64)
|
||||
require.True(t, ok, "id_token_units total should be float64")
|
||||
require.Equal(t, float64(0), total, "id_token_units total should be 0")
|
||||
|
||||
details, ok := metricData["metric_details"].([]map[string]interface{})
|
||||
require.True(t, ok, "id_token_units metric_details should be array")
|
||||
require.NotEmpty(t, details, "id_token_units metric_details should always be present")
|
||||
// Verify both token types are present with zero counts
|
||||
require.Len(t, details, 2)
|
||||
expectedTypes := map[string]bool{"oidc": false, "spiffe": false}
|
||||
for _, detail := range details {
|
||||
detailType := detail["type"].(string)
|
||||
expectedTypes[detailType] = true
|
||||
require.Equal(t, float64(0), detail["count"])
|
||||
}
|
||||
for typeName, found := range expectedTypes {
|
||||
require.True(t, found, "type %s should be present", typeName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -941,6 +997,135 @@ func TestSystemBackend_BillingOverview_UpdatedAtTimestamp_NoStoredTimestamp(t *t
|
||||
"previous month updated_at should be zero time when no stored timestamp exists")
|
||||
}
|
||||
|
||||
// TestSystemBackend_BillingOverview_AllMetricTypesPresent verifies that all metric types
|
||||
// are always present in the response, even when their counts are zero. This test specifically
|
||||
// validates that metric_details arrays contain all expected types for each metric category.
|
||||
func TestSystemBackend_BillingOverview_AllMetricTypesPresent(t *testing.T) {
|
||||
_, b, _ := testCoreSystemBackend(t)
|
||||
ctx := namespace.RootContext(nil)
|
||||
|
||||
// Make a request without creating any billable resources
|
||||
req := logical.TestRequest(t, logical.ReadOperation, "billing/overview")
|
||||
resp, err := b.HandleRequest(ctx, req)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resp)
|
||||
require.NotNil(t, resp.Data)
|
||||
|
||||
// Verify the response structure exists
|
||||
months, ok := resp.Data["months"].([]interface{})
|
||||
require.True(t, ok)
|
||||
require.Len(t, months, billing.BillingRetentionMonths)
|
||||
|
||||
// Check current month has all metrics
|
||||
currentMonth, ok := months[0].(map[string]interface{})
|
||||
require.True(t, ok)
|
||||
require.Contains(t, currentMonth, "usage_metrics")
|
||||
|
||||
usageMetrics, ok := currentMonth["usage_metrics"].([]map[string]interface{})
|
||||
require.True(t, ok)
|
||||
require.NotNil(t, usageMetrics)
|
||||
require.NotEmpty(t, usageMetrics, "usage_metrics should contain all metrics even with zero values")
|
||||
|
||||
// Build a map of metrics for easy lookup
|
||||
metricsMap := make(map[string]map[string]interface{})
|
||||
for _, metric := range usageMetrics {
|
||||
metricName, ok := metric["metric_name"].(string)
|
||||
require.True(t, ok, "metric_name should be a string")
|
||||
metricsMap[metricName] = metric
|
||||
}
|
||||
|
||||
// Verify static_secrets has kv type
|
||||
staticSecretsMetric, exists := metricsMap["static_secrets"]
|
||||
require.True(t, exists, "static_secrets metric should be present")
|
||||
staticSecretsData := staticSecretsMetric["metric_data"].(map[string]interface{})
|
||||
staticSecretsDetails := staticSecretsData["metric_details"].([]map[string]interface{})
|
||||
require.Len(t, staticSecretsDetails, 1, "static_secrets should have 1 type")
|
||||
require.Equal(t, "kv", staticSecretsDetails[0]["type"])
|
||||
require.Equal(t, 0, staticSecretsDetails[0]["count"])
|
||||
|
||||
// Verify dynamic_roles has all 13 types
|
||||
dynamicRolesMetric, exists := metricsMap["dynamic_roles"]
|
||||
require.True(t, exists, "dynamic_roles metric should be present")
|
||||
dynamicRolesData := dynamicRolesMetric["metric_data"].(map[string]interface{})
|
||||
dynamicRolesDetails := dynamicRolesData["metric_details"].([]map[string]interface{})
|
||||
require.Len(t, dynamicRolesDetails, 13, "dynamic_roles should have 13 types")
|
||||
|
||||
expectedDynamicTypes := []string{
|
||||
"aws_dynamic", "azure_dynamic", "database_dynamic", "gcp_dynamic",
|
||||
"ldap_dynamic", "openldap_dynamic", "alicloud_dynamic", "rabbitmq_dynamic",
|
||||
"consul_dynamic", "nomad_dynamic", "kubernetes_dynamic", "mongodbatlas_dynamic",
|
||||
"terraform_dynamic",
|
||||
}
|
||||
for i, expectedType := range expectedDynamicTypes {
|
||||
require.Equal(t, expectedType, dynamicRolesDetails[i]["type"], "dynamic role type at index %d should be %s", i, expectedType)
|
||||
require.Equal(t, 0, dynamicRolesDetails[i]["count"], "dynamic role count at index %d should be 0", i)
|
||||
}
|
||||
|
||||
// Verify auto_rotated_roles has all 7 types
|
||||
autoRotatedMetric, exists := metricsMap["auto_rotated_roles"]
|
||||
require.True(t, exists, "auto_rotated_roles metric should be present")
|
||||
autoRotatedData := autoRotatedMetric["metric_data"].(map[string]interface{})
|
||||
autoRotatedDetails := autoRotatedData["metric_details"].([]map[string]interface{})
|
||||
require.Len(t, autoRotatedDetails, 7, "auto_rotated_roles should have 7 types")
|
||||
|
||||
expectedAutoRotatedTypes := []string{
|
||||
"aws_static", "azure_static", "database_static", "gcp_static",
|
||||
"gcp_impersonated", "ldap_static", "openldap_static",
|
||||
}
|
||||
for i, expectedType := range expectedAutoRotatedTypes {
|
||||
require.Equal(t, expectedType, autoRotatedDetails[i]["type"], "auto-rotated role type at index %d should be %s", i, expectedType)
|
||||
require.Equal(t, 0, autoRotatedDetails[i]["count"], "auto-rotated role count at index %d should be 0", i)
|
||||
}
|
||||
|
||||
// Verify data_protection_calls has all 3 types
|
||||
dataProtectionMetric, exists := metricsMap["data_protection_calls"]
|
||||
require.True(t, exists, "data_protection_calls metric should be present")
|
||||
dataProtectionData := dataProtectionMetric["metric_data"].(map[string]interface{})
|
||||
dataProtectionDetails := dataProtectionData["metric_details"].([]map[string]interface{})
|
||||
require.Len(t, dataProtectionDetails, 3, "data_protection_calls should have 3 types")
|
||||
|
||||
expectedDataProtectionTypes := []string{"transit", "transform", "gcpkms"}
|
||||
for i, expectedType := range expectedDataProtectionTypes {
|
||||
require.Equal(t, expectedType, dataProtectionDetails[i]["type"], "data protection type at index %d should be %s", i, expectedType)
|
||||
require.Equal(t, uint64(0), dataProtectionDetails[i]["count"], "data protection count at index %d should be 0", i)
|
||||
}
|
||||
|
||||
// Verify managed_keys has both types
|
||||
managedKeysMetric, exists := metricsMap["managed_keys"]
|
||||
require.True(t, exists, "managed_keys metric should be present")
|
||||
managedKeysData := managedKeysMetric["metric_data"].(map[string]interface{})
|
||||
managedKeysDetails := managedKeysData["metric_details"].([]map[string]interface{})
|
||||
require.Len(t, managedKeysDetails, 2, "managed_keys should have 2 types")
|
||||
|
||||
expectedManagedKeyTypes := []string{"totp", "kmse"}
|
||||
for i, expectedType := range expectedManagedKeyTypes {
|
||||
require.Equal(t, expectedType, managedKeysDetails[i]["type"], "managed key type at index %d should be %s", i, expectedType)
|
||||
require.Equal(t, 0, managedKeysDetails[i]["count"], "managed key count at index %d should be 0", i)
|
||||
}
|
||||
|
||||
// Verify ssh_units has both types
|
||||
sshMetric, exists := metricsMap["ssh_units"]
|
||||
require.True(t, exists, "ssh_units metric should be present")
|
||||
sshData := sshMetric["metric_data"].(map[string]interface{})
|
||||
sshDetails := sshData["metric_details"].([]map[string]interface{})
|
||||
require.Len(t, sshDetails, 2, "ssh_units should have 2 types")
|
||||
require.Equal(t, "otp_units", sshDetails[0]["type"])
|
||||
require.Equal(t, "certificate_units", sshDetails[1]["type"])
|
||||
|
||||
// Verify id_token_units has both types
|
||||
idTokenMetric, exists := metricsMap["id_token_units"]
|
||||
require.True(t, exists, "id_token_units metric should be present")
|
||||
idTokenData := idTokenMetric["metric_data"].(map[string]interface{})
|
||||
idTokenDetails := idTokenData["metric_details"].([]map[string]interface{})
|
||||
require.Len(t, idTokenDetails, 2, "id_token_units should have 2 types")
|
||||
|
||||
expectedIdTokenTypes := []string{"oidc", "spiffe"}
|
||||
for i, expectedType := range expectedIdTokenTypes {
|
||||
require.Equal(t, expectedType, idTokenDetails[i]["type"], "id token type at index %d should be %s", i, expectedType)
|
||||
require.Equal(t, float64(0), idTokenDetails[i]["count"], "id token count at index %d should be 0", i)
|
||||
}
|
||||
}
|
||||
|
||||
// TestSystemBackend_BillingOverview_PreviousMonth_WithError tests the behavior
|
||||
// when retrieving the previous month's timestamp fails with an error.
|
||||
// This ensures the endpoint gracefully handles storage errors by returning zero time.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user