Added endpoints to get/list interface and system health
This commit is contained in:
commit
ed5cd865c5
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
1635
Cargo.lock
generated
Normal file
1635
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
21
Cargo.toml
Normal file
21
Cargo.toml
Normal file
|
@ -0,0 +1,21 @@
|
|||
[package]
|
||||
name = "mikrotik"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
async-process = "1.2.0"
|
||||
async-recursion = "0.3.2"
|
||||
base64 = "0.13.0"
|
||||
color-eyre = "0.6.1"
|
||||
futures = "0.3.17"
|
||||
reqwest = { version = "0.11.4", features = ["rustls-tls", "serde_json", "json"] }
|
||||
serde = { version = "1.0.130", features = ["derive"] }
|
||||
serde_derive = "1.0.136"
|
||||
serde_json = "1.0.68"
|
||||
tokio = { version = "1.10.1", features = ["full"] }
|
||||
tokio-test = "0.4.2"
|
||||
tracing = "0.1.34"
|
||||
tracing-subscriber = { version = "0.3.11", features = ["env-filter"] }
|
51
src/client.rs
Normal file
51
src/client.rs
Normal file
|
@ -0,0 +1,51 @@
|
|||
use color_eyre::Report;
|
||||
use reqwest::{
|
||||
header::{HeaderMap, HeaderValue},
|
||||
Request, Url,
|
||||
};
|
||||
|
||||
pub struct Client {
|
||||
pub client: reqwest::Client,
|
||||
pub base_url: Url,
|
||||
pub basic_auth: HeaderValue,
|
||||
pub self_signed_cert: bool,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub fn new(
|
||||
base_url: Url,
|
||||
username: String,
|
||||
password: String,
|
||||
self_signed_cert: bool,
|
||||
) -> Result<Self, Report> {
|
||||
let value = format!("{}:{}", username, password);
|
||||
let value = base64::encode(value);
|
||||
|
||||
let basic_auth = HeaderValue::from_str(&format!("Basic {}", value))?;
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.danger_accept_invalid_certs(self_signed_cert)
|
||||
.build()?;
|
||||
|
||||
Ok(Self {
|
||||
client,
|
||||
base_url,
|
||||
basic_auth,
|
||||
self_signed_cert,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn add_credentials(&self, m: &mut HeaderMap<HeaderValue>) {
|
||||
let token = m
|
||||
.entry("Authorization")
|
||||
.or_insert_with(|| self.basic_auth.clone());
|
||||
|
||||
*token = self.basic_auth.clone();
|
||||
}
|
||||
|
||||
pub async fn execute(&mut self, mut r: Request) -> Result<reqwest::Response, reqwest::Error> {
|
||||
self.add_credentials(r.headers_mut());
|
||||
|
||||
self.client.execute(r).await
|
||||
}
|
||||
}
|
28
src/interface/interface.rs
Normal file
28
src/interface/interface.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
use super::types::*;
|
||||
use crate::Client;
|
||||
use color_eyre::Report;
|
||||
use reqwest::{Method, Request};
|
||||
use tracing::debug;
|
||||
|
||||
pub async fn list(client: &mut Client) -> Result<Vec<Interface>, Report> {
|
||||
let url = client.base_url.clone();
|
||||
let url = url.join(super::BASE)?;
|
||||
|
||||
let req = Request::new(Method::GET, url);
|
||||
|
||||
let response = client.execute(req).await?.json::<Vec<Interface>>().await?;
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
pub async fn get(client: &mut Client, ifid: &str) -> Result<Interface, Report> {
|
||||
let url = client.base_url.clone();
|
||||
let url = url.join(&format!("{}/{}", super::BASE, ifid))?;
|
||||
debug!("url {}", url);
|
||||
|
||||
let req = Request::new(Method::GET, url);
|
||||
|
||||
let response = client.execute(req).await?.json::<Interface>().await?;
|
||||
|
||||
Ok(response)
|
||||
}
|
6
src/interface/mod.rs
Normal file
6
src/interface/mod.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
mod interface;
|
||||
mod types;
|
||||
|
||||
pub use interface::*;
|
||||
|
||||
const BASE: &str = "rest/interface";
|
58
src/interface/types.rs
Normal file
58
src/interface/types.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use serde_derive::Deserialize;
|
||||
use serde_derive::Serialize;
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Interface {
|
||||
#[serde(rename = ".id")]
|
||||
pub id: String,
|
||||
#[serde(rename = "actual-mtu")]
|
||||
pub actual_mtu: String,
|
||||
pub comment: Option<String>,
|
||||
#[serde(rename = "default-name")]
|
||||
pub default_name: Option<String>,
|
||||
pub disabled: String,
|
||||
#[serde(rename = "fp-rx-byte")]
|
||||
pub fp_rx_byte: String,
|
||||
#[serde(rename = "fp-rx-packet")]
|
||||
pub fp_rx_packet: String,
|
||||
#[serde(rename = "fp-tx-byte")]
|
||||
pub fp_tx_byte: String,
|
||||
#[serde(rename = "fp-tx-packet")]
|
||||
pub fp_tx_packet: String,
|
||||
pub l2mtu: Option<String>,
|
||||
#[serde(rename = "last-link-up-time")]
|
||||
pub last_link_up_time: Option<String>,
|
||||
#[serde(rename = "link-downs")]
|
||||
pub link_downs: String,
|
||||
#[serde(rename = "mac-address")]
|
||||
pub mac_address: Option<String>,
|
||||
#[serde(rename = "max-l2mtu")]
|
||||
pub max_l2mtu: Option<String>,
|
||||
pub mtu: String,
|
||||
pub name: String,
|
||||
pub running: String,
|
||||
#[serde(rename = "rx-byte")]
|
||||
pub rx_byte: String,
|
||||
#[serde(rename = "rx-drop")]
|
||||
pub rx_drop: String,
|
||||
#[serde(rename = "rx-error")]
|
||||
pub rx_error: String,
|
||||
#[serde(rename = "rx-packet")]
|
||||
pub rx_packet: String,
|
||||
pub slave: Option<String>,
|
||||
#[serde(rename = "tx-byte")]
|
||||
pub tx_byte: String,
|
||||
#[serde(rename = "tx-drop")]
|
||||
pub tx_drop: String,
|
||||
#[serde(rename = "tx-error")]
|
||||
pub tx_error: String,
|
||||
#[serde(rename = "tx-packet")]
|
||||
pub tx_packet: String,
|
||||
#[serde(rename = "tx-queue-drop")]
|
||||
pub tx_queue_drop: String,
|
||||
#[serde(rename = "type")]
|
||||
pub type_field: String,
|
||||
#[serde(rename = "last-link-down-time")]
|
||||
pub last_link_down_time: Option<String>,
|
||||
}
|
5
src/lib.rs
Normal file
5
src/lib.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
mod client;
|
||||
pub mod interface;
|
||||
pub mod system;
|
||||
|
||||
pub use client::*;
|
14
src/system/health.rs
Normal file
14
src/system/health.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
use crate::{system::types::Health, Client};
|
||||
use color_eyre::Report;
|
||||
use reqwest::{Method, Request};
|
||||
|
||||
pub async fn health(client: &mut Client) -> Result<Vec<Health>, Report> {
|
||||
let url = client.base_url.clone();
|
||||
let url = url.join(&format!("{}/health", super::BASE))?;
|
||||
|
||||
let req = Request::new(Method::GET, url);
|
||||
|
||||
let response = client.execute(req).await?.json::<Vec<Health>>().await?;
|
||||
|
||||
Ok(response)
|
||||
}
|
6
src/system/mod.rs
Normal file
6
src/system/mod.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
mod health;
|
||||
mod types;
|
||||
|
||||
pub use health::*;
|
||||
|
||||
const BASE: &str = "rest/system";
|
13
src/system/types.rs
Normal file
13
src/system/types.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
use serde_derive::Deserialize;
|
||||
use serde_derive::Serialize;
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Health {
|
||||
#[serde(rename = ".id")]
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
#[serde(rename = "type")]
|
||||
pub type_field: String,
|
||||
pub value: String,
|
||||
}
|
54
tests/interfaces_test.rs
Normal file
54
tests/interfaces_test.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
use color_eyre::Report;
|
||||
use mikrotik::Client;
|
||||
use reqwest::Url;
|
||||
use std::sync::Once;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
static INIT: Once = Once::new();
|
||||
|
||||
fn setup() -> Result<(), Report> {
|
||||
INIT.call_once(|| {
|
||||
if std::env::var("RUST_LIB_BACKTRACE").is_err() {
|
||||
std::env::set_var("RUST_LIB_BACKTRACE", "1")
|
||||
}
|
||||
color_eyre::install();
|
||||
|
||||
if std::env::var("RUST_LOG").is_err() {
|
||||
std::env::set_var("RUST_LOG", "info");
|
||||
}
|
||||
|
||||
tracing_subscriber::fmt::fmt()
|
||||
.with_env_filter(EnvFilter::from_default_env())
|
||||
.init();
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn list_interfaces() -> Result<(), Report> {
|
||||
setup()?;
|
||||
|
||||
let base = Url::parse("https://10.0.10.1")?;
|
||||
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)?;
|
||||
|
||||
let response = mikrotik::interface::list(&mut client).await?;
|
||||
|
||||
println!("{:?}", response);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_interface() -> Result<(), Report> {
|
||||
setup()?;
|
||||
|
||||
let base = Url::parse("https://10.0.10.1")?;
|
||||
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)?;
|
||||
|
||||
let response = mikrotik::interface::get(&mut client, "ether5").await?;
|
||||
|
||||
println!("{:?}", response);
|
||||
|
||||
Ok(())
|
||||
}
|
40
tests/system_test.rs
Normal file
40
tests/system_test.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
use color_eyre::Report;
|
||||
use mikrotik::Client;
|
||||
use reqwest::Url;
|
||||
use std::sync::Once;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
static INIT: Once = Once::new();
|
||||
|
||||
fn setup() -> Result<(), Report> {
|
||||
INIT.call_once(|| {
|
||||
if std::env::var("RUST_LIB_BACKTRACE").is_err() {
|
||||
std::env::set_var("RUST_LIB_BACKTRACE", "1")
|
||||
}
|
||||
color_eyre::install();
|
||||
|
||||
if std::env::var("RUST_LOG").is_err() {
|
||||
std::env::set_var("RUST_LOG", "info");
|
||||
}
|
||||
|
||||
tracing_subscriber::fmt::fmt()
|
||||
.with_env_filter(EnvFilter::from_default_env())
|
||||
.init();
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn health() -> Result<(), Report> {
|
||||
setup()?;
|
||||
|
||||
let base = Url::parse("https://10.0.10.1")?;
|
||||
let mut client = Client::new(base, "admin".to_string(), "ifd783far".to_string(), true)?;
|
||||
|
||||
let response = mikrotik::system::health(&mut client).await?;
|
||||
|
||||
println!("{:?}", response);
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue
Block a user