Files
harmony/opnsense-api/examples/install_package.rs
Jean-Gabriel Gill-Couture da90dc55ad
Some checks failed
Run Check Script / check (pull_request) Failing after 19s
chore: cargo fmt across workspace
2026-03-25 23:20:57 -04:00

89 lines
3.1 KiB
Rust

//! Example: install OPNsense packages (os-haproxy, os-caddy) via the firmware API.
//!
//! ```text
//! cargo run --example install_package -- os-haproxy
//! cargo run --example install_package -- os-caddy os-acme
//! ```
//!
//! Calls `POST /api/core/firmware/install/<pkg_name>` for each package.
//! These are the standard OPNsense plugin packages.
use std::env;
use opnsense_api::client::OpnsenseClient;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct FirmwareActionResponse {
pub status: String,
#[serde(default)]
pub msg_uuid: String,
#[serde(default)]
pub status_msg: Option<String>,
}
fn build_client() -> OpnsenseClient {
let base_url =
env::var("OPNSENSE_BASE_URL").unwrap_or_else(|_| "https://192.168.1.1/api".to_string());
match (
env::var("OPNSENSE_API_KEY").ok(),
env::var("OPNSENSE_API_SECRET").ok(),
) {
(Some(key), Some(secret)) => OpnsenseClient::builder()
.base_url(&base_url)
.auth_from_key_secret(&key, &secret)
.skip_tls_verify()
.timeout_secs(300)
.build()
.expect("failed to build HTTP client"),
_ => {
eprintln!("ERROR: OPNSENSE_API_KEY and OPNSENSE_API_SECRET must be set.");
eprintln!(" export OPNSENSE_API_KEY=your_key");
eprintln!(" export OPNSENSE_API_SECRET=your_secret");
eprintln!(" export OPNSENSE_BASE_URL=https://your-firewall/api");
std::process::exit(1);
}
}
}
#[tokio::main]
async fn main() {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
let packages: Vec<String> = env::args().skip(1).collect();
if packages.is_empty() {
eprintln!("Usage: cargo run --example install_package -- <package1> [package2 ...]");
eprintln!("Example: cargo run --example install_package -- os-haproxy os-caddy");
std::process::exit(1);
}
let client = build_client();
println!();
println!("╔═══════════════════════════════════════════════════════════╗");
println!("║ OPNsense Package Installer ║");
println!("╚═══════════════════════════════════════════════════════════╝");
println!();
for pkg in &packages {
println!(" Installing {pkg} ...");
log::info!("POST /api/core/firmware/install/{pkg}");
let response: FirmwareActionResponse = client
.post_typed("core", "firmware", &format!("install/{pkg}"), None::<&()>)
.await
.expect("API call failed");
if response.status == "ok" {
println!("{pkg} installed (msg_uuid: {})", response.msg_uuid);
} else {
println!("{pkg} failed: {:?}", response.status_msg);
}
}
println!();
println!(" Done.");
}