xbp 10.17.2

XBP is a zero-config build pack that can also interact with proxies, kafka, sockets, synthetic monitors.
Documentation
use crate::cli::commands::{
    NetworkConfigSubCommand, NetworkFloatingIpSubCommand, NetworkSubCommand,
};
use crate::sdk::network::{
    add_floating_ip, list_floating_ips, list_network_config_sources, AddFloatingIpRequest,
};
use anyhow::Result;

pub async fn run_network(command: NetworkSubCommand, _debug: bool) -> Result<()> {
    match command {
        NetworkSubCommand::FloatingIp(floating_ip) => match floating_ip.command {
            NetworkFloatingIpSubCommand::Add {
                ip,
                cidr,
                interface,
                label,
                apply,
                dry_run,
            } => {
                let response = add_floating_ip(AddFloatingIpRequest {
                    ip,
                    cidr,
                    interface,
                    label,
                    apply,
                    dry_run,
                })
                .await?;
                println!("{}", serde_json::to_string_pretty(&response)?);
            }
            NetworkFloatingIpSubCommand::List { json } => {
                let response = list_floating_ips().await?;
                if json {
                    println!("{}", serde_json::to_string_pretty(&response)?);
                } else {
                    print_floating_ips_table(&response.items);
                }
            }
        },
        NetworkSubCommand::Config(config) => match config.command {
            NetworkConfigSubCommand::List { json } => {
                let response = list_network_config_sources().await?;
                if json {
                    println!("{}", serde_json::to_string_pretty(&response)?);
                } else {
                    print_network_config_sources_table(
                        &response.sources,
                        response.detected_backend,
                    );
                }
            }
        },
    }

    Ok(())
}

fn print_floating_ips_table(items: &[crate::sdk::network::FloatingIpEntry]) {
    if items.is_empty() {
        println!("No floating IP entries found.");
        return;
    }

    println!(
        "{:<8} {:<14} {:<20} {:<8} {:<10} SOURCE",
        "BACKEND", "INTERFACE", "IP/CIDR", "RUNTIME", "CONFIG"
    );
    println!("{}", "-".repeat(96));
    for item in items {
        println!(
            "{:<8} {:<14} {:<20} {:<8} {:<10} {}",
            item.backend,
            item.interface,
            item.address_cidr,
            if item.runtime { "yes" } else { "no" },
            if item.config { "yes" } else { "no" },
            item.source_file.as_deref().unwrap_or("-"),
        );
    }
}

fn print_network_config_sources_table(
    sources: &[crate::sdk::network::NetworkConfigSource],
    detected_backend: crate::sdk::network::NetworkBackend,
) {
    println!("Detected backend: {}", detected_backend);
    if sources.is_empty() {
        println!("No network config sources discovered.");
        return;
    }

    println!("{:<8} {:<6} PATH", "BACKEND", "EXISTS");
    println!("{}", "-".repeat(96));
    for source in sources {
        println!(
            "{:<8} {:<6} {}",
            source.backend,
            if source.exists { "yes" } else { "no" },
            source.path
        );
    }
}