You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.1 KiB
Rust

pub mod v1 {
use std::process::Stdio;
use serde::Serialize;
use crate::{read_config, Result};
#[derive(Serialize)]
pub enum JsonResult<T, E> {
#[serde(rename = "ok")]
Ok(T),
#[serde(rename = "error")]
Err(E),
}
pub type ApiResult<T> = JsonResult<T, &'static str>;
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub enum Status {
Up,
Down,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Service {
name: String,
public_url: Option<String>,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetConfigurationResponse {
hosts: Vec<String>,
services: Vec<Service>,
}
pub async fn get_configuration() -> Result<GetConfigurationResponse> {
let config = read_config().await?;
Ok(GetConfigurationResponse {
hosts: config.hosts.into_keys().collect(),
services: config
.services
.into_iter()
.map(|(name, si)| Service {
name,
public_url: si.public_url,
})
.collect(),
})
}
pub async fn get_host_status(name: &str) -> Result<ApiResult<Status>> {
let config = read_config().await?;
let ip = match config.hosts.get(name) {
Some(s) => s,
None => return Ok(JsonResult::Err("unknown host")),
};
let mut ping = tokio::process::Command::new("ping")
.arg("-c1")
.arg("-w2")
.arg(ip)
.stdout(Stdio::null())
.stderr(Stdio::null())
.stdin(Stdio::null())
.spawn()?;
let status = ping.wait().await?;
Ok(JsonResult::Ok(match status.code() {
Some(0) => Status::Up,
_ => Status::Down,
}))
}
pub async fn get_service_status(name: &str) -> Result<ApiResult<Status>> {
let config = read_config().await?;
let service = match config.services.get(name) {
Some(s) => s,
None => return Ok(JsonResult::Err("unknown service")),
};
let endpoint = &service.url;
let resp = reqwest::get(endpoint)
.await
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
let status = resp.status().as_u16();
Ok(JsonResult::Ok(if (200..300).contains(&status) {
Status::Up
} else {
Status::Down
}))
}
}