From 8945fdeda361811f2668660fde17e5346e280a1f Mon Sep 17 00:00:00 2001 From: Samuel Lorch Date: Thu, 2 Nov 2023 00:47:54 +0100 Subject: [PATCH] add create_map, update_map and update_vec macros --- src/api/firewall.rs | 22 +++++++++++ src/api/mod.rs | 96 ++++++++++++++++++++++++++++++++++++++++++++- src/api/network.rs | 24 +++++++++++- src/api/object.rs | 30 ++++++++++++++ src/api/service.rs | 22 +++++++++++ src/api/vpn.rs | 30 +++++++++++++- 6 files changed, 221 insertions(+), 3 deletions(-) diff --git a/src/api/firewall.rs b/src/api/firewall.rs index 70f1c3f..76d1fb5 100644 --- a/src/api/firewall.rs +++ b/src/api/firewall.rs @@ -4,6 +4,7 @@ use crate::{ definitions::firewall::{DestinationNATRule, ForwardRule, SourceNATRule}, delete_vec_thing, get_vec_thing, list_things, state::RpcState, + update_vec_thing, }; use jsonrpsee::RpcModule; @@ -29,6 +30,13 @@ pub fn register_methods(module: &mut RpcModule) { ) .unwrap(); + module + .register_method( + "firewall.forward_rules.update", + update_vec_thing!(firewall.forward_rules, ForwardRule), + ) + .unwrap(); + module .register_method( "firewall.forward_rules.delete", @@ -57,6 +65,13 @@ pub fn register_methods(module: &mut RpcModule) { ) .unwrap(); + module + .register_method( + "firewall.destination_nat_rules.update", + update_vec_thing!(firewall.destination_nat_rules, DestinationNATRule), + ) + .unwrap(); + module .register_method( "firewall.destination_nat_rules.delete", @@ -85,6 +100,13 @@ pub fn register_methods(module: &mut RpcModule) { ) .unwrap(); + module + .register_method( + "firewall.source_nat_rules.update", + update_vec_thing!(firewall.source_nat_rules, SourceNATRule), + ) + .unwrap(); + module .register_method( "firewall.source_nat_rules.delete", diff --git a/src/api/mod.rs b/src/api/mod.rs index 9d42434..33c356d 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -107,6 +107,37 @@ macro_rules! list_things { }; } +#[macro_export] +macro_rules! create_map_thing { + ($( $sub_system:ident ).+, $typ:ty) => { + |params, state| { + use serde::{Deserialize, Serialize}; + + #[derive(Deserialize, Serialize)] + struct CreateThing { + id: String, + thing: $typ + } + + let t: CreateThing = params.parse().map_err(ApiError::ParameterDeserialize)?; + let mut cm = state.config_manager.clone(); + let mut tx = cm.start_transaction(); + + if tx.config.$($sub_system).+.insert(t.id.clone(), t.thing).is_none() { + tx.commit(crate::config_manager::Change { + action: crate::config_manager::ChangeAction::Create, + path: stringify!($($sub_system).+), + id: t.id, + }) + .map_err(ApiError::ConfigError) + } else { + tx.revert(); + Err(ApiError::AlreadyExists) + } + } + }; +} + #[macro_export] macro_rules! create_vec_thing { ($( $sub_system:ident ).+, $typ:ty) => { @@ -119,12 +150,75 @@ macro_rules! create_vec_thing { tx.config.$($sub_system).+.push(t); let id = {tx.config.$($sub_system).+.len() - 1}.to_string(); tx.commit(crate::config_manager::Change { - action: crate::config_manager::ChangeAction::Delete, + action: crate::config_manager::ChangeAction::Create, path: stringify!($($sub_system).+), id, }) .map_err(ApiError::ConfigError) + } + }; +} +#[macro_export] +macro_rules! update_map_thing { + ($( $sub_system:ident ).+, $typ:ty) => { + |params, state| { + use serde::{Deserialize, Serialize}; + + #[derive(Deserialize, Serialize)] + struct CreateThing { + id: String, + thing: $typ + } + + let t: CreateThing = params.parse().map_err(ApiError::ParameterDeserialize)?; + let mut cm = state.config_manager.clone(); + let mut tx = cm.start_transaction(); + + if tx.config.$($sub_system).+.insert(t.id.clone(), t.thing).is_none() { + tx.revert(); + Err(ApiError::NotFound) + } else { + tx.commit(crate::config_manager::Change { + action: crate::config_manager::ChangeAction::Update, + path: stringify!($($sub_system).+), + id: t.id, + }) + .map_err(ApiError::ConfigError) + } + } + }; +} + +#[macro_export] +macro_rules! update_vec_thing { + ($( $sub_system:ident ).+, $typ:ty) => { + |params, state| { + use serde::{Deserialize, Serialize}; + + #[derive(Deserialize, Serialize)] + struct CreateThing { + id: i64, + thing: $typ + } + + let t: CreateThing = params.parse().map_err(ApiError::ParameterDeserialize)?; + let mut cm = state.config_manager.clone(); + let mut tx = cm.start_transaction(); + + if tx.config.$($sub_system).+.len() > t.id as usize { + tx.config.$($sub_system).+[t.id as usize] = t.thing; + + tx.commit(crate::config_manager::Change { + action: crate::config_manager::ChangeAction::Update, + path: stringify!($($sub_system).+), + id: t.id.to_string(), + }) + .map_err(ApiError::ConfigError) + } else { + tx.revert(); + Err(ApiError::NotFound) + } } }; } diff --git a/src/api/network.rs b/src/api/network.rs index 387f93b..b998db7 100644 --- a/src/api/network.rs +++ b/src/api/network.rs @@ -1,9 +1,10 @@ use super::ApiError; use crate::{ - create_vec_thing, + create_map_thing, create_vec_thing, definitions::network::{NetworkInterface, StaticRoute}, delete_map_thing, delete_vec_thing, get_map_thing, get_vec_thing, list_things, state::RpcState, + update_map_thing, update_vec_thing, }; use jsonrpsee::RpcModule; use std::collections::HashMap; @@ -30,6 +31,13 @@ pub fn register_methods(module: &mut RpcModule) { ) .unwrap(); + module + .register_method( + "network.static_routes.update", + update_vec_thing!(network.static_routes, StaticRoute), + ) + .unwrap(); + module .register_method( "network.static_routes.delete", @@ -48,6 +56,20 @@ pub fn register_methods(module: &mut RpcModule) { ) .unwrap(); + module + .register_method( + "network.interfaces.create", + create_map_thing!(network.interfaces, NetworkInterface), + ) + .unwrap(); + + module + .register_method( + "network.interfaces.update", + update_map_thing!(network.interfaces, NetworkInterface), + ) + .unwrap(); + module .register_method( "network.interfaces.delete", diff --git a/src/api/object.rs b/src/api/object.rs index b62615f..7baab32 100644 --- a/src/api/object.rs +++ b/src/api/object.rs @@ -1,8 +1,10 @@ use super::ApiError; use crate::{ + create_map_thing, definitions::object::{Address, Service}, delete_map_thing, get_map_thing, list_things, state::RpcState, + update_map_thing, }; use jsonrpsee::RpcModule; use std::collections::HashMap; @@ -19,6 +21,20 @@ pub fn register_methods(module: &mut RpcModule) { ) .unwrap(); + module + .register_method( + "object.services.create", + create_map_thing!(object.services, Service), + ) + .unwrap(); + + module + .register_method( + "object.services.update", + update_map_thing!(object.services, Service), + ) + .unwrap(); + module .register_method("object.services.delete", delete_map_thing!(object.services)) .unwrap(); @@ -34,6 +50,20 @@ pub fn register_methods(module: &mut RpcModule) { ) .unwrap(); + module + .register_method( + "object.addresses.create", + create_map_thing!(object.addresses, Address), + ) + .unwrap(); + + module + .register_method( + "object.addresses.update", + update_map_thing!(object.addresses, Address), + ) + .unwrap(); + module .register_method( "object.addresses.delete", diff --git a/src/api/service.rs b/src/api/service.rs index 51d575f..b94b05f 100644 --- a/src/api/service.rs +++ b/src/api/service.rs @@ -4,6 +4,7 @@ use crate::{ definitions::service::{DHCPServer, DNSServer, NTPServer}, delete_vec_thing, get_vec_thing, list_things, state::RpcState, + update_vec_thing, }; use jsonrpsee::RpcModule; @@ -29,6 +30,13 @@ pub fn register_methods(module: &mut RpcModule) { ) .unwrap(); + module + .register_method( + "service.dhcp_servers.update", + update_vec_thing!(service.dhcp_servers, DHCPServer), + ) + .unwrap(); + module .register_method( "service.dhcp_servers.delete", @@ -57,6 +65,13 @@ pub fn register_methods(module: &mut RpcModule) { ) .unwrap(); + module + .register_method( + "service.dns_servers.update", + update_vec_thing!(service.dns_servers, DNSServer), + ) + .unwrap(); + module .register_method( "service.dns_servers.delete", @@ -85,6 +100,13 @@ pub fn register_methods(module: &mut RpcModule) { ) .unwrap(); + module + .register_method( + "service.ntp_servers.update", + update_vec_thing!(service.ntp_servers, NTPServer), + ) + .unwrap(); + module .register_method( "service.ntp_servers.delete", diff --git a/src/api/vpn.rs b/src/api/vpn.rs index bfc1e98..9794bc1 100644 --- a/src/api/vpn.rs +++ b/src/api/vpn.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use super::ApiError; use crate::definitions::vpn::{WireguardInterface, WireguardPeer}; use crate::state::RpcState; -use crate::{delete_map_thing, get_map_thing, list_things}; +use crate::{create_map_thing, delete_map_thing, get_map_thing, list_things, update_map_thing}; use jsonrpsee::types::Params; use jsonrpsee::RpcModule; @@ -26,6 +26,20 @@ pub fn register_methods(module: &mut RpcModule) { ) .unwrap(); + module + .register_method( + "vpn.wireguard.interfaces.create", + create_map_thing!(vpn.wireguard.interfaces, WireguardInterface), + ) + .unwrap(); + + module + .register_method( + "vpn.wireguard.interfaces.update", + update_map_thing!(vpn.wireguard.interfaces, WireguardInterface), + ) + .unwrap(); + module .register_method( "vpn.wireguard.interfaces.delete", @@ -47,6 +61,20 @@ pub fn register_methods(module: &mut RpcModule) { ) .unwrap(); + module + .register_method( + "vpn.wireguard.peers.create", + create_map_thing!(vpn.wireguard.peers, WireguardPeer), + ) + .unwrap(); + + module + .register_method( + "vpn.wireguard.peers.update", + update_map_thing!(vpn.wireguard.peers, WireguardPeer), + ) + .unwrap(); + module .register_method( "vpn.wireguard.peers.delete",