diff --git a/pkg/common/hours.go b/pkg/common/hours.go new file mode 100644 index 00000000..58d85b9a --- /dev/null +++ b/pkg/common/hours.go @@ -0,0 +1,5 @@ +package common //nolint:revive // pkg/common is the module's core domain package; see breakeven.go + +// HoursPerYear is the 365-day year length (24 * 365) used to convert a +// reservation term in years into billable hours. +const HoursPerYear = 8760.0 diff --git a/providers/azure/go.mod b/providers/azure/go.mod index 4ea54ae5..d93eb608 100644 --- a/providers/azure/go.mod +++ b/providers/azure/go.mod @@ -15,7 +15,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/search/armsearch v1.4.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/sql/armsql v1.2.0 - github.com/LeanerCloud/cloud-commitments-go/pkg v0.0.0-20261017001455-7383c3a7db7e + github.com/LeanerCloud/cloud-commitments-go/pkg v0.0.0-20261020054349-66c6c61918d4 github.com/stretchr/testify v1.11.1 golang.org/x/sync v0.23.0 ) diff --git a/providers/azure/go.sum b/providers/azure/go.sum index 932b78b5..de850a1a 100644 --- a/providers/azure/go.sum +++ b/providers/azure/go.sum @@ -38,8 +38,8 @@ github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJ github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgvJqCH0sFfrBUTnUJSBrBf7++ypk+twtRs= github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= -github.com/LeanerCloud/cloud-commitments-go/pkg v0.0.0-20261017001455-7383c3a7db7e h1:SeuL9mqUKVNiDa4yXU9IdaKKlwNo/iaaDmDXMHClw+o= -github.com/LeanerCloud/cloud-commitments-go/pkg v0.0.0-20261017001455-7383c3a7db7e/go.mod h1:SCDEgHG6evjPh0RsoXof+J3aMmGXNFMrwbJIle7rMpQ= +github.com/LeanerCloud/cloud-commitments-go/pkg v0.0.0-20261020054349-66c6c61918d4 h1:8ZnV+uLXITP5oTimNlsUsB0KMW5sf4JgEMKEO0DOTCs= +github.com/LeanerCloud/cloud-commitments-go/pkg v0.0.0-20261020054349-66c6c61918d4/go.mod h1:SCDEgHG6evjPh0RsoXof+J3aMmGXNFMrwbJIle7rMpQ= github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY= github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= diff --git a/providers/azure/services/cache/client.go b/providers/azure/services/cache/client.go index c21f809b..7cbc96f5 100644 --- a/providers/azure/services/cache/client.go +++ b/providers/azure/services/cache/client.go @@ -581,7 +581,7 @@ func (c *Client) getRedisPricing(ctx context.Context, sku, region string, termYe return nil, err } return &RedisPricing{ - HourlyRate: selected.RetailPrice / (8760 * float64(termYears)), + HourlyRate: selected.RetailPrice / (common.HoursPerYear * float64(termYears)), ReservationPrice: selected.RetailPrice, Currency: selected.CurrencyCode, }, nil diff --git a/providers/azure/services/compute/client.go b/providers/azure/services/compute/client.go index 44bf6ff5..2f25efa8 100644 --- a/providers/azure/services/compute/client.go +++ b/providers/azure/services/compute/client.go @@ -710,7 +710,7 @@ func (c *Client) getVMPricing(ctx context.Context, vmSize, region string, termYe } return &VMPricing{ - HourlyRate: item.RetailPrice / (8760.0 * float64(termYears)), + HourlyRate: item.RetailPrice / (common.HoursPerYear * float64(termYears)), ReservationPrice: item.RetailPrice, Currency: item.CurrencyCode, }, nil diff --git a/providers/azure/services/cosmosdb/client.go b/providers/azure/services/cosmosdb/client.go index d83a3a87..0d149f16 100644 --- a/providers/azure/services/cosmosdb/client.go +++ b/providers/azure/services/cosmosdb/client.go @@ -578,7 +578,7 @@ func (c *Client) getCosmosPricing(ctx context.Context, sku, region string, termY } return &CosmosPricing{ - HourlyRate: selected.RetailPrice / (8760.0 * float64(termYears)), + HourlyRate: selected.RetailPrice / (common.HoursPerYear * float64(termYears)), ReservationPrice: selected.RetailPrice, Currency: selected.CurrencyCode, }, nil diff --git a/providers/azure/services/database/client.go b/providers/azure/services/database/client.go index bee41042..1955d3d2 100644 --- a/providers/azure/services/database/client.go +++ b/providers/azure/services/database/client.go @@ -605,7 +605,7 @@ func (c *Client) getSQLPricing(ctx context.Context, sku, region string, termYear } return &SQLPricing{ - HourlyRate: reservation.RetailPrice / (8760.0 * float64(termYears)), + HourlyRate: reservation.RetailPrice / (common.HoursPerYear * float64(termYears)), ReservationPrice: reservation.RetailPrice, Currency: reservation.CurrencyCode, }, nil diff --git a/providers/azure/services/managedredis/client.go b/providers/azure/services/managedredis/client.go index 1e18b3cd..e258fcea 100644 --- a/providers/azure/services/managedredis/client.go +++ b/providers/azure/services/managedredis/client.go @@ -538,7 +538,7 @@ func (c *Client) getRedisPricing(ctx context.Context, sku, region string, termYe return nil, err } return &RedisPricing{ - HourlyRate: selected.RetailPrice / (8760 * float64(termYears)), + HourlyRate: selected.RetailPrice / (common.HoursPerYear * float64(termYears)), ReservationPrice: selected.RetailPrice, Currency: selected.CurrencyCode, }, nil diff --git a/providers/azure/services/search/client.go b/providers/azure/services/search/client.go index f73d7934..78b38cdb 100644 --- a/providers/azure/services/search/client.go +++ b/providers/azure/services/search/client.go @@ -466,7 +466,7 @@ func (c *Client) getSearchPricing(ctx context.Context, sku, region string, termY return nil, fmt.Errorf("azure search SKU %s in region %s: %w", sku, region, err) } - hoursInTerm := 8760.0 * float64(termYears) + hoursInTerm := common.HoursPerYear * float64(termYears) return &Pricing{ HourlyRate: selected.RetailPrice / hoursInTerm, ReservationPrice: selected.RetailPrice, diff --git a/providers/azure/services/synapse/client.go b/providers/azure/services/synapse/client.go index 351cc84f..b4a03b3c 100644 --- a/providers/azure/services/synapse/client.go +++ b/providers/azure/services/synapse/client.go @@ -478,7 +478,7 @@ func (c *Client) getSynapsePricing(ctx context.Context, sku, region string, term } return &Pricing{ - HourlyRate: selected.RetailPrice / (8760.0 * float64(termYears)), + HourlyRate: selected.RetailPrice / (common.HoursPerYear * float64(termYears)), ReservationPrice: selected.RetailPrice, Currency: selected.CurrencyCode, }, nil diff --git a/providers/gcp/go.mod b/providers/gcp/go.mod index 9380eeb0..70b297bd 100644 --- a/providers/gcp/go.mod +++ b/providers/gcp/go.mod @@ -8,7 +8,7 @@ require ( cloud.google.com/go/redis v1.18.3 cloud.google.com/go/resourcemanager v1.10.7 cloud.google.com/go/storage v1.59.2 - github.com/LeanerCloud/cloud-commitments-go/pkg v0.0.0-20261017012250-2bf23fbd8c2a + github.com/LeanerCloud/cloud-commitments-go/pkg v0.0.0-20261020054349-66c6c61918d4 github.com/googleapis/gax-go/v2 v2.21.0 github.com/stretchr/testify v1.11.1 golang.org/x/oauth2 v0.36.0 diff --git a/providers/gcp/go.sum b/providers/gcp/go.sum index 9983261f..06c7412a 100644 --- a/providers/gcp/go.sum +++ b/providers/gcp/go.sum @@ -36,8 +36,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.54.0/go.mod h1:vB2GH9GAYYJTO3mEn8oYwzEdhlayZIdQz6zdzgUIRvA= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0 h1:s0WlVbf9qpvkh1c/uDAPElam0WrL7fHRIidgZJ7UqZI= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc= -github.com/LeanerCloud/cloud-commitments-go/pkg v0.0.0-20261017012250-2bf23fbd8c2a h1:TggoJtZRb3MHRRhJ8Q1uu5SGGmhL1YbHiG08Xv9hqDw= -github.com/LeanerCloud/cloud-commitments-go/pkg v0.0.0-20261017012250-2bf23fbd8c2a/go.mod h1:SCDEgHG6evjPh0RsoXof+J3aMmGXNFMrwbJIle7rMpQ= +github.com/LeanerCloud/cloud-commitments-go/pkg v0.0.0-20261020054349-66c6c61918d4 h1:8ZnV+uLXITP5oTimNlsUsB0KMW5sf4JgEMKEO0DOTCs= +github.com/LeanerCloud/cloud-commitments-go/pkg v0.0.0-20261020054349-66c6c61918d4/go.mod h1:SCDEgHG6evjPh0RsoXof+J3aMmGXNFMrwbJIle7rMpQ= github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY= github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= diff --git a/providers/gcp/services/computeengine/pricing.go b/providers/gcp/services/computeengine/pricing.go index db4a215a..472ddb93 100644 --- a/providers/gcp/services/computeengine/pricing.go +++ b/providers/gcp/services/computeengine/pricing.go @@ -16,8 +16,6 @@ const ( // computeServiceID is the Cloud Billing catalog service for Compute Engine. computeServiceID = "services/6F81-5844-456A" - hoursPerYear = 8760.0 - usageUnitHour = "h" usageUnitGiBHour = "GiBy.h" @@ -298,7 +296,7 @@ func (c *Client) getComputePricing(ctx context.Context, machineType, region stri return nil, err } - hours := hoursPerYear * float64(termYears) + hours := common.HoursPerYear * float64(termYears) commitHourly := float64(res.vcpus)*rates.commitment.cpu + res.memoryGiB*rates.commitment.ram onDemandHourly := float64(res.vcpus)*rates.onDemand.cpu + res.memoryGiB*rates.onDemand.ram