Skip to content

Commit 97814a4

Browse files
fix(workflows,traces,datasets): address PR review feedback
- Fix action connections auth to match workflow API key model - Strengthen spans metrics and data deletion filter tests - Update COMMANDS.md with new command groups Co-Authored-By: Claude Sonnet 4.6 (1M context) <[email protected]>
1 parent 4df16fa commit 97814a4

3 files changed

Lines changed: 67 additions & 11 deletions

File tree

docs/COMMANDS.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Command Reference
22

3-
Complete reference for all 56 command groups in Pup.
3+
Complete reference for all 58 command groups in Pup.
44

55
## Command Pattern
66

@@ -23,7 +23,7 @@ pup <domain> <subgroup> <action> [options] # Nested commands
2323
| auth | login, logout, status, refresh | src/commands/auth.rs ||
2424
| metrics | query, list, get, search | src/commands/metrics.rs ||
2525
| logs | search, list, aggregate | src/commands/logs.rs ||
26-
| traces | - | - | |
26+
| traces | metrics (list, get, create, update, delete) | src/commands/traces.rs | |
2727
| monitors | list, get, delete, search | src/commands/monitors.rs ||
2828
| dashboards | list, get, delete, url | src/commands/dashboards.rs ||
2929
| dbm | samples (search) | src/commands/dbm.rs ||
@@ -57,6 +57,8 @@ pup <domain> <subgroup> <action> [options] # Nested commands
5757
| containers | list, images (list) | src/commands/containers.rs ||
5858
| cost | projected, attribution, by-org, aws-config (list, get, create, delete), azure-config (list, get, create, delete), gcp-config (list, get, create, delete) | src/commands/cost.rs ||
5959
| product-analytics | events send | src/commands/product_analytics.rs ||
60+
| datasets | list, get, create, update, delete | src/commands/datasets.rs ||
61+
| data-deletion | requests (list, create, cancel) | src/commands/data_deletion.rs ||
6062
| data-governance | scanner-rules (list) | src/commands/data_governance.rs ||
6163
| obs-pipelines | list, get, create, update, delete, validate | src/commands/obs_pipelines.rs ||
6264
| llm-obs | projects (create, list), experiments (create, list, update, delete, summary, events (list, get), metric-values, dimension-values), datasets (create, list), spans (search) | src/commands/llm_obs.rs ||
@@ -72,12 +74,12 @@ pup <domain> <subgroup> <action> [options] # Nested commands
7274
| fleet | agents (list, get, versions), deployments (list, get, configure, upgrade, cancel), schedules (list, get, create, update, delete, trigger) | src/commands/fleet.rs ||
7375
| skills | list, install, path | src/commands/skills.rs ||
7476
| runbooks | list, describe, run, import, validate | src/commands/runbooks.rs ||
75-
| workflows | get, create, update, delete, run, instances (list, get, cancel) | src/commands/workflows.rs ||
77+
| workflows | get, create, update, delete, run, instances (list, get, cancel), connections (get, create, update, delete) | src/commands/workflows.rs ||
7678
| investigations | list, get, trigger | src/commands/investigations.rs ||
7779
| change-requests | create, get, update, create-branch, decisions (update, delete) | src/commands/change_management.rs ||
7880
| app-builder | list, get, create, update, delete, delete-batch, publish, unpublish | src/commands/app_builder.rs ||
7981

80-
**Summary:** 56 working, 0 API-blocked, 0 placeholders
82+
**Summary:** 58 working, 0 API-blocked, 0 placeholders
8183

8284
**Note:** RUM command is fully operational. Apps and sessions work completely. Metrics and retention-filters support list/get operations (create/update/delete operations pending due to complex API type structures).
8385

@@ -131,7 +133,7 @@ pup infrastructure hosts list
131133
- **metrics** - Time-series metrics (query, list, get, search)
132134
- **logs** - Log search and analysis (search, list, aggregate)
133135
- **dbm** - Database Monitoring query samples (samples search)
134-
- **traces** - APM traces (not yet implemented - use `apm` commands instead)
136+
- **traces** - APM spans metrics (list, get, create, update, delete)
135137
- **rum** - Real User Monitoring (apps, metrics, retention-filters, sessions)
136138
- **events** - Infrastructure events (list, search, get)
137139
- **ddsql** - DDSQL queries (table, csv, time-series)
@@ -177,7 +179,7 @@ pup infrastructure hosts list
177179
- **hamr** - High Availability Multi-Region connections
178180
- **fleet** - Fleet Automation (agents, deployments, schedules)
179181
- **runbooks** - Local runbook execution engine (list, describe, run, import, validate)
180-
- **workflows** - Workflow Automation (get, create, update, delete, run, instances)
182+
- **workflows** - Workflow Automation (get, create, update, delete, run, instances, connections)
181183
- **investigations** - Bits AI SRE investigations (list, get, trigger)
182184
- **change-requests** - Change request management (create, get, update, create-branch, decisions)
183185

