|
1 | 1 | use anyhow::Result; |
2 | 2 | use datadog_api_client::datadogV1::api_dashboards::{DashboardsAPI, ListDashboardsOptionalParams}; |
3 | 3 | use datadog_api_client::datadogV1::model::Dashboard; |
| 4 | +use url::Url; |
4 | 5 |
|
5 | 6 | use crate::config::Config; |
6 | 7 | use crate::formatter; |
@@ -53,6 +54,35 @@ pub async fn delete(cfg: &Config, id: &str) -> Result<()> { |
53 | 54 | formatter::output(cfg, &resp) |
54 | 55 | } |
55 | 56 |
|
| 57 | +pub async fn url(cfg: &Config, id: &str, from: &str, to: &str, live: bool) -> Result<()> { |
| 58 | + let api = crate::make_api!(DashboardsAPI, cfg); |
| 59 | + let dashboard = api |
| 60 | + .get_dashboard(id.to_string()) |
| 61 | + .await |
| 62 | + .map_err(|e| anyhow::anyhow!("failed to get dashboard: {e:?}"))?; |
| 63 | + let base_url = dashboard |
| 64 | + .url |
| 65 | + .ok_or_else(|| anyhow::anyhow!("dashboard response did not include url"))?; |
| 66 | + println!("{}", dashboard_url_with_time(&base_url, from, to, live)?); |
| 67 | + Ok(()) |
| 68 | +} |
| 69 | + |
| 70 | +fn dashboard_url_with_time(base_url: &str, from: &str, to: &str, live: bool) -> Result<String> { |
| 71 | + let mut url = Url::parse(base_url).map_err(|e| { |
| 72 | + anyhow::anyhow!("dashboard response included invalid url {base_url:?}: {e}") |
| 73 | + })?; |
| 74 | + let mut query_pairs: Vec<(String, String)> = url |
| 75 | + .query_pairs() |
| 76 | + .filter(|(key, _)| key != "from_ts" && key != "to_ts" && key != "live") |
| 77 | + .map(|(key, value)| (key.into_owned(), value.into_owned())) |
| 78 | + .collect(); |
| 79 | + query_pairs.push(("from_ts".to_string(), from.to_string())); |
| 80 | + query_pairs.push(("to_ts".to_string(), to.to_string())); |
| 81 | + query_pairs.push(("live".to_string(), live.to_string())); |
| 82 | + url.query_pairs_mut().clear().extend_pairs(query_pairs); |
| 83 | + Ok(url.to_string()) |
| 84 | +} |
| 85 | + |
56 | 86 | #[cfg(test)] |
57 | 87 | mod tests { |
58 | 88 |
|
@@ -107,4 +137,36 @@ mod tests { |
107 | 137 | ); |
108 | 138 | cleanup_env(); |
109 | 139 | } |
| 140 | + |
| 141 | + #[test] |
| 142 | + fn test_dashboard_url_with_time_adds_live_window() { |
| 143 | + let url = super::dashboard_url_with_time( |
| 144 | + "https://app.datadoghq.com/dashboard/abc-123/test-dashboard?tpl_var_env=prod", |
| 145 | + "now-1w", |
| 146 | + "now", |
| 147 | + true, |
| 148 | + ) |
| 149 | + .expect("dashboard URL should be valid"); |
| 150 | + |
| 151 | + assert_eq!( |
| 152 | + url, |
| 153 | + "https://app.datadoghq.com/dashboard/abc-123/test-dashboard?tpl_var_env=prod&from_ts=now-1w&to_ts=now&live=true" |
| 154 | + ); |
| 155 | + } |
| 156 | + |
| 157 | + #[test] |
| 158 | + fn test_dashboard_url_with_time_replaces_existing_time_params() { |
| 159 | + let url = super::dashboard_url_with_time( |
| 160 | + "https://app.datadoghq.com/dashboard/abc-123/test-dashboard?from_ts=old&to_ts=old&live=false", |
| 161 | + "now-1w", |
| 162 | + "now", |
| 163 | + true, |
| 164 | + ) |
| 165 | + .expect("dashboard URL should be valid"); |
| 166 | + |
| 167 | + assert_eq!( |
| 168 | + url, |
| 169 | + "https://app.datadoghq.com/dashboard/abc-123/test-dashboard?from_ts=now-1w&to_ts=now&live=true" |
| 170 | + ); |
| 171 | + } |
110 | 172 | } |
0 commit comments