1use netconf_rust::{Datastore, Session};
2
3#[tokio::main]
4async fn main() -> netconf_rust::Result<()> {
5 let session = Session::connect("localhost", 830, "netconf", "netconf").await?;
7
8 println!("Session ID: {}", session.session_id());
9 println!("Framing: {:?}", session.framing_mode());
10 println!("Capabilities: {}", session.server_capabilities().join(", "));
11
12 let config = session.get_config(Datastore::Running, None).await?;
14 println!("\n=== Running config ===\n{config}");
15
16 let interfaces = session
18 .get_config(
19 Datastore::Running,
20 Some(r#"<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"/>"#),
21 )
22 .await?;
23 println!("\n=== Interfaces ===\n{interfaces}");
24
25 let payload = session.get_config_payload(Datastore::Running, None).await?;
27 println!("\n=== Config payload size: {} bytes ===", payload.len());
28
29 let mut reader = payload.reader();
31 let mut element_count = 0;
32 loop {
33 match reader.read_event() {
34 Ok(quick_xml::events::Event::Start(_)) => element_count += 1,
35 Ok(quick_xml::events::Event::Eof) => break,
36 _ => {}
37 }
38 }
39 println!("Total XML elements: {element_count}");
40
41 session.lock(Datastore::Candidate).await?;
45 println!("\n=== Locked candidate ===");
46
47 match session
48 .edit_config(
49 Datastore::Candidate,
50 r#"
51 <netconf-server xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-server">
52 <listen>
53 <endpoint>
54 <name>default-ssh</name>
55 <ssh>
56 <tcp-server-parameters>
57 <local-address>0.0.0.0</local-address>
58 </tcp-server-parameters>
59 </ssh>
60 </endpoint>
61 </listen>
62 </netconf-server>
63 "#,
64 )
65 .await
66 {
67 Ok(()) => {
68 println!("Edited candidate config");
69 session.commit().await?;
70 println!("Committed");
71 }
72 Err(e) => {
73 eprintln!("edit-config failed (NACM?): {e}");
74 }
75 }
76
77 session.unlock(Datastore::Candidate).await?;
78 println!("Unlocked candidate");
79
80 println!("\n=== Pipelining ===");
82 let fut1 = session
83 .rpc_send("<get-config><source><running/></source></get-config>")
84 .await?;
85 let fut2 = session
86 .rpc_send("<get-config><source><running/></source></get-config>")
87 .await?;
88 let fut3 = session
89 .rpc_send("<get-config><source><running/></source></get-config>")
90 .await?;
91
92 println!(
93 "Sent 3 RPCs (message-ids: {}, {}, {})",
94 fut1.message_id(),
95 fut2.message_id(),
96 fut3.message_id()
97 );
98
99 let reply1 = fut1.response().await?;
100 let reply2 = fut2.response().await?;
101 let reply3 = fut3.response().await?;
102 println!(
103 "Got 3 replies (message-ids: {}, {}, {})",
104 reply1.message_id, reply2.message_id, reply3.message_id
105 );
106
107 println!("\n=== Raw RPC ===");
109 let reply = session
110 .rpc_raw("<get-schema><identifier>ietf-interfaces</identifier></get-schema>")
111 .await?;
112 match reply.body {
113 netconf_rust::RpcReplyBody::Data(payload) => {
114 println!("Got schema ({} bytes)", payload.len())
115 }
116 netconf_rust::RpcReplyBody::Ok => println!("ok"),
117 netconf_rust::RpcReplyBody::Error(errors) => {
118 for e in &errors {
119 eprintln!("Error: {}: {}", e.error_tag, e.error_message);
120 }
121 }
122 }
123
124 session.close_session().await?;
126 println!("\nSession closed (state: {})", session.state());
127
128 Ok(())
129}