Rust wrapper around the GNS3 server REST API (GNS3 2.2+),
a port of the Python gns3fy library. Use it to drive a GNS3
server from scripts, tooling and network CI/CD pipelines.
[dependencies]
gns3fy = { path = "." }use std::sync::Arc;
use gns3fy::{Gns3Connector, Lookup, Project};
fn main() -> gns3fy::Result<()> {
let server = Arc::new(Gns3Connector::new("http://localhost:3080")?);
let mut lab = Project::with_connector(server.clone()).with_name("API_TEST");
lab.get()?; // project + stats + snapshots + drawings + nodes + links
lab.open()?;
for node in lab.nodes_summary()? { println!("{node}"); }
for link in lab.links_summary()? { println!("{link}"); }
if let Some(node) = lab.get_node_mut(Lookup::Name("alpine-1"))? {
node.stop()?;
node.start()?;
}
lab.create_link("alpine-1", "eth1", "IOU1", "Ethernet0/1")?;
Ok(())
}Run the bundled walkthrough with cargo run --example lab -- http://localhost:3080 API_TEST.
| Python | Rust |
|---|---|
Gns3Connector(url, user, cred, verify, api_version) |
Gns3Connector::new(url) / Gns3Connector::builder(url).user(..).cred(..).verify(..).api_version(..).build() |
Project, Node, Link (pydantic dataclasses) |
Project, Node, Link structs, Default + with_* builders; share the connector with Arc |
name= / project_id= / template_id= keyword pairs |
Lookup::Name(..) / Lookup::Id(..) |
update(**kwargs), create_template(**kwargs) |
take a serde_json::Value object: node.update(json!({"x": 10}))? |
*_summary(is_print=...) |
return Vec of typed rows; rows implement Display (same text the Python version printed) |
validators on node_type, console_type, status, link_type |
enums NodeType, ConsoleType, NodeStatus, ProjectStatus, LinkType; invalid values fail at deserialization |
ValueError / HTTPError |
gns3fy::Error (InvalidInput, NotFound, Api{status,message}, MissingConnector, Http, Json, Io) |
drawing_utils.generate_*_svg(...) |
generate_*_svg(&Options { .. , ..Default::default() }) |
- No printing.
create_node,create_link,create_snapshot,create_drawing,delete_*and the*_summarymethods return data instead ofprinting.create_*return the created object. verifyis honored. Python acceptedverifybut always sentverify=False. Here the default is still "do not verify", but.verify(true)really enables certificate checking.- Port-in-use / link matching is orientation-independent. Python only compared
nodes[0]with node A andnodes[1]with node B, so a link stored the other way round was missed.create_linknow rejects any link that uses either port;delete_linkfinds the link in either orientation. - Missing objects are
NotFounderrors where Python crashed withIndexError/TypeError/AttributeError(unknown node name, unknown project name, unknown template...). - No request timeout by default (as in Python); set one with
.timeout(..)on the builder. - Connector-level calls (
get_projects,get_templates,get_computes, ...) return rawserde_json::Valuelike the Python dicts;Project/Node/Linkgive you typed access. nodes_inventoryreturns a name-sortedBTreeMap(Python used insertion order).
cargo test runs unit tests, doc-tests and integration tests against an in-process mock GNS3 server
(tests/common) using the original Python fixtures (tests/data). No GNS3 server is needed.
0 comments
log in to comment.