Added REST route to get the list of bridges

This commit is contained in:
Pierre HUBERT 2025-05-26 20:43:19 +02:00
parent de33c7d521
commit a8171375a8
5 changed files with 46 additions and 1 deletions

View File

@ -111,3 +111,6 @@ pub const API_TOKEN_RIGHT_PATH_MAX_LENGTH: usize = 255;
/// Qemu image program path
pub const QEMU_IMAGE_PROGRAM: &str = "/usr/bin/qemu-img";
/// IP program path
pub const IP_PROGRAM: &str = "/usr/sbin/ip";

View File

@ -188,3 +188,7 @@ pub async fn number_vcpus() -> HttpResult {
pub async fn networks_list() -> HttpResult {
Ok(HttpResponse::Ok().json(net_utils::net_list()))
}
pub async fn bridges_list() -> HttpResult {
Ok(HttpResponse::Ok().json(net_utils::bridges_list()?))
}

View File

@ -48,6 +48,10 @@ async fn main() -> std::io::Result<()> {
constants::QEMU_IMAGE_PROGRAM,
"QEMU disk image utility is required to manipulate QCow2 files!",
);
exec_utils::check_program(
constants::IP_PROGRAM,
"ip is required to access bridges information!",
);
log::debug!("Create required directory, if missing");
files_utils::create_directory_if_missing(AppConfig::get().iso_storage_path()).unwrap();
@ -137,6 +141,10 @@ async fn main() -> std::io::Result<()> {
"/api/server/networks",
web::get().to(server_controller::networks_list),
)
.route(
"/api/server/bridges",
web::get().to(server_controller::bridges_list),
)
// Auth controller
.route(
"/api/auth/local",

View File

@ -1,6 +1,8 @@
use crate::constants;
use nix::sys::socket::{AddressFamily, SockaddrLike};
use std::collections::HashMap;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::process::Command;
use std::str::FromStr;
use sysinfo::Networks;
@ -68,7 +70,7 @@ pub fn net_list() -> Vec<String> {
/// Get the list of available network interfaces associated with their IP address
pub fn net_list_and_ips() -> anyhow::Result<HashMap<String, Vec<IpAddr>>> {
let addrs = nix::ifaddrs::getifaddrs().unwrap();
let addrs = nix::ifaddrs::getifaddrs()?;
let mut res = HashMap::new();
@ -136,6 +138,31 @@ pub fn net_list_and_ips() -> anyhow::Result<HashMap<String, Vec<IpAddr>>> {
Ok(res)
}
#[derive(serde::Deserialize)]
struct IPBridgeInfo {
ifname: String,
}
/// Get the list of bridge interfaces
pub fn bridges_list() -> anyhow::Result<Vec<String>> {
let mut cmd = Command::new(constants::IP_PROGRAM);
cmd.args(["-json", "link", "show", "type", "bridge"]);
let output = cmd.output()?;
if !output.status.success() {
anyhow::bail!(
"{} failed, status: {}, stderr: {}",
constants::IP_PROGRAM,
output.status,
String::from_utf8_lossy(&output.stderr)
);
}
// Parse JSON result
let res: Vec<IPBridgeInfo> = serde_json::from_str(&String::from_utf8_lossy(&output.stdout))?;
Ok(res.iter().map(|ip| ip.ifname.clone()).collect())
}
#[cfg(test)]
mod tests {
use crate::utils::net_utils::{

View File

@ -38,6 +38,9 @@ sudo netplan apply
```bash
sudo brctl show
# Or
ip link show type bridge
```
## Reference