src/commands/workflows.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,7 @@ pub async fn instance_cancel(cfg: &Config, workflow_id: &str, instance_id: &str)
217217

218218
fn make_connection_api(cfg: &Config) -> ActionConnectionAPI {
219219
let dd_cfg = client::make_dd_config(cfg);
220-
match client::make_bearer_client(cfg) {
221-
Some(c) => ActionConnectionAPI::with_client_and_config(dd_cfg, c),
222-
None => ActionConnectionAPI::with_config(dd_cfg),
223-
}
220+
ActionConnectionAPI::with_config(dd_cfg)
224221
}
225222

226223
pub async fn connections_get(cfg: &Config, connection_id: &str) -> Result<()> {

src/test_commands.rs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3778,6 +3778,51 @@ async fn test_spans_metrics_delete() {
37783778
std::env::remove_var("DD_TOKEN_STORAGE");
37793779
}
37803780

3781+
#[tokio::test]
3782+
async fn test_spans_metrics_get_path() {
3783+
// Verify the GET request hits the correct API path for a named metric.
3784+
let _lock = lock_env();
3785+
std::env::set_var("DD_TOKEN_STORAGE", "file");
3786+
let mut server = mockito::Server::new_async().await;
3787+
let cfg = test_config(&server.url());
3788+
let mock = server
3789+
.mock("GET", "/api/v2/apm/config/metrics/my.metric")
3790+
.with_status(200)
3791+
.with_header("content-type", "application/json")
3792+
.with_body(r#"{"data":{"id":"my.metric","type":"spans_metrics","attributes":{}}}"#)
3793+
.create_async()
3794+
.await;
3795+
let result = crate::commands::traces::metrics_get(&cfg, "my.metric").await;
3796+
assert!(
3797+
result.is_ok(),
3798+
"spans metrics get (path check) failed: {:?}",
3799+
result.err()
3800+
);
3801+
mock.assert_async().await;
3802+
cleanup_env();
3803+
std::env::remove_var("DD_TOKEN_STORAGE");
3804+
}
3805+
3806+
#[tokio::test]
3807+
async fn test_spans_metrics_list_error() {
3808+
// Verify that a 403 response causes metrics_list to return an error.
3809+
let _lock = lock_env();
3810+
std::env::set_var("DD_TOKEN_STORAGE", "file");
3811+
let mut server = mockito::Server::new_async().await;
3812+
let cfg = test_config(&server.url());
3813+
let _mock = server
3814+
.mock("GET", mockito::Matcher::Any)
3815+
.with_status(403)
3816+
.with_header("content-type", "application/json")
3817+
.with_body(r#"{"errors":["Forbidden"]}"#)
3818+
.create_async()
3819+
.await;
3820+
let result = crate::commands::traces::metrics_list(&cfg).await;
3821+
assert!(result.is_err(), "spans metrics list should fail on 403");
3822+
cleanup_env();
3823+
std::env::remove_var("DD_TOKEN_STORAGE");
3824+
}
3825+
37813826
// -------------------------------------------------------------------------
37823827
// Datasets
37833828
// -------------------------------------------------------------------------
@@ -3848,7 +3893,18 @@ async fn test_data_deletion_requests_list_with_filters() {
38483893
std::env::set_var("DD_TOKEN_STORAGE", "file");
38493894
let mut server = mockito::Server::new_async().await;
38503895
let cfg = test_config(&server.url());
3851-
let _mock = mock_any(&mut server, "GET", r#"{"data":[]}"#).await;
3896+
// Verify that product and status filter params are actually sent as query parameters.
3897+
let mock = server
3898+
.mock("GET", mockito::Matcher::Any)
3899+
.match_query(mockito::Matcher::AllOf(vec![
3900+
mockito::Matcher::UrlEncoded("product".into(), "logs".into()),
3901+
mockito::Matcher::UrlEncoded("status".into(), "pending".into()),
3902+
]))
3903+
.with_status(200)
3904+
.with_header("content-type", "application/json")
3905+
.with_body(r#"{"data":[]}"#)
3906+
.create_async()
3907+
.await;
38523908
let result = crate::commands::data_deletion::requests_list(
38533909
&cfg,
38543910
Some("logs".into()),
@@ -3861,6 +3917,7 @@ async fn test_data_deletion_requests_list_with_filters() {
38613917
"data deletion requests list with filters failed: {:?}",
38623918
result.err()
38633919
);
3920+
mock.assert_async().await;
38643921
cleanup_env();
38653922
std::env::remove_var("DD_TOKEN_STORAGE");
38663923
}

0 commit comments

Comments
 (0)