xbp 10.15.4

XBP is a zero-config build pack that can also interact with proxies, kafka, sockets, synthetic monitors.
Documentation
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone)]
pub struct PortInfo {
    pub port: u16,
    pub pid: Option<String>,
    pub local_addr: String,
    pub remote_addr: String,
    pub state: String,
    pub process: String,
}

#[derive(Serialize, Deserialize)]
pub struct PortsResponse {
    pub ports: Vec<PortInfo>,
}

#[derive(Serialize, Deserialize)]
pub struct SystemctlService {
    pub name: String,
    pub status: String,
    pub active: bool,
    pub enabled: bool,
}

#[derive(Serialize, Deserialize)]
pub struct SystemctlResponse {
    pub services: Vec<SystemctlService>,
}

#[derive(Serialize, Deserialize)]
pub struct Pm2Process {
    pub name: String,
    pub pid: Option<u32>,
    pub status: String,
    pub cpu: Option<f64>,
    pub memory: Option<f64>,
    pub uptime: Option<String>,
}

#[derive(Serialize, Deserialize)]
pub struct Pm2Response {
    pub processes: Vec<Pm2Process>,
}

#[derive(Serialize, Deserialize)]
pub struct ServiceInfo {
    pub name: String,
    pub target: String,
    pub port: u16,
    pub branch: String,
    pub url: Option<String>,
}

#[derive(Serialize, Deserialize)]
pub struct ServicesResponse {
    pub services: Vec<ServiceInfo>,
}

#[derive(Serialize, Deserialize)]
pub struct BinaryDownloadRequest {
    pub url: String,
    pub name: String,
    pub args: Option<Vec<String>>,
}

#[derive(Serialize, Deserialize)]
pub struct BinaryDownloadResponse {
    pub success: bool,
    pub message: String,
    pub pm2_name: Option<String>,
}

#[derive(Serialize, Deserialize)]
pub struct ErrorResponse {
    pub error: String,
}

#[derive(Serialize, Deserialize)]
pub struct HealthResponse {
    pub status: String,
    pub version: String,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RouteTarget {
    pub url: String,
    #[serde(default = "RouteTarget::default_weight")]
    pub weight: u32,
}

impl RouteTarget {
    fn default_weight() -> u32 {
        1
    }
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RouteEntry {
    pub domain: String,
    pub targets: Vec<RouteTarget>,
    #[serde(default)]
    pub conditions: Option<RouteConditions>,
}

#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct RouteConditions {
    #[serde(default)]
    pub header: Option<String>,
    #[serde(default)]
    pub path_prefix: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct RoutesResponse {
    pub routes: Vec<RouteEntry>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct CreateRouteRequest {
    pub domain: String,
    pub targets: Vec<RouteTarget>,
    #[serde(default)]
    pub conditions: Option<RouteConditions>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct CreateRouteResponse {
    pub success: bool,
    pub domain: String,
    pub target_count: usize,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ExecCommandRequest {
    pub command: String,
    #[serde(default)]
    pub args: Vec<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ExecCommandResponse {
    pub success: bool,
    pub command: String,
    pub args: Vec<String>,
    pub exit_code: i32,
    pub stdout: String,
    pub stderr: String,
    pub duration_ms: u128,
    pub truncated_stdout: bool,
    pub truncated_stderr: bool,
}