greentic_runner_host/http/
admin.rs1use axum::Json;
2use axum::extract::State;
3use axum::http::StatusCode;
4use axum::response::IntoResponse;
5use serde_json::json;
6use time::format_description::well_known::Rfc3339;
7
8use crate::http::auth::AdminGuard;
9use crate::runner::ServerState;
10
11pub async fn status(AdminGuard: AdminGuard, State(state): State<ServerState>) -> impl IntoResponse {
12 let snapshot = state.active.snapshot();
13 let tenants = snapshot
14 .iter()
15 .map(|(tenant, runtime)| {
16 let pack = runtime.pack();
17 let metadata = pack.metadata();
18 let required_secrets = runtime.required_secrets();
19 let missing_secrets = runtime.missing_secrets();
20 let overlays = runtime
21 .overlays()
22 .into_iter()
23 .zip(runtime.overlay_digests().into_iter())
24 .map(|(overlay, digest)| {
25 let meta = overlay.metadata();
26 json!({
27 "pack_id": meta.pack_id,
28 "version": meta.version,
29 "digest": digest,
30 })
31 })
32 .collect::<Vec<_>>();
33 json!({
34 "tenant": tenant,
35 "pack_id": metadata.pack_id,
36 "version": metadata.version,
37 "digest": runtime.digest(),
38 "overlays": overlays,
39 "required_secrets": required_secrets,
40 "missing_secrets": missing_secrets,
41 })
42 })
43 .collect::<Vec<_>>();
44
45 let health = state.health.snapshot();
46 let last_reload = health.last_reload.and_then(|ts| ts.format(&Rfc3339).ok());
47
48 Json(json!({
49 "tenants": tenants,
50 "active": snapshot.len(),
51 "last_reload": last_reload,
52 "last_error": health.last_error,
53 }))
54}
55
56pub async fn reload(AdminGuard: AdminGuard, State(state): State<ServerState>) -> impl IntoResponse {
57 if let Some(handle) = &state.reload {
58 match handle.trigger().await {
59 Ok(()) => {
60 tracing::info!("pack.reload.requested");
61 (
62 StatusCode::ACCEPTED,
63 Json(json!({ "status": "reload requested" })),
64 )
65 }
66 Err(err) => {
67 tracing::warn!(error = %err, "reload trigger failed");
68 (
69 StatusCode::INTERNAL_SERVER_ERROR,
70 Json(json!({ "error": err.to_string() })),
71 )
72 }
73 }
74 } else {
75 (
76 StatusCode::NOT_IMPLEMENTED,
77 Json(json!({ "error": "reload handle unavailable" })),
78 )
79 }
80}