Generate typed API models for HAProxy, Caddy, Firewall, VLAN, LAGG,
WireGuard (client/server/general), and regenerate Dnsmasq. All core
modules validated against a live OPNsense 26.1.2 instance.
Codegen improvements:
- Add --module-name and --api-key CLI flags for controlling output
filenames and API response envelope keys
- Fix enum variant names starting with digits (prefix with V)
- Use value="" XML attribute for wire values instead of element names
- Handle unknown *Field types as opn_string (select widget safe)
- Forgiving enum deserialization (warn instead of error on unknown)
- Handle empty arrays in opn_string deserializer
Add per-module examples (list_haproxy, list_caddy, list_vlan, etc.)
and utility examples (raw_get, check_package, install_and_wait).
Extract shared client setup into examples/common/mod.rs.
Fix post_typed sending empty JSON body ({}) instead of no body,
which was causing 400 errors on firmware endpoints.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
46 lines
1.5 KiB
Rust
46 lines
1.5 KiB
Rust
//! Example: fetch a raw JSON response from any OPNsense API endpoint.
|
|
//!
|
|
//! ```text
|
|
//! cargo run --example raw_get -- interfaces vlan_settings get
|
|
//! ```
|
|
|
|
mod common;
|
|
|
|
use std::env;
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
let client = common::client_from_env();
|
|
|
|
let args: Vec<String> = env::args().skip(1).collect();
|
|
if args.len() != 3 {
|
|
eprintln!("Usage: cargo run --example raw_get -- <module> <controller> <command>");
|
|
eprintln!("Example: cargo run --example raw_get -- interfaces vlan_settings get");
|
|
std::process::exit(1);
|
|
}
|
|
|
|
let response: serde_json::Value = client
|
|
.get_typed(&args[0], &args[1], &args[2])
|
|
.await
|
|
.expect("API call failed");
|
|
|
|
// Print just the top-level keys and their types
|
|
if let Some(obj) = response.as_object() {
|
|
println!("Top-level keys:");
|
|
for (key, value) in obj {
|
|
let type_str = match value {
|
|
serde_json::Value::Object(m) => format!("object ({} keys)", m.len()),
|
|
serde_json::Value::Array(a) => format!("array ({} items)", a.len()),
|
|
serde_json::Value::String(s) => format!("string: {:?}", &s[..s.len().min(50)]),
|
|
serde_json::Value::Number(n) => format!("number: {n}"),
|
|
serde_json::Value::Bool(b) => format!("bool: {b}"),
|
|
serde_json::Value::Null => "null".to_string(),
|
|
};
|
|
println!(" {key}: {type_str}");
|
|
}
|
|
}
|
|
|
|
println!("\nFull JSON:");
|
|
println!("{}", serde_json::to_string_pretty(&response).unwrap());
|
|
}
|