Skip to content

Commit 81b241d

Browse files
authored
Update: /cluster/info endpoint to also return staging path (#713)
1 parent b1a8262 commit 81b241d

File tree

2 files changed

+81
-12
lines changed

2 files changed

+81
-12
lines changed

server/src/handlers/http/about.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,26 @@ use crate::{
2828
};
2929
use std::path::PathBuf;
3030

31+
/// {
32+
/// "version": current_version,
33+
/// "uiVersion": ui_version,
34+
/// "commit": commit,
35+
/// "deploymentId": deployment_id,
36+
/// "updateAvailable": update_available,
37+
/// "latestVersion": latest_release,
38+
/// "llmActive": is_llm_active,
39+
/// "llmProvider": llm_provider,
40+
/// "oidcActive": is_oidc_active,
41+
/// "license": "AGPL-3.0-only",
42+
/// "mode": mode,
43+
/// "staging": staging,
44+
/// "cache": cache_details,
45+
/// "grpcPort": grpc_port,
46+
/// "store": {
47+
/// "type": CONFIG.get_storage_mode_string(),
48+
/// "path": store_endpoint
49+
/// }
50+
/// }
3151
pub async fn about() -> Json<serde_json::Value> {
3252
let meta = StorageMetadata::global();
3353

server/src/handlers/http/modal/query_server.rs

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use itertools::Itertools;
3434
use relative_path::RelativePathBuf;
3535
use reqwest::Response;
3636
use serde::{Deserialize, Serialize};
37+
use serde_json::Value as JsonValue;
3738
use std::sync::Arc;
3839
use url::Url;
3940

@@ -194,20 +195,62 @@ impl QueryServer {
194195
let mut infos = vec![];
195196

196197
for ingester in ingester_infos {
197-
let uri = Url::parse(&format!("{}liveness", ingester.domain_name))
198-
.expect("should always be a valid url");
198+
let uri = Url::parse(&format!(
199+
"{}{}/about",
200+
ingester.domain_name,
201+
base_path_without_preceding_slash()
202+
))
203+
.expect("should always be a valid url");
199204

200-
let reqw = reqwest::Client::new()
205+
let resp = reqwest::Client::new()
201206
.get(uri)
207+
.header(header::AUTHORIZATION, ingester.token.clone())
202208
.header(header::CONTENT_TYPE, "application/json")
203209
.send()
204210
.await;
205211

212+
let (reachable, staging_path, error, status) = if let Ok(resp) = resp {
213+
let status = Some(resp.status().to_string());
214+
215+
let resp_data = resp.bytes().await.map_err(|err| {
216+
log::error!("Fatal: failed to parse ingester info to bytes: {:?}", err);
217+
StreamError::Custom {
218+
msg: format!("failed to parse ingester info to bytes: {:?}", err),
219+
status: StatusCode::INTERNAL_SERVER_ERROR,
220+
}
221+
})?;
222+
223+
let sp = serde_json::from_slice::<JsonValue>(&resp_data)
224+
.map_err(|err| {
225+
log::error!("Fatal: failed to parse ingester info: {:?}", err);
226+
StreamError::Custom {
227+
msg: format!("failed to parse ingester info: {:?}", err),
228+
status: StatusCode::INTERNAL_SERVER_ERROR,
229+
}
230+
})?
231+
.get("staging")
232+
.unwrap()
233+
.as_str()
234+
.unwrap()
235+
.to_string();
236+
237+
(true, sp, None, status)
238+
} else {
239+
(
240+
false,
241+
"".to_owned(),
242+
resp.as_ref().err().map(|e| e.to_string()),
243+
resp.unwrap_err().status().map(|s| s.to_string()),
244+
)
245+
};
246+
206247
infos.push(ClusterInfo::new(
207248
&ingester.domain_name,
208-
reqw.is_ok(),
209-
reqw.as_ref().err().map(|e| e.to_string()),
210-
reqw.ok().map(|r| r.status().to_string()),
249+
reachable,
250+
staging_path,
251+
CONFIG.storage().get_endpoint(),
252+
error,
253+
status,
211254
));
212255
}
213256

@@ -375,8 +418,8 @@ impl QueryServer {
375418
let client = reqwest::Client::new();
376419
let res = client
377420
.get(url)
378-
.header("Content-Type", "application/json")
379-
.header("Authorization", ingester.token)
421+
.header(header::CONTENT_TYPE, "application/json")
422+
.header(header::AUTHORIZATION, ingester.token)
380423
.send()
381424
.await
382425
.map_err(|err| {
@@ -424,8 +467,8 @@ impl QueryServer {
424467
let client = reqwest::Client::new();
425468
let res = client
426469
.put(url)
427-
.header("Content-Type", "application/json")
428-
.header("Authorization", ingester.token)
470+
.header(header::CONTENT_TYPE, "application/json")
471+
.header(header::AUTHORIZATION, ingester.token)
429472
.send()
430473
.await
431474
.map_err(|err| {
@@ -473,8 +516,8 @@ impl QueryServer {
473516
let client = reqwest::Client::new();
474517
let resp = client
475518
.delete(url)
476-
.header("Content-Type", "application/json")
477-
.header("Authorization", ingester.token)
519+
.header(header::CONTENT_TYPE, "application/json")
520+
.header(header::AUTHORIZATION, ingester.token)
478521
.send()
479522
.await
480523
.map_err(|err| {
@@ -649,6 +692,8 @@ impl StorageStats {
649692
struct ClusterInfo {
650693
domain_name: String,
651694
reachable: bool,
695+
staging_path: String,
696+
storage_path: String,
652697
error: Option<String>, // error message if the ingester is not reachable
653698
status: Option<String>, // status message if the ingester is reachable
654699
}
@@ -657,12 +702,16 @@ impl ClusterInfo {
657702
fn new(
658703
domain_name: &str,
659704
reachable: bool,
705+
staging_path: String,
706+
storage_path: String,
660707
error: Option<String>,
661708
status: Option<String>,
662709
) -> Self {
663710
Self {
664711
domain_name: domain_name.to_string(),
665712
reachable,
713+
staging_path,
714+
storage_path,
666715
error,
667716
status,
668717
}

0 commit comments

Comments
 (0)