port_plumber/
api.rs

1use std::fs;
2use std::net::IpAddr;
3use std::path::Path;
4use anyhow::Context;
5use axum::{Json, Router, Server, ServiceExt};
6use axum::extract::{State};
7use axum::routing::{get, IntoMakeService};
8use hyperlocal::{SocketIncoming, UnixServerExt};
9use crate::plumber::Plumber;
10use crate::resolver::NameResolver;
11
12pub fn build_server(path: impl AsRef<Path>, name_resolver: NameResolver) -> anyhow::Result<Server<SocketIncoming, IntoMakeService<Router>>> {
13    if path.as_ref().exists() {
14        fs::remove_file(path.as_ref())
15            .context("Could not remove old socket!")?;
16    }
17
18    let app = Router::new()
19        .route("/list", get(list_endpoints))
20        .route("/resolve/:name", get(resolve_endpoint))
21        .with_state(name_resolver);
22
23    let srv = axum::Server::bind_unix(path)?
24        .serve(app.into_make_service());
25
26    Ok(srv)
27}
28
29#[derive(serde::Serialize, serde::Deserialize, Debug)]
30pub struct Endpoint {
31    pub ip: IpAddr,
32}
33
34async fn list_endpoints() -> Json<Vec<Endpoint>> {
35    Json(vec![])
36}
37
38async fn resolve_endpoint(
39    axum::extract::Path(name): axum::extract::Path<String>,
40    State(state): State<NameResolver>
41) -> Json<Option<Endpoint>> {
42    let res = state.resolve(&name)
43        .map(|ip| Endpoint { ip });
44
45    Json(res)
46}