summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2024-09-27 12:16:23 -0500
committerToby Vincent <tobyv@tobyvin.dev>2024-09-27 12:16:23 -0500
commit1218705fd52771a902eb6c64762623d0c6a13173 (patch)
treeafdded96bff04b8e22704e54dedff5bf78e28229
parentfd992d7e3c03f37fbcafe9d3f26c72a2ead3b2a7 (diff)
refactor: merge Check into Status type
-rw-r--r--src/api.rs32
-rw-r--r--src/api/services.rs6
-rw-r--r--src/lib.rs16
-rw-r--r--src/service.rs10
-rw-r--r--src/service/http.rs11
-rw-r--r--src/service/systemd.rs20
-rw-r--r--src/service/tcp.rs9
7 files changed, 44 insertions, 60 deletions
diff --git a/src/api.rs b/src/api.rs
index e6a91ba..8cf66ea 100644
--- a/src/api.rs
+++ b/src/api.rs
@@ -3,7 +3,7 @@ use std::collections::HashMap;
use axum::{extract::State, response::IntoResponse, Json};
use serde::{Deserialize, Serialize};
-use crate::{service::Services, Check, Error, Status};
+use crate::{service::Services, Error, Status};
pub mod services;
@@ -19,15 +19,13 @@ pub fn router() -> axum::Router<Services> {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Health {
pub status: Status,
- pub output: Option<String>,
- pub checks: HashMap<String, Check>,
+ pub checks: HashMap<String, Status>,
}
impl<T: std::error::Error> From<T> for Health {
fn from(value: T) -> Self {
Health {
- status: Status::Fail,
- output: Some(value.to_string()),
+ status: value.into(),
..Default::default()
}
}
@@ -42,30 +40,20 @@ impl IntoResponse for Health {
pub async fn healthcheck(State(services): State<Services>) -> Health {
let checks = match services.check().await {
Ok(c) => c,
- Err(err) => {
- return Health {
- status: Status::Fail,
- output: Some(err.to_string()),
- ..Default::default()
- }
- }
+ Err(err) => return err.into(),
};
- let (status, output) = match checks
+ let status = match checks
.values()
- .filter(|s| !matches!(s.status, Status::Pass))
+ .filter(|s| !matches!(s, Status::Pass))
.count()
{
- 0 => (Status::Pass, None),
- 1 => (Status::Fail, Some("1 issue detected".to_string())),
- n => (Status::Fail, Some(format!("{n} issues detected"))),
+ 0 => Status::Pass,
+ 1 => Status::Fail(Some("1 issue detected".to_string())),
+ n => Status::Fail(Some(format!("{n} issues detected"))),
};
- Health {
- status,
- output,
- checks,
- }
+ Health { status, checks }
}
pub async fn fallback(uri: axum::http::Uri) -> Error {
diff --git a/src/api/services.rs b/src/api/services.rs
index 59e891f..63018f1 100644
--- a/src/api/services.rs
+++ b/src/api/services.rs
@@ -7,7 +7,7 @@ use axum::{
use axum_extra::routing::Resource;
use serde::{Deserialize, Serialize};
-use crate::{service::Services, Check, Error, Status};
+use crate::{service::Services, Error, Status};
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ServiceQuery {
@@ -22,7 +22,7 @@ pub fn router() -> Router<Services> {
pub async fn index(
Query(query): Query<ServiceQuery>,
State(services): State<Services>,
-) -> Result<Json<HashMap<String, Check>>, Error> {
+) -> Result<Json<HashMap<String, Status>>, Error> {
services
.check_filtered(|name| (!query.name.as_ref().is_some_and(|s| s != name)))
.await
@@ -32,7 +32,7 @@ pub async fn index(
pub async fn show(
Path(name): Path<String>,
State(services): State<Services>,
-) -> Result<Check, Error> {
+) -> Result<Status, Error> {
services
.check_one(&name)
.await
diff --git a/src/lib.rs b/src/lib.rs
index 2c9fa91..1ccecf7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -11,21 +11,21 @@ pub mod error;
pub mod service;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
-#[serde(rename_all = "lowercase")]
+#[serde(rename_all = "lowercase", tag = "status", content = "output")]
pub enum Status {
#[default]
Pass,
- Fail,
- Warn,
+ Fail(Option<String>),
+ Warn(Option<String>),
}
-#[derive(Debug, Clone, Default, Serialize, Deserialize)]
-pub struct Check {
- pub status: Status,
- pub output: Option<String>,
+impl<T: std::error::Error> From<T> for Status {
+ fn from(value: T) -> Self {
+ Status::Fail(Some(value.to_string()))
+ }
}
-impl axum::response::IntoResponse for Check {
+impl axum::response::IntoResponse for Status {
fn into_response(self) -> axum::response::Response {
axum::Json(self).into_response()
}
diff --git a/src/service.rs b/src/service.rs
index 677db17..bae6867 100644
--- a/src/service.rs
+++ b/src/service.rs
@@ -6,7 +6,7 @@ use serde::Deserialize;
use systemd::Systemd;
use tcp::Tcp;
-use crate::{Check, Error};
+use crate::{Error, Status};
pub mod http;
pub mod systemd;
@@ -33,7 +33,7 @@ impl Services {
reqwest::Client::new()
}
- pub async fn check(&self) -> Result<HashMap<String, Check>, Error> {
+ pub async fn check(&self) -> Result<HashMap<String, Status>, Error> {
let checks = self
.inner
.values()
@@ -50,11 +50,11 @@ impl Services {
.collect::<HashMap<_, _>>())
}
- pub async fn check_one(&self, name: &str) -> Option<Result<Check, Error>> {
+ pub async fn check_one(&self, name: &str) -> Option<Result<Status, Error>> {
Some(self.inner.get(name)?.check(self.client.clone()).await)
}
- pub async fn check_filtered<P>(&self, mut predicate: P) -> Result<HashMap<String, Check>, Error>
+ pub async fn check_filtered<P>(&self, mut predicate: P) -> Result<HashMap<String, Status>, Error>
where
P: FnMut(&String) -> bool,
{
@@ -85,7 +85,7 @@ pub enum Service {
}
impl Service {
- pub async fn check(&self, client: reqwest::Client) -> Result<Check, Error> {
+ pub async fn check(&self, client: reqwest::Client) -> Result<Status, Error> {
match self {
Service::Http(http) => http.check(client).await,
Service::Tcp(tcp) => tcp.check().await,
diff --git a/src/service/http.rs b/src/service/http.rs
index 15696a1..fb3ff13 100644
--- a/src/service/http.rs
+++ b/src/service/http.rs
@@ -2,7 +2,7 @@ use std::fmt::Display;
use serde::Deserialize;
-use crate::{Check, Error, Status};
+use crate::{Error, Status};
#[derive(Debug, Clone, Deserialize)]
pub struct Http {
@@ -30,7 +30,7 @@ impl Display for Http {
}
impl Http {
- pub async fn check(&self, client: reqwest::Client) -> Result<Check, Error> {
+ pub async fn check(&self, client: reqwest::Client) -> Result<Status, Error> {
let status_code = client
.request(self.method.parse().map_err(|_| Error::Method)?, &self.url)
.send()
@@ -39,11 +39,8 @@ impl Http {
.as_u16();
match status_code == self.status_code {
- true => Ok(Check::default()),
- false => Ok(Check {
- status: Status::Fail,
- output: Some(format!("Status code: {status_code}")),
- }),
+ true => Ok(Status::Pass),
+ false => Ok(Status::Fail(Some(format!("Status code: {status_code}")))),
}
}
}
diff --git a/src/service/systemd.rs b/src/service/systemd.rs
index 2e3b74c..45f3bf9 100644
--- a/src/service/systemd.rs
+++ b/src/service/systemd.rs
@@ -2,7 +2,7 @@ use std::{fmt::Display, process::Command};
use serde::Deserialize;
-use crate::{Check, Error, Status};
+use crate::{Error, Status};
#[derive(Debug, Clone, Deserialize)]
pub struct Systemd {
@@ -16,18 +16,20 @@ impl Display for Systemd {
}
impl Systemd {
- pub async fn check(&self) -> Result<Check, Error> {
+ pub async fn check(&self) -> Result<Status, Error> {
let output = Command::new("systemctl")
.arg("is-active")
.arg(&self.service)
.output()?;
- let stdout = String::from_utf8_lossy(&output.stdout).to_string();
- Ok((!output.status.success())
- .then(|| Check {
- status: Status::Fail,
- output: Some(format!("Service state: {}", stdout.trim())),
- })
- .unwrap_or_default())
+ let status = match output.status.success() {
+ true => Status::Pass,
+ false => {
+ let stdout = String::from_utf8_lossy(&output.stdout).trim().to_string();
+ Status::Fail(Some(format!("Service state: {}", stdout)))
+ }
+ };
+
+ Ok(status)
}
}
diff --git a/src/service/tcp.rs b/src/service/tcp.rs
index 5f55091..87e696a 100644
--- a/src/service/tcp.rs
+++ b/src/service/tcp.rs
@@ -2,7 +2,7 @@ use std::fmt::Display;
use serde::Deserialize;
-use crate::{Check, Error, Status};
+use crate::{Error, Status};
#[derive(Debug, Clone, Deserialize)]
pub struct Tcp {
@@ -16,13 +16,10 @@ impl Display for Tcp {
}
impl Tcp {
- pub async fn check(&self) -> Result<Check, Error> {
+ pub async fn check(&self) -> Result<Status, Error> {
Ok(std::net::TcpStream::connect(&self.address)
.err()
- .map(|err| Check {
- status: Status::Fail,
- output: Some(format!("error: {err}")),
- })
+ .map(Into::into)
.unwrap_or_default())
}
}