Added routing/rule, ip/route. updated system/health, ip/dhcp-client

This commit is contained in:
Ishan Jain 2022-05-01 19:38:09 +05:30
parent 4d21251a5b
commit 8b04dbb4d2
12 changed files with 421 additions and 5 deletions

View File

@ -2,14 +2,14 @@ pub use crate::ip::types::DhcpClient;
use crate::{Client, ClientError};
use serde::{Deserialize, Serialize};
/// list all DHCPv4 Clients
/// List all DHCPv4 Clients
pub async fn list(client: &mut Client) -> Result<Vec<DhcpClient>, ClientError> {
let url = format!("{}/dhcp-client", super::BASE);
client.execute_get::<Vec<DhcpClient>>(&url).await
}
/// get a specific DHCPv4 Client
/// Get a specific DHCPv4 Client
pub async fn get(client: &mut Client, id: &str) -> Result<DhcpClient, ClientError> {
let url = format!("{}/dhcp-client/{}", super::BASE, id);

View File

@ -1,6 +1,7 @@
pub mod address;
pub mod dhcp_client;
pub mod dhcp_server;
pub mod route;
mod types;
const BASE: &str = "rest/ip";

51
src/ip/route.rs Normal file
View File

@ -0,0 +1,51 @@
pub use crate::ip::types::Route;
use crate::{Client, ClientError};
use serde::{Deserialize, Serialize};
/// List all IPv4 Routes
pub async fn list(client: &mut Client) -> Result<Vec<Route>, ClientError> {
let url = format!("{}/route", super::BASE);
client.execute_get::<Vec<Route>>(&url).await
}
/// Get a specific IPv4 Route
pub async fn get(client: &mut Client, rid: &str) -> Result<Route, ClientError> {
let url = format!("{}/route/{}", super::BASE, rid);
client.execute_get::<Route>(&url).await
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct RouteInput {
pub numbers: String,
}
/// Disable an IPv4 Route
pub async fn disable(client: &mut Client, input: RouteInput) -> Result<(), ClientError> {
let url = format!("{}/route/disable", super::BASE);
client
.execute_post_with_no_response::<RouteInput>(&url, input)
.await
}
/// Enable an IPv4 Route
pub async fn enable(client: &mut Client, input: RouteInput) -> Result<(), ClientError> {
let url = format!("{}/route/enable", super::BASE);
client
.execute_post_with_no_response::<RouteInput>(&url, input)
.await
}
/// Remove a IPv4 Route
pub async fn remove(client: &mut Client, input: RouteInput) -> Result<(), ClientError> {
let url = format!("{}/route/remove", super::BASE);
client
.execute_post_with_no_response::<RouteInput>(&url, input)
.await
}
//TODO(ishan): add set/unset/reset

View File

@ -1,4 +1,4 @@
use crate::serde_helpers::deserialize_bool;
use crate::serde_helpers::{deserialize_bool, deserialize_u16};
use serde::{Deserialize, Serialize};
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
@ -139,3 +139,49 @@ pub struct DhcpClient {
#[serde(rename = "use-peer-ntp", deserialize_with = "deserialize_bool")]
pub use_peer_ntp: bool,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Route {
#[serde(rename = ".id")]
pub id: String,
pub comment: Option<String>,
#[serde(default, deserialize_with = "deserialize_bool")]
pub disabled: bool,
pub distance: String,
#[serde(rename = "dst-address")]
pub dst_address: String,
#[serde(deserialize_with = "deserialize_bool")]
pub dynamic: bool,
#[serde(default, deserialize_with = "deserialize_bool")]
pub ecmp: bool,
pub gateway: String,
#[serde(rename = "hw-offloaded", deserialize_with = "deserialize_bool")]
pub hw_offloaded: bool,
#[serde(rename = "immediate-gw")]
pub immediate_gw: String,
#[serde(deserialize_with = "deserialize_bool")]
pub inactive: bool,
#[serde(rename = "pref-src")]
pub pref_src: Option<String>,
#[serde(rename = "routing-table")]
pub routing_table: String,
#[serde(deserialize_with = "deserialize_u16")]
pub scope: u16,
#[serde(default, rename = "static", deserialize_with = "deserialize_bool")]
pub static_field: bool,
#[serde(rename = "suppress-hw-offload", deserialize_with = "deserialize_bool")]
pub suppress_hw_offload: bool,
#[serde(
default,
rename = "target-scope",
deserialize_with = "deserialize_bool"
)]
pub target_scope: bool,
#[serde(default, deserialize_with = "deserialize_bool")]
pub active: bool,
#[serde(default, deserialize_with = "deserialize_bool")]
pub connect: bool,
#[serde(rename = "local-address")]
pub local_address: Option<String>,
}

View File

@ -1,7 +1,9 @@
mod client;
mod serde_helpers;
pub mod interface;
pub mod ip;
mod serde_helpers;
pub mod routing;
pub mod system;
pub use client::*;

4
src/routing/mod.rs Normal file
View File

@ -0,0 +1,4 @@
pub mod rule;
mod types;
const BASE: &str = "rest/routing";

52
src/routing/rule.rs Normal file
View File

@ -0,0 +1,52 @@
use serde::{Deserialize, Serialize};
use crate::{Client, ClientError};
pub use crate::routing::types::Rule;
/// List all routing rules
pub async fn list(client: &mut Client) -> Result<Vec<Rule>, ClientError> {
let url = format!("{}/rule", super::BASE);
client.execute_get::<Vec<Rule>>(&url).await
}
/// Get a specific routing rule
pub async fn get(client: &mut Client, id: &str) -> Result<Rule, ClientError> {
let url = format!("{}/rule/{}", super::BASE, id);
client.execute_get::<Rule>(&url).await
}
// TODO(ishan): Figure out a smarter way to implement these common operations
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct RuleInput {
pub numbers: String,
}
/// Disable a rule
pub async fn disable(client: &mut Client, input: RuleInput) -> Result<(), ClientError> {
let url = format!("{}/rule/disable", super::BASE);
client
.execute_post_with_no_response::<RuleInput>(&url, input)
.await
}
/// Enable a rule
pub async fn enable(client: &mut Client, input: RuleInput) -> Result<(), ClientError> {
let url = format!("{}/rule/enable", super::BASE);
client
.execute_post_with_no_response::<RuleInput>(&url, input)
.await
}
/// Remove a rule
pub async fn remove(client: &mut Client, input: RuleInput) -> Result<(), ClientError> {
let url = format!("{}/rule/remove", super::BASE);
client
.execute_post_with_no_response::<RuleInput>(&url, input)
.await
}

19
src/routing/types.rs Normal file
View File

@ -0,0 +1,19 @@
use crate::serde_helpers::deserialize_bool;
use serde::{Deserialize, Serialize};
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Rule {
#[serde(rename = ".id")]
pub id: String,
#[serde(rename = ".nextid")]
pub nextid: Option<String>,
pub action: String,
#[serde(default, deserialize_with = "deserialize_bool")]
pub disabled: bool,
#[serde(default, deserialize_with = "deserialize_bool")]
pub inactive: bool,
#[serde(rename = "src-address")]
pub src_address: String,
pub table: String,
}

View File

@ -52,6 +52,7 @@ where
}
}
#[allow(unused)]
pub fn maybe_deserialize_u64<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
where
D: Deserializer<'de>,

