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
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
|
|
}))
|
|
}
|
|
}
|