Skip to content

fix(aws/ec2): refuse an offering priced above the approved upfront - #611

Open
cristim wants to merge 2 commits into
mainfrom
fix/aws-offering-price-guard
Open

cristim wants to merge 2 commits into
mainfrom
fix/aws-offering-price-guard

Conversation

@cristim

@cristim cristim commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

Part of #53

What

EC2 PurchaseCommitment bought the first matching offering without comparing its price to the approved recommendation and left the API's LimitPrice nil (finding "No purchase path reconciles the resolved offering's price against the approved recommendation cost"). Now it refuses when the offering's total upfront (FixedPrice x Count, in cents) exceeds rec.CommitmentCost by more than 5%, and sends that ceiling as LimitPrice (USD). No positive approved upfront (no-upfront options, missing figure) leaves behavior unchanged; a non-USD offering or a missing FixedPrice with an approved upfront is refused.

Why this item: it is the one place a bought price can silently exceed the figure the MaxPurchaseAmount approval was evaluated on, on a path that spends real money. The 5% tolerance is a constant in offeringprice (UpfrontTolerance) shared by the other services, which are not covered here.

Not covered (left on #53)

Same check for RDS, ElastiCache, MemoryDB, OpenSearch, Redshift; SUBSCRIPTION_ID join, region aliases, STS caching, SP date parsing, lookback fallback, MemoryDB engine, A09-009.

Proof

  • New tests fail with the guard removed (refusal and LimitPrice tests) and with the ceiling's tolerance removed; the boundary test fails when > becomes >=.
  • providers/aws: build, vet, go test -timeout 300s -count=1 ./..., golangci-lint v2.10.1 with the repo config, gocyclo: clean.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • AWS EC2 Reserved Instance purchases now reject offerings priced more than 5% above the approved upfront amount.
    • Purchase requests pass the approved upfront ceiling as the USD price limit.
    • Purchases are blocked when fixed pricing is missing or uses a non-USD currency.
    • Requests without an approved upfront amount continue without a price limit.
  • Tests

    • Added coverage for price boundaries, currency validation, missing prices, and omitted limits.

PurchaseCommitment bought the first matching offering without comparing its
price to the recommendation's CommitmentCost, and left the API's LimitPrice
unset, so a repriced or differently-priced offering bypassed the approved cap.

Refuse when the offering's total upfront (FixedPrice x Count) exceeds the
approved upfront by more than 5%, and send that ceiling as LimitPrice.
Recommendations with no positive upfront are unchanged. Other services'
purchase paths from #53 are not covered here.

Part of #53

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Warning

Review limit reached

  • Run on-demand review

This review includes 3 billable files and costs up to $0.75.

  • Ask an admin to make reviews automatic

Open in CodeRabbit

Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing.

Or wait 34 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 88 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: LeanerCloud/cloud-commitments-go/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 99cb2819-77ae-41f5-beb0-23cb01a554bd
📥 Commits

Reviewing files that changed from the base of the PR and between ab34d8f and 590288e.

📒 Files selected for processing: 3
  • CHANGELOG.md
  • providers/aws/services/ec2/client.go
  • providers/aws/services/ec2/purchase_price_guard_test.go

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: LeanerCloud/cloud-commitments-go/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 464e7305-966a-446b-ae88-ff2a30df265d
📥 Commits

Reviewing files that changed from the base of the PR and between fe9c574 and ab34d8f.

📒 Files selected for processing: 5
  • CHANGELOG.md
  • providers/aws/internal/offeringprice/offeringprice.go
  • providers/aws/internal/offeringprice/offeringprice_test.go
  • providers/aws/services/ec2/client.go
  • providers/aws/services/ec2/purchase_price_guard_test.go

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

📝 Walkthrough

EC2 commitment purchases now validate an offering’s total upfront price against the approved amount plus 5%. Valid purchases send the rounded USD ceiling as LimitPrice. Purchases without a positive approved upfront amount leave the limit unset.

Changes: EC2 Upfront Price Guard

Layer / File(s) Summary
Upfront ceiling policy
providers/aws/internal/offeringprice/offeringprice.go, providers/aws/internal/offeringprice/offeringprice_test.go
The shared check applies a 5% ceiling and compares amounts rounded to whole cents. Tests cover the boundary and a value above it.
EC2 purchase validation and limit
providers/aws/services/ec2/client.go, providers/aws/services/ec2/purchase_price_guard_test.go, CHANGELOG.md
EC2 purchases validate positive approved upfront amounts against fixed USD prices. Valid purchases send the rounded ceiling as LimitPrice; tests cover rejection and cases where a limit is omitted or cannot be calculated. The changelog records the behavior.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant PurchaseCommitment
  participant upfrontLimit
  participant CheckUpfront
  participant EC2PurchaseAPI
  PurchaseCommitment->>upfrontLimit: Resolve upfront LimitPrice
  upfrontLimit->>CheckUpfront: Check offered total against approved amount
  CheckUpfront-->>upfrontLimit: Return validation result
  upfrontLimit-->>PurchaseCommitment: Return rounded USD ceiling or error
  PurchaseCommitment->>EC2PurchaseAPI: Submit purchase with LimitPrice
Loading
Merge Risk: ⚪ Minimal · up to ab34d

EC2 reserved instance purchases now refuse offerings priced more than 5% above the approved upfront amount and send that ceiling to AWS as a price limit. No actionable merge-blocking risk was found in the supplied changes.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 41.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 4 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main EC2 change: refusing offerings priced above the approved upfront amount.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 41.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 4 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@cristim

cristim commented Oct 20, 2026 •

Copy link
Copy Markdown
Member Author

Owner decision needed before merge (purchase semantics). #53 asks to refuse when the resolved offering's upfront exceeds the approved recommendation cost "by more than a configured tolerance". This PR hard-codes UpfrontTolerance = 0.05: offers above approved +5% are refused. (Update: the EC2 LimitPrice cap was dropped in 590288e because AWS applies it only to Marketplace offerings, which this path never buys.)

Options:

  1. Merge as is: fixed 5% (callers cannot change it).
  2. 0% (refuse any increase over the approved figure).
  3. Make it a caller-set field with 5% as the default.

Default if there is no answer within 24h: 1, merged as written. Both cold reviews approved this head; the tolerance is the only open point. [claude-cc-libs]

… unchecked

AWS documents LimitPrice only for Marketplace offerings, which findOffering
excludes, so it protected nothing and might be rejected. The local upfront
refusal stays unchanged. A recommendation whose commitment currency is set
and is not USD is now refused. Zero CommitmentCost stays unchecked because
the MCP EC2 tool never sets it.

Part of #53

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant