Skip to content

Commit a3a33fb

Browse files
committed
refactor: rename linux_agent to system_agent and update related cache handling
1 parent c112f5d commit a3a33fb

5 files changed

Lines changed: 62 additions & 62 deletions

File tree

metrics-cache/src/handlers/ingest.rs

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::time::Instant;
77
use crate::AppState;
88
use crate::auth::kubernetes::TokenValidator;
99
use crate::ingest::MetricsFetcherIngestion;
10+
use crate::ingest::SystemAgentOutput;
1011
use crate::ingest::kubelet_stats::StatsSummary;
1112

1213
pub async fn kubelet_stats_summary(
@@ -25,22 +26,54 @@ pub async fn kubelet_stats_summary(
2526
Json("ok".to_string())
2627
}
2728

28-
/// Store the raw check_mk_agent output for a node as-is, keyed by node
29-
/// name. No parsing/validation is done here or by the caller. Kept as
30-
/// [`Bytes`] rather than [`String`] since agent plugins are not guaranteed to
31-
/// produce valid UTF-8.
32-
pub async fn linux_agent(
29+
/// Store the raw output of a machine-level agent (currently only Linux's
30+
/// `check_mk_agent`) for a node as-is, keyed by node name. No
31+
/// parsing/validation is done here or by the caller. Kept as [`Bytes`]
32+
/// rather than [`String`] since agent plugins are not guaranteed to produce
33+
/// valid UTF-8.
34+
pub async fn system_agent(
3335
State(state): State<AppState<impl TokenValidator>>,
3436
Path(node_name): Path<String>,
3537
body: Bytes,
3638
) -> Json<String> {
3739
let ingestion = MetricsFetcherIngestion {
3840
received_at: Instant::now(),
39-
payload: body,
41+
payload: SystemAgentOutput(body),
4042
};
4143
state
42-
.linux_agent_cache
44+
.system_agent_cache
4345
.insert(node_name, Arc::new(ingestion))
4446
.await;
4547
Json("ok".to_string())
4648
}
49+
50+
#[cfg(test)]
51+
mod tests {
52+
use axum::extract::{Path, State};
53+
54+
use super::*;
55+
use crate::state::tests::test_app_state;
56+
57+
/// Exercises the handler directly (no router, no auth middleware) — this
58+
/// is about whether the handler does what's expected of it, not whether
59+
/// the route is wired up correctly; that's covered in `handlers::tests`.
60+
#[tokio::test]
61+
async fn system_agent_populates_cache_and_returns_ok() {
62+
let state = test_app_state();
63+
let cache = state.system_agent_cache.clone();
64+
65+
let Json(resp) = system_agent(
66+
State(state),
67+
Path("node-1".to_string()),
68+
Bytes::from_static(b"<<<check_mk>>>\nVersion: 2.5.0\n"),
69+
)
70+
.await;
71+
72+
assert_eq!(resp, "ok");
73+
cache.run_pending_tasks().await;
74+
assert_eq!(
75+
cache.get("node-1").await.map(|v| v.payload.0.clone()),
76+
Some(Bytes::from_static(b"<<<check_mk>>>\nVersion: 2.5.0\n"))
77+
);
78+
}
79+
}

metrics-cache/src/handlers/mod.rs

Lines changed: 8 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub fn ingest_app<V: TokenValidator>(state: AppState<V>) -> Router {
3636
"/kubelet_stats_summary",
3737
post(ingest::kubelet_stats_summary),
3838
)
39-
.route("/linux_agent/{node_name}", post(ingest::linux_agent))
39+
.route("/system_agent/{node_name}", post(ingest::system_agent))
4040
.route_layer(middleware::from_fn_with_state(
4141
state.clone(),
4242
auth::kubernetes::authenticate,
@@ -50,68 +50,26 @@ pub fn ingest_app<V: TokenValidator>(state: AppState<V>) -> Router {
5050

5151
#[cfg(test)]
5252
mod tests {
53-
use axum::body::{Body, Bytes};
53+
use axum::body::Body;
5454
use axum::http::{Request, StatusCode};
55-
use k8s_openapi::api::authentication::v1::{TokenReview, TokenReviewStatus, UserInfo};
5655
use tower::ServiceExt;
5756

5857
use super::*;
59-
use crate::state::tests::{MockValidator, test_app_state, test_app_state_with_validator};
60-
61-
fn authenticated_review(username: &str) -> TokenReview {
62-
TokenReview {
63-
status: Some(TokenReviewStatus {
64-
authenticated: Some(true),
65-
user: Some(UserInfo {
66-
username: Some(username.to_string()),
67-
..Default::default()
68-
}),
69-
..Default::default()
70-
}),
71-
..Default::default()
72-
}
73-
}
74-
75-
#[tokio::test]
76-
async fn linux_agent_ingest_populates_cache_and_returns_ok() {
77-
let state = test_app_state_with_validator(MockValidator {
78-
response: Ok(authenticated_review(
79-
"system:serviceaccount:test-ns:test-writer",
80-
)),
81-
});
82-
let cache = state.linux_agent_cache.clone();
83-
let app = ingest_app(state);
84-
85-
let resp = app
86-
.oneshot(
87-
Request::builder()
88-
.method("POST")
89-
.uri("/ingest/linux_agent/node-1")
90-
.header("Authorization", "Bearer test-token")
91-
.body(Body::from("<<<check_mk>>>\nVersion: 2.5.0\n"))
92-
.unwrap(),
93-
)
94-
.await
95-
.unwrap();
96-
97-
assert_eq!(resp.status(), StatusCode::OK);
98-
cache.run_pending_tasks().await;
99-
assert_eq!(
100-
cache.get("node-1").await.map(|v| v.payload.clone()),
101-
Some(Bytes::from_static(b"<<<check_mk>>>\nVersion: 2.5.0\n"))
102-
);
103-
}
58+
use crate::state::tests::test_app_state;
10459

60+
/// Sanity check that the ingest route is actually wired up behind the
61+
/// kubernetes-token middleware; handler-level behavior is covered in
62+
/// `handlers::ingest::tests`.
10563
#[tokio::test]
106-
async fn linux_agent_ingest_requires_auth() {
64+
async fn system_agent_ingest_requires_auth() {
10765
let state = test_app_state();
10866
let app = ingest_app(state);
10967

11068
let resp = app
11169
.oneshot(
11270
Request::builder()
11371
.method("POST")
114-
.uri("/ingest/linux_agent/node-1")
72+
.uri("/ingest/system_agent/node-1")
11573
.body(Body::from("<<<check_mk>>>\n"))
11674
.unwrap(),
11775
)

metrics-cache/src/ingest/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use axum::body::Bytes;
12
use std::time::Instant;
23

34
pub mod kubelet_stats;
@@ -13,3 +14,11 @@ pub struct MetricsFetcherIngestion<T> {
1314
pub received_at: Instant,
1415
pub payload: T,
1516
}
17+
18+
/// Raw output from a machine-level agent (currently only Linux's
19+
/// `check_mk_agent`, but named generically since a Windows agent could push
20+
/// here too some day). A distinct type rather than a bare [`Bytes`], so the
21+
/// cache's shape stays unambiguous if another `Bytes`-based payload is ever
22+
/// added.
23+
#[derive(Clone, Debug, PartialEq, Eq)]
24+
pub struct SystemAgentOutput(pub Bytes);

metrics-cache/src/state.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use axum::body::Bytes;
21
use kube::Client;
32
use moka::future::Cache;
43
use std::sync::Arc;
@@ -10,6 +9,7 @@ use crate::cli_args::CliArgs;
109
use crate::error::Result;
1110
use crate::host_settings::{AlwaysEmitted, AnnotationKeyPattern, HostSettings};
1211
use crate::ingest::MetricsFetcherIngestion;
12+
use crate::ingest::SystemAgentOutput;
1313
use crate::ingest::kubelet_stats::StatsSummary;
1414
use crate::ingest::reflectors::Stores;
1515

@@ -23,7 +23,7 @@ pub struct AppState<V: TokenValidator> {
2323
pub reader_allowlist: Vec<String>,
2424
pub writer_allowlist: Vec<String>,
2525
pub kubelet_stats_summary_cache: Cache<String, Arc<MetricsFetcherIngestion<StatsSummary>>>,
26-
pub linux_agent_cache: Cache<String, Arc<MetricsFetcherIngestion<Bytes>>>,
26+
pub system_agent_cache: Cache<String, Arc<MetricsFetcherIngestion<SystemAgentOutput>>>,
2727
pub host_settings: Arc<HostSettings>,
2828
}
2929

@@ -49,7 +49,7 @@ impl AppState<Client> {
4949
kubelet_stats_summary_cache: Cache::builder()
5050
.max_capacity(MAX_SUPPORTED_KUBERNETES_NODES)
5151
.build(),
52-
linux_agent_cache: Cache::builder()
52+
system_agent_cache: Cache::builder()
5353
.max_capacity(MAX_SUPPORTED_KUBERNETES_NODES)
5454
.build(),
5555
host_settings: host_settings.into(),
@@ -106,7 +106,7 @@ pub mod tests {
106106
.time_to_live(Duration::from_secs(120))
107107
.max_capacity(10000)
108108
.build(),
109-
linux_agent_cache: Cache::builder()
109+
system_agent_cache: Cache::builder()
110110
.time_to_live(Duration::from_secs(120))
111111
.max_capacity(10000)
112112
.build(),

metrics-fetcher/src/payload.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ impl Payload {
1414
fn metrics_cache_endpoint(&self) -> String {
1515
match self {
1616
Self::KubeletStatsSummary(_) => "/kubelet_stats_summary".to_string(),
17-
Self::CheckmkLinuxAgent { node_name, .. } => format!("/linux_agent/{node_name}"),
17+
Self::CheckmkLinuxAgent { node_name, .. } => format!("/system_agent/{node_name}"),
1818
}
1919
}
2020

0 commit comments

Comments
 (0)