feat: delete ip resources

This commit is contained in:
2025-03-05 10:03:29 +00:00
parent fc735590d6
commit 8838853957
6 changed files with 200 additions and 99 deletions

View File

@ -1,6 +1,6 @@
use crate::json_api::JsonApi;
use crate::router::{ArpEntry, Router};
use anyhow::Result;
use anyhow::{ensure, Result};
use base64::engine::general_purpose::STANDARD;
use base64::Engine;
use log::debug;
@ -32,27 +32,9 @@ impl Router for MikrotikRouter {
Ok(rsp.into_iter().map(|e| e.into()).collect())
}
async fn add_arp_entry(
&self,
ip: IpAddr,
mac: &str,
arp_interface: &str,
comment: Option<&str>,
) -> Result<ArpEntry> {
let rsp: MikrotikArpEntry = self
.api
.req(
Method::PUT,
"/rest/ip/arp",
MikrotikArpEntry {
id: None,
address: ip.to_string(),
mac_address: Some(mac.to_string()),
interface: arp_interface.to_string(),
comment: comment.map(|c| c.to_string()),
},
)
.await?;
async fn add_arp_entry(&self, entry: &ArpEntry) -> Result<ArpEntry> {
let req: MikrotikArpEntry = entry.clone().into();
let rsp: MikrotikArpEntry = self.api.req(Method::PUT, "/rest/ip/arp", req).await?;
debug!("{:?}", rsp);
Ok(rsp.into())
}
@ -60,11 +42,26 @@ impl Router for MikrotikRouter {
async fn remove_arp_entry(&self, id: &str) -> Result<()> {
let rsp: MikrotikArpEntry = self
.api
.req(Method::DELETE, &format!("/rest/ip/arp/{id}"), ())
.req(Method::DELETE, &format!("/rest/ip/arp/{}", id), ())
.await?;
debug!("{:?}", rsp);
Ok(())
}
async fn update_arp_entry(&self, entry: &ArpEntry) -> Result<ArpEntry> {
ensure!(entry.id.is_some(), "Cannot update an arp entry without ID");
let req: MikrotikArpEntry = entry.clone().into();
let rsp: MikrotikArpEntry = self
.api
.req(
Method::PATCH,
&format!("/rest/ip/arp/{}", entry.id.as_ref().unwrap()),
req,
)
.await?;
debug!("{:?}", rsp);
Ok(rsp.into())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -84,7 +81,7 @@ pub struct MikrotikArpEntry {
impl Into<ArpEntry> for MikrotikArpEntry {
fn into(self) -> ArpEntry {
ArpEntry {
id: self.id.unwrap(),
id: self.id,
address: self.address,
mac_address: self.mac_address.unwrap(),
interface: Some(self.interface),
@ -92,3 +89,15 @@ impl Into<ArpEntry> for MikrotikArpEntry {
}
}
}
impl Into<MikrotikArpEntry> for ArpEntry {
fn into(self) -> MikrotikArpEntry {
MikrotikArpEntry {
id: self.id,
address: self.address,
mac_address: Some(self.mac_address),
interface: self.interface.unwrap(),
comment: self.comment,
}
}
}

View File

@ -1,6 +1,6 @@
use anyhow::Result;
use lnvps_db::{Vm, VmIpAssignment};
use rocket::async_trait;
use std::net::IpAddr;
/// Router defines a network device used to access the hosts
///
@ -12,25 +12,32 @@ use std::net::IpAddr;
#[async_trait]
pub trait Router: Send + Sync {
async fn list_arp_entry(&self) -> Result<Vec<ArpEntry>>;
async fn add_arp_entry(
&self,
ip: IpAddr,
mac: &str,
interface: &str,
comment: Option<&str>,
) -> Result<ArpEntry>;
async fn add_arp_entry(&self, entry: &ArpEntry) -> Result<ArpEntry>;
async fn remove_arp_entry(&self, id: &str) -> Result<()>;
async fn update_arp_entry(&self, entry: &ArpEntry) -> Result<ArpEntry>;
}
#[derive(Debug, Clone)]
pub struct ArpEntry {
pub id: String,
pub id: Option<String>,
pub address: String,
pub mac_address: String,
pub interface: Option<String>,
pub comment: Option<String>,
}
impl ArpEntry {
pub fn new(vm: &Vm, ip: &VmIpAssignment, interface: Option<String>) -> Result<Self> {
Ok(Self {
id: ip.arp_ref.clone(),
address: ip.ip.clone(),
mac_address: vm.mac_address.clone(),
interface,
comment: Some(format!("VM{}", vm.id)),
})
}
}
#[cfg(feature = "mikrotik")]
mod mikrotik;
#[cfg(feature = "mikrotik")]