View File

@ -8,7 +8,7 @@ pub async fn health(client: &mut Client) -> Result<Vec<Health>, ClientError> {
client.execute_get::<Vec<Health>>(&url).await
}
/// voltage can be used to get device's voltag reading
/// voltage can be used to get device's voltage reading
pub async fn voltage(client: &mut Client) -> Result<f32, ClientError> {
let url = format!("{}/health/voltage", super::BASE);

View File

@ -182,3 +182,31 @@ async fn release_dhcp_lease() -> Result<(), ClientError> {
Ok(())
}
#[tokio::test]
async fn list_routes() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::route::list(&mut client).await?;
println!("{:?}", response);
Ok(())
}
#[tokio::test]
async fn get_route() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::route::list(&mut client).await?;
let response = mikrotik::ip::route::get(&mut client, &response[0].id).await?;
println!("{:?}", response);
Ok(())
}

212
tests/routing_test.rs Normal file
View File

@ -0,0 +1,212 @@
use mikrotik::{ip::dhcp_client::DhcpClientInput, Client, ClientError};
use reqwest::Url;
#[tokio::test]
async fn list_dhcp_servers() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::dhcp_server::list(&mut client).await?;
println!("{:?}", response);
Ok(())
}
#[tokio::test]
async fn get_dhcp_server() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::dhcp_server::get(&mut client, "vlan-150").await?;
println!("{:?}", response);
Ok(())
}
#[tokio::test]
async fn list_network() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::dhcp_server::list_network(&mut client).await?;
println!("{:?}", response);
Ok(())
}
#[tokio::test]
async fn get_network() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::dhcp_server::list_network(&mut client).await?;
let response = mikrotik::ip::dhcp_server::get_network(&mut client, &response[0].id).await?;
println!("{:?}", response);
Ok(())
}
#[tokio::test]
async fn list_leases() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::dhcp_server::list_leases(&mut client).await?;
println!("{:?}", response);
Ok(())
}
#[tokio::test]
async fn get_lease() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::dhcp_server::list_leases(&mut client).await?;
let response = mikrotik::ip::dhcp_server::get_lease(&mut client, &response[0].id).await?;
println!("{:?}", response);
Ok(())
}
#[tokio::test]
async fn list_address() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::address::list(&mut client).await?;
println!("{:?}", response);
Ok(())
}
#[tokio::test]
async fn get_address() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::address::list(&mut client).await?;
let response = mikrotik::ip::address::get(&mut client, &response[0].id).await?;
println!("{:?}", response);
Ok(())
}
#[tokio::test]
async fn list_dhcp_client() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::dhcp_client::list(&mut client).await?;
println!("{:?}", response);
Ok(())
}
#[tokio::test]
async fn get_dhcp_client() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::dhcp_client::list(&mut client).await?;
let response = mikrotik::ip::dhcp_client::get(&mut client, &response[0].id).await?;
println!("{:?}", response);
Ok(())
}
#[tokio::test]
async fn renew_dhcp_lease() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::dhcp_client::list(&mut client).await?;
let response = mikrotik::ip::dhcp_client::renew(
&mut client,
DhcpClientInput {
numbers: response[0].id.clone(),
},
)
.await?;
println!("{:?}", response);
Ok(())
}
#[tokio::test]
async fn release_dhcp_lease() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::dhcp_client::list(&mut client).await?;
println!("{:?}", response);
let response = mikrotik::ip::dhcp_client::release(
&mut client,
DhcpClientInput {
numbers: response[0].id.clone(),
},
)
.await?;
println!("{:?}", response);
Ok(())
}
#[tokio::test]
async fn list_routes() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::route::list(&mut client).await?;
println!("{:?}", response);
Ok(())
}
#[tokio::test]
async fn get_route() -> Result<(), ClientError> {
let base = Url::parse("https://10.0.10.1")?;
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)
.expect("error in creating client");
let response = mikrotik::ip::route::list(&mut client).await?;
let response = mikrotik::ip::route::get(&mut client, &response[0].id).await?;
println!("{:?}", response);
Ok(())
}