feat(cost_ccm): add costs ccm recommendations search#543
Open
gm2211 wants to merge 1 commit into
Open
Conversation
Surfaces Datadog Cloud Cost Management recommendations (POST /api/v2/cost/recommendations) via the CLI. CCM optimization recommendations were previously unreachable from pup — the `costs ccm` subtree covered custom-costs, budgets, commitments, and tags but had no entry point for rightsize / terminate / idle-resource suggestions. Adds: - `pup costs ccm recommendations search` with `--view`, `--filter`, `--sort-by`, `--order`, `--page-size`, `--page-token` - Client-side validation of `--view` (active | dismissed | open | in-progress | completed | all) and `--order` (asc | desc). - `--order` requires `--sort-by`; mismatched flags fail before any HTTP request. Implementation matches the existing `cost_ccm.rs` style: builds the JSON:API envelope manually and uses `client::raw_request` (the typed SDK method exists as `search_cost_recommendations` but cost_ccm.rs consistently uses raw requests, so this keeps the file uniform). Verified live against datadoghq.com: - Default view returns recommendations + pagination token. - `--sort-by potential_daily_savings --order desc` returns rows in descending order. - Invalid `--view` fails fast with a clear error. Tests: - 6 unit tests on `build_recommendations_body` cover the happy path (minimal + filter/sort), default-order behavior, and three error branches (invalid view, invalid order, `--order` without `--sort-by`). - 2 mockito-backed tests cover the success path through `recommendations_search` and confirm the invalid-view check fires before any network call. cargo fmt, cargo clippy -- -D warnings, and cargo test all pass.
| let resp = client::raw_request( | ||
| cfg, | ||
| "POST", | ||
| "/api/v2/cost/recommendations", |
Collaborator
There was a problem hiding this comment.
Should this already be in the SDK? Instead of maintaining 2 mappings
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Surfaces Datadog Cloud Cost Management recommendations (
POST /api/v2/cost/recommendations) via the CLI. CCM optimization recommendations were previously unreachable from pup — thecosts ccmsubtree covered custom-costs, budgets, commitments, and tags but had no entry point for rightsize / terminate / idle-resource suggestions.Changes
src/main.rs: newCostCcmActions::Recommendationsvariant +CostCcmRecommendationsActions::Searchsubcommand with--view,--filter,--sort-by,--order,--page-size,--page-token; dispatched in theCommands::Cost { action }match.src/commands/cost_ccm.rs:recommendations_searchasync function +build_recommendations_bodyhelper. Client-side validation of--view(active | dismissed | open | in-progress | completed | all) and--order(asc | desc);--orderrequires--sort-by. Builds the JSON:API envelope (type: recommendations_filter) and usesclient::raw_requestso the file stays consistent with sibling commands (custom-costs, budgets, etc.).Testing
cargo fmt --check,cargo clippy --all-targets -- -D warnings, andcargo test --bin pup cost_ccmall pass.Unit tests (added):
test_build_recommendations_body_minimal— happy path with only--view.test_build_recommendations_body_with_sort_default_order—--sort-bywithout--orderdefaults todesc.test_build_recommendations_body_with_filter_and_sort_asc— full envelope shape with filter + asc sort.test_build_recommendations_body_invalid_view— rejects unknown view.test_build_recommendations_body_invalid_order— rejects unknown order.test_build_recommendations_body_order_without_sort_by— rejects--orderwithout--sort-by.test_recommendations_search_success— mockito-backed end-to-end happy path.test_recommendations_search_invalid_view_errors_before_request— confirms the validation fires before any HTTP call.Live verification against
datadoghq.com:Notes
search(list). The public SDK exposes a singlesearch_cost_recommendationsoperation; there is no get-by-id, dismiss, or apply endpoint to wrap.--filteris passed through verbatim to the server. The API accepts a facet-style filter expression; I deliberately did not document a specific syntax in--helpbecause the public API docs do not pin it down. Happy to refine the help text if there's a canonical reference to point at.