diff --git a/src/main.rs b/src/main.rs index 362484e..24f1a9f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,6 +51,12 @@ enum Commands { confirm_timeout: Option, }, + /// Incrementally updates the config from the given config statements + EditConfig { + statement: String, + confirm_timeout: Option, + }, + /// Confirm a previously applied configuration Confirm, @@ -114,7 +120,7 @@ fn main() { netconf_session.lock_configuration().unwrap(); - if let Err(e) = netconf_session.load_configuration(data) { + if let Err(e) = netconf_session.load_configuration(data, "update".into(), "text".into()) { eprintln!("Config load failed: {}", e); std::process::exit(1); } @@ -132,6 +138,32 @@ fn main() { netconf_session.unlock_configuration().unwrap(); } + Commands::EditConfig { + statement, + confirm_timeout, + } => { + netconf_session.lock_configuration().unwrap(); + + for line in statement.split(";") { + if let Err(e) = netconf_session.load_configuration(line.into(), "set".into(), "set".into()) { + eprintln!("Config load failed: {}", e); + std::process::exit(1); + } + } + + let diff_reply = netconf_session + .diff_configuration("text".to_string()) + .unwrap(); + println!("{}", diff_reply); + + eprintln!("Applying configuration..."); + + netconf_session + .apply_configuration(confirm_timeout) + .unwrap(); + + netconf_session.unlock_configuration().unwrap(); + } Commands::Confirm => { eprintln!("Confirming configuration"); @@ -142,7 +174,7 @@ fn main() { let _ = netconf_session.lock_configuration().unwrap(); - if let Err(e) = netconf_session.load_configuration(data) { + if let Err(e) = netconf_session.load_configuration(data, "update".into(), "text".into()) { eprintln!("Config load failed: {}", e); std::process::exit(1); } diff --git a/src/netconf/mod.rs b/src/netconf/mod.rs index 50be10a..727e049 100644 --- a/src/netconf/mod.rs +++ b/src/netconf/mod.rs @@ -201,12 +201,20 @@ impl NETCONFClient { ok.ok_or(NETCONFError::MissingOk) } - pub fn load_configuration(&mut self, cfg: String) -> NETCONFResult<()> { + pub fn load_configuration(&mut self, cfg: String, action: String, format: String) -> NETCONFResult<()> { + let mut cfg_text = None; + let mut cfg_set = None; + match format.as_str() { + "text" => cfg_text = Some(cfg), + "set" => cfg_set = Some(cfg), + _ => unimplemented!(), + } let c = RPC { rpc: RPCCommand::LoadConfiguration { - format: "text".to_string(), - action: "update".to_string(), - cfg, + format, + action, + cfg_text, + cfg_set, }, }; let _ = self.send_rpc(c)?; @@ -233,6 +241,9 @@ impl NETCONFClient { return Err(error.into()); } } + LoadConfigurationResultsEnum::LoadErrorCount(l) => { + eprintln!("{:?}", l); + } LoadConfigurationResultsEnum::Ok => ok = Some(()), } } diff --git a/src/netconf/xml.rs b/src/netconf/xml.rs index cb585d6..a92a41a 100644 --- a/src/netconf/xml.rs +++ b/src/netconf/xml.rs @@ -65,8 +65,13 @@ pub enum RPCCommand { #[serde(rename = "@action")] action: String, + #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "configuration-text")] - cfg: String, + cfg_text: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "configuration-set")] + cfg_set: Option, }, #[serde(rename = "commit-configuration")] @@ -84,12 +89,6 @@ pub enum RPCCommand { #[derive(Debug, Deserialize, Serialize)] pub struct ConfigurationConfirmed {} -#[derive(Debug, Deserialize, Serialize)] -pub struct ConfigurationInformation { - #[serde(rename = "configuration-text")] - pub configuration_text: String, -} - #[derive(Debug, Deserialize, Serialize)] #[serde(rename = "rpc-reply")] pub struct RPCReply { @@ -140,6 +139,16 @@ pub enum LoadConfigurationResultsEnum { #[serde(rename = "rpc-error")] RPCError(RPCError), + + #[serde(rename = "load-error-count")] + LoadErrorCount(LoadErrorCount), +} + +#[derive(Debug, Deserialize, Serialize)] +#[serde(deny_unknown_fields)] +pub struct LoadErrorCount { + #[serde(rename = "$text")] + message: String, } impl Display for RPCReply { @@ -181,6 +190,9 @@ impl Display for RPCReplyCommand { LoadConfigurationResultsEnum::RPCError(error) => { writeln!(f, "{}", error)?; } + LoadConfigurationResultsEnum::LoadErrorCount(l)=> { + writeln!(f, "{:?}", l)?; + } } }