diff --git a/.golangci.yml b/.golangci.yml index e40a39e3..1bd7b68a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -52,12 +52,6 @@ linters: pattern: (?i)passwd|pass|password|pwd|secret|token govet: enable-all: true - disable: - # fieldalignment: many production structs have alignment violations that - # pre-date this PR; fixing them is a separate concern. Suppress globally - # rather than per-struct since golangci-lint v2.10.x (CI) doesn't treat - # severity:warning as a non-fatal exit, unlike v2.11+. - - fieldalignment misspell: locale: US revive: @@ -93,12 +87,17 @@ linters: # unusedwrite: test fixture struct fields may be set for documentation # completeness even when only a subset of fields is read by a given subtest. # Scoped to test files so production unusedwrite bugs remain visible. - # Note: fieldalignment is disabled globally in govet.disable (many - # pre-existing production violations; separate cleanup PR needed). - linters: - govet text: "unusedwrite" path: _test\.go + # fieldalignment: test-table memory layout is irrelevant, and reordering + # positional table literals risks silent misassignment. Production code + # stays checked. + - linters: + - govet + text: "fieldalignment:" + path: _test\.go - linters: - all path: .*_gen\.go diff --git a/providers/gcp/internal/billingguard/billingguard.go b/providers/gcp/internal/billingguard/billingguard.go index 0ce21ce9..ca76e6c4 100644 --- a/providers/gcp/internal/billingguard/billingguard.go +++ b/providers/gcp/internal/billingguard/billingguard.go @@ -19,8 +19,8 @@ const marker = "failed to create billing service" type watcher struct { next io.Writer - mu sync.Mutex hits []string + mu sync.Mutex } func (w *watcher) Write(p []byte) (int, error) { diff --git a/providers/gcp/provider.go b/providers/gcp/provider.go index 3973fea2..361a6c0a 100644 --- a/providers/gcp/provider.go +++ b/providers/gcp/provider.go @@ -93,11 +93,11 @@ func (r *realResourceManagerService) ListProjects(ctx context.Context) ([]*cloud // Provider implements the provider.Provider interface for Google Cloud Platform. type Provider struct { - projectID string - clientOpts []option.ClientOption projectsClient ProjectsClient regionsClient RegionsClient resourceManagerService ResourceManagerService + projectID string + clientOpts []option.ClientOption } // NewProvider creates a new GCP provider. diff --git a/providers/gcp/recommendations.go b/providers/gcp/recommendations.go index 0d6eab58..7ca1febd 100644 --- a/providers/gcp/recommendations.go +++ b/providers/gcp/recommendations.go @@ -54,22 +54,29 @@ func gcpRegionConcurrency() int { // only an explicit request reaches those clients, which return // common.ErrCommitmentPurchaseNotSupported. type regionResult struct { + // attempted counts the service calls launched for this region (after the + // params service filter), failed counts how many of those errored, and + // lastErr keeps one representative error. mergeRegionResults aggregates + // these across regions for the all-attempted-failed guard (COR-03). + lastErr error + compute []common.Recommendation + // attempted counts the service calls launched for this region (after the // params service filter), failed counts how many of those errored, and // lastErr keeps one representative error. mergeRegionResults aggregates // these across regions for the all-attempted-failed guard (COR-03). attempted int failed int - lastErr error } // RecommendationsClientAdapter aggregates GCP CUD and commitment recommendations across all services. type RecommendationsClientAdapter struct { - projectID string - clientOpts []option.ClientOption // regionsFn replaces the live region lookup; tests only. regionsFn func(context.Context) ([]string, error) + + projectID string + clientOpts []option.ClientOption } // GetRecommendations retrieves all GCP commitment recommendations across all diff --git a/providers/gcp/services/cloudsql/client.go b/providers/gcp/services/cloudsql/client.go index 0771cd08..393dba95 100644 --- a/providers/gcp/services/cloudsql/client.go +++ b/providers/gcp/services/cloudsql/client.go @@ -47,7 +47,7 @@ type RecommenderClient interface { } // Client handles GCP Cloud SQL commitments. -type Client struct { +type Client struct { //nolint:govet // fieldalignment: file owned by open PR #471 skuMu sync.Mutex skuCache *cloudbilling.ListSkusResponse ctx context.Context @@ -258,7 +258,7 @@ func (c *Client) GetValidResourceTypes(ctx context.Context) ([]string, error) { } // SQLPricing contains pricing information for Cloud SQL. -type SQLPricing struct { +type SQLPricing struct { //nolint:govet // fieldalignment: file owned by open PR #471 HourlyRate float64 CommitmentPrice float64 OnDemandPrice float64 diff --git a/providers/gcp/services/cloudstorage/client.go b/providers/gcp/services/cloudstorage/client.go index 7054c2ef..3b7574b7 100644 --- a/providers/gcp/services/cloudstorage/client.go +++ b/providers/gcp/services/cloudstorage/client.go @@ -59,7 +59,7 @@ type BillingService interface { } // Client handles GCP Cloud Storage commitments. -type Client struct { +type Client struct { //nolint:govet // fieldalignment: file owned by open PR #471 ctx context.Context projectID string region string @@ -219,7 +219,7 @@ func (c *Client) GetValidResourceTypes(ctx context.Context) ([]string, error) { } // StoragePricing contains pricing information for Cloud Storage. -type StoragePricing struct { +type StoragePricing struct { //nolint:govet // fieldalignment: file owned by open PR #471 HourlyRate float64 CommitmentPrice float64 OnDemandPrice float64 diff --git a/providers/gcp/services/computeengine/client.go b/providers/gcp/services/computeengine/client.go index 970459fa..c214b7c7 100644 --- a/providers/gcp/services/computeengine/client.go +++ b/providers/gcp/services/computeengine/client.go @@ -260,16 +260,15 @@ type RecommenderClient interface { // Client handles GCP Compute Engine Committed Use Discounts. type Client struct { - projectID string - region string - clientOpts []option.ClientOption commitmentsService CommitmentsService machineTypesService MachineTypesService billingService BillingService recommenderClient RecommenderClient - - skuMu sync.Mutex - skuCache []*cloudbilling.Sku + projectID string + region string + clientOpts []option.ClientOption + skuCache []*cloudbilling.Sku + skuMu sync.Mutex } // NewClient creates a new GCP Compute Engine client. diff --git a/providers/gcp/services/computeengine/pricing.go b/providers/gcp/services/computeengine/pricing.go index 261603d8..0a499cc5 100644 --- a/providers/gcp/services/computeengine/pricing.go +++ b/providers/gcp/services/computeengine/pricing.go @@ -25,13 +25,17 @@ const ( // ComputePricing is the price of a commitment's resources, for one term. type ComputePricing struct { + Currency string + // HourlyRate is the committed price per hour for the whole resource set. HourlyRate float64 + // CommitmentPrice is the committed price over the whole term. CommitmentPrice float64 + // OnDemandPrice is the on-demand price of the same resources over the term. - OnDemandPrice float64 - Currency string + OnDemandPrice float64 + SavingsPercentage float64 } @@ -97,8 +101,8 @@ type skuRates struct { } type familyRates struct { - onDemand, commitment skuRates currency string + onDemand, commitment skuRates } // onDemandDescription matches e.g. "N2 Instance Core running in Americas", @@ -127,11 +131,11 @@ func legacyCommitmentDescription(label string) *regexp.Regexp { // rateMatcher recognizes the catalog SKUs of one family, region and term. type rateMatcher struct { - region string onDemand *regexp.Regexp - commitments []*regexp.Regexp + region string wantTerm string wantUsage string + commitments []*regexp.Regexp } func newRateMatcher(labels skuFamilyLabels, region string, termYears int) rateMatcher { @@ -190,8 +194,8 @@ func (r *rateSlot) set(price float64, sku *cloudbilling.Sku) error { // rateCollector accumulates the four prices wanted from matched SKUs. type rateCollector struct { - odCPU, odRAM, cCPU, cRAM rateSlot currency string + odCPU, odRAM, cCPU, cRAM rateSlot } func (c *rateCollector) add(sku *cloudbilling.Sku, isCommit, isRAM bool) error { diff --git a/providers/gcp/services/memorystore/client.go b/providers/gcp/services/memorystore/client.go index 486623ad..fc39b8de 100644 --- a/providers/gcp/services/memorystore/client.go +++ b/providers/gcp/services/memorystore/client.go @@ -53,7 +53,7 @@ type RecommenderClient interface { } // Client handles GCP Memorystore (Redis) commitments. -type Client struct { +type Client struct { //nolint:govet // fieldalignment: file owned by open PR #471 skuMu sync.Mutex skuCache *cloudbilling.ListSkusResponse ctx context.Context @@ -221,7 +221,7 @@ func (c *Client) GetValidResourceTypes(ctx context.Context) ([]string, error) { } // RedisPricing contains pricing information for Memorystore Redis. -type RedisPricing struct { +type RedisPricing struct { //nolint:govet // fieldalignment: file owned by open PR #471 HourlyRate float64 CommitmentPrice float64 OnDemandPrice float64