fix(aws): fail loud on unknown payment-option/term/engine -- remove silent defaults - #1085
Conversation
…t default convertPaymentOption and convertTermToSeconds previously logged a warning and silently substituted All Upfront (largest cash outlay) or 1 year when given an unrecognized or empty value, risking a mis-purchase on any typo or new/renamed AWS enum value. Both functions now return an explicit error on unrecognized input so the purchase and offering-lookup paths fail loud instead of buying the wrong product. Mirrors the pattern already used by the RDS convertPaymentOption. Regression tests for H1 (unknown/empty payment option) and H2 (unknown/empty term) are added to TestClient_FindOfferingID_AllPaymentOptions and TestClient_FindOfferingID_TermVariations; the previously-passing "default term" case is updated to assert the error path. Fixes H1 and H2 from docs/code-review/19-hardcoded-fallbacks-aws.md (PR #1039).
Fixes H3, H4, M1-M6, L1, L2 from the 19-hardcoded-fallbacks-aws.md audit plus H1/H2 from the now-merged #1039 branch (savingsplans). H3 (converters.go): add convertPaymentOptionE/convertTermInYearsE/ convertLookbackPeriodE that error on unrecognized input; wire into the SP recommendation path (parser_sp.go). The legacy non-erroring wrappers are retained for the RI path in client.go (owned by #865/#1075) with a deprecation comment and a follow-up reference. H4 (elasticache/client.go): convertPaymentOption now returns (string, error) mirroring the RDS sibling that already errors correctly. H1/H2 (savingsplans/client.go): convertPaymentOption and convertTermToSeconds now return (type, error); cherry-picked from the merged #1039 branch where the fix was staged. M4 (parser_services.go, rds/client.go): parseRDSDetails no longer silently defaults AZConfig to "single-az" when CE omits DeploymentOption; findOfferingID rejects empty AZConfig with an explicit error. M5 (parser_services.go): resolveEC2Tenancy now maps only the known CE values ("shared"/nil -> default, "dedicated" -> dedicated); any other value (e.g. "host" for Dedicated Hosts) returns an error rather than silently collapsing to default tenancy. M6 (rds/client.go): normalizeEngineName now returns (string, error) and errors for ambiguous Oracle ("oracle*"), SQL Server ("sqlserver*"/"sql-server*"), and bare Aurora inputs; unambiguous engines (mysql, postgresql, mariadb, aurora-mysql, aurora-postgresql) pass through unchanged. M1/M2/M3 (ec2/client.go): replace raw "convertible" literals with types.OfferingClassTypeConvertible; buildEC2OfferingQuery errors on empty Platform (purchase path); centralize "Linux/UNIX" literal into defaultEC2Platform constant (exchange-path helpers retain their safe fallback; the purchase path does not). Regression tests added for H3, H1/H2, H4, M2, M4, M5, M6, L1, L2; each fails pre-fix and passes post-fix. Closes #1084
|
Warning Review limit reached
More reviews will be available in 28 minutes and 23 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThis PR systematically replaces silent defaults with fail-loud error returns across AWS Cost Explorer enum converters and RI/Savings Plans offering lookup paths. New error-returning converter variants validate payment options, terms, and lookback periods; RDS and EC2 offering discovery now rejects missing or ambiguous metadata (AZConfig, engine name, platform, tenancy) instead of guessing; and Savings Plans offerings validation propagates conversion failures early. ChangesFail-loud AWS enum converters and stricter offering validation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
Simplify TestNormalizeEngineName_AmbiguousErrors: remove the confusing
oracle-se2 case (strings.Contains("oracle-se2","oracle") is true, so it
errors like all other oracle inputs -- no special case needed) and remove
the misleading inline comment. All remaining cases assert that any Oracle,
SQL Server, or bare Aurora input errors, which is the invariant under test.
…avingsplans gocyclo -over 10 fails on two functions added by the fail-loud refactor: - savingsplans.(*Client).findOfferingID (complexity 12): extract resolveSPPlanType and buildSPOfferingsInput helpers - rds.(*Client).paginateRDSOfferings (complexity 11): extract fetchRDSOfferingPage to isolate the per-page API call and scan Also apply gofmt to rds/client.go (trailing whitespace / brace style). Behaviour and error paths are unchanged; all rds and savingsplans tests still pass.
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@providers/aws/recommendations/parser_services.go`:
- Around line 38-43: parseRDSDetails currently maps any non-nil
rdsDetails.DeploymentOption that's not "Multi-AZ" into "single-az", which
silently misclassifies unknown tokens; change parseRDSDetails so it explicitly
accepts only "Multi-AZ" and "Single-AZ" values: set rdsInfo.AZConfig =
"multi-az" for "Multi-AZ", "single-az" for "Single-AZ", and for any other
non-nil value return an error (or propagate one) instead of folding to
single-az; update the parseRDSDetails signature/callers to propagate the error
so providers/aws/services/rds/client.go consumes only validated AZConfig values.
In `@providers/aws/services/rds/client.go`:
- Around line 306-313: Validate that details.AZConfig contains one of the
expected enum values instead of only checking for empty string: in the RDS logic
(around details.AZConfig and paginateRDSOfferings) perform an explicit
check/switch against the allowed DeploymentOption values (e.g., the known
single-AZ and multi-AZ tokens your codebase expects) and return an error for any
unknown/typo value so you never silently treat invalid input as single-AZ;
update callers/consumers (e.g., where multiAZ is derived) to rely on this
validated value.
- Around line 580-593: normalizeEngineName currently rejects any engine string
containing "oracle" or "sqlserver"/"sql-server", which also blocks valid exact
edition tokens like "oracle-se2" or "sqlserver-se"; change the checks to only
error when the engineLower is exactly "oracle" or exactly
"sqlserver"/"sql-server" (i.e., when the caller omitted the edition), allowing
strings that include edition suffixes (e.g., "oracle-ee", "sqlserver-web") to
pass; update the conditional logic around engineLower in normalizeEngineName
(referencing variables engineLower and engine) so product-edition tokens are
accepted and only generic names produce the fmt.Errorf.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2b009b7f-830b-48c7-bcfb-0dfd1ccd9557
📒 Files selected for processing (11)
providers/aws/recommendations/converters.goproviders/aws/recommendations/converters_test.goproviders/aws/recommendations/parser_services.goproviders/aws/recommendations/parser_services_test.goproviders/aws/recommendations/parser_sp.goproviders/aws/services/ec2/client.goproviders/aws/services/ec2/client_test.goproviders/aws/services/rds/client.goproviders/aws/services/rds/client_test.goproviders/aws/services/savingsplans/client.goproviders/aws/services/savingsplans/client_test.go
Three related fail-loud fixes in the AWS RDS purchase path: 1. parseRDSDetails: unknown DeploymentOption now errors instead of silently folding into "single-az". Only "Multi-AZ" and "Single-AZ" are accepted; any other non-nil value (e.g. "Multi-AZ-Readable-Standbys") returns an explicit error so the bad token surfaces rather than driving findOfferingID to the wrong RI class. 2. findOfferingID: AZConfig validation now uses a switch with an explicit default error case rather than only checking for empty string. A non-empty but invalid value (typo, future AWS enum addition) would previously fall through to multiAZ==false in paginateRDSOfferings, silently treating the bad input as single-AZ. 3. normalizeEngineName: Oracle and SQL Server checks changed from strings.Contains to == so that edition-qualified tokens (oracle-se2, oracle-ee, sqlserver-se, sqlserver-web, etc.) pass through as valid RDS ProductDescription values. The previous Contains check contradicted the error message itself, which told callers to supply those exact edition tokens. Regression tests added for all three: each new test was verified to fail against the pre-fix code and pass after.
|
Addressed CR pass (2026-06-07T19:21:35Z) findings (all 3 fixed in 681fd9e):
@coderabbitai review |
|
Triggering a fresh review now. ✏️ Learnings added
🧠 Learnings used✅ Action performedReview finished.
|
Summary
Regression tests added for all findings; each fails pre-fix and passes post-fix.
Closes #1084
Summary by CodeRabbit
Bug Fixes
Tests