public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Stefan Hanreich <s.hanreich@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH proxmox-firewall v2 19/25] config: tests: add support for loading sdn and ipam config
Date: Thu, 10 Oct 2024 17:56:31 +0200	[thread overview]
Message-ID: <20241010155637.255451-20-s.hanreich@proxmox.com> (raw)
In-Reply-To: <20241010155637.255451-1-s.hanreich@proxmox.com>

Also add example SDN configuration files that get automatically
loaded, which can be used for future tests.

Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
---
 proxmox-firewall/src/config.rs                | 69 +++++++++++++++++++
 .../tests/input/.running-config.json          | 45 ++++++++++++
 proxmox-firewall/tests/input/ipam.db          | 32 +++++++++
 proxmox-firewall/tests/integration_tests.rs   | 10 +++
 proxmox-nftables/src/types.rs                 |  2 +-
 5 files changed, 157 insertions(+), 1 deletion(-)
 create mode 100644 proxmox-firewall/tests/input/.running-config.json
 create mode 100644 proxmox-firewall/tests/input/ipam.db

diff --git a/proxmox-firewall/src/config.rs b/proxmox-firewall/src/config.rs
index 5bd2512..c27aac6 100644
--- a/proxmox-firewall/src/config.rs
+++ b/proxmox-firewall/src/config.rs
@@ -16,6 +16,10 @@ use proxmox_ve_config::guest::{GuestEntry, GuestMap};
 use proxmox_nftables::command::{CommandOutput, Commands, List, ListOutput};
 use proxmox_nftables::types::ListChain;
 use proxmox_nftables::NftClient;
+use proxmox_ve_config::sdn::{
+    config::{RunningConfig, SdnConfig},
+    ipam::{Ipam, IpamJson},
+};
 
 pub trait FirewallConfigLoader {
     fn cluster(&self) -> Result<Option<Box<dyn io::BufRead>>, Error>;
@@ -27,6 +31,8 @@ pub trait FirewallConfigLoader {
         guest: &GuestEntry,
     ) -> Result<Option<Box<dyn io::BufRead>>, Error>;
     fn guest_firewall_config(&self, vmid: &Vmid) -> Result<Option<Box<dyn io::BufRead>>, Error>;
+    fn sdn_running_config(&self) -> Result<Option<Box<dyn io::BufRead>>, Error>;
+    fn ipam(&self) -> Result<Option<Box<dyn io::BufRead>>, Error>;
 }
 
 #[derive(Default)]
@@ -58,6 +64,9 @@ fn open_config_file(path: &str) -> Result<Option<File>, Error> {
 const CLUSTER_CONFIG_PATH: &str = "/etc/pve/firewall/cluster.fw";
 const HOST_CONFIG_PATH: &str = "/etc/pve/local/host.fw";
 
+const SDN_RUNNING_CONFIG_PATH: &str = "/etc/pve/sdn/.running-config";
+const SDN_IPAM_PATH: &str = "/etc/pve/priv/ipam.db";
+
 impl FirewallConfigLoader for PveFirewallConfigLoader {
     fn cluster(&self) -> Result<Option<Box<dyn io::BufRead>>, Error> {
         log::info!("loading cluster config");
@@ -119,6 +128,32 @@ impl FirewallConfigLoader for PveFirewallConfigLoader {
 
         Ok(None)
     }
+
+    fn sdn_running_config(&self) -> Result<Option<Box<dyn io::BufRead>>, Error> {
+        log::info!("loading SDN running-config");
+
+        let fd = open_config_file(SDN_RUNNING_CONFIG_PATH)?;
+
+        if let Some(file) = fd {
+            let buf_reader = Box::new(BufReader::new(file)) as Box<dyn io::BufRead>;
+            return Ok(Some(buf_reader));
+        }
+
+        Ok(None)
+    }
+
+    fn ipam(&self) -> Result<Option<Box<dyn io::BufRead>>, Error> {
+        log::info!("loading IPAM config");
+
+        let fd = open_config_file(SDN_IPAM_PATH)?;
+
+        if let Some(file) = fd {
+            let buf_reader = Box::new(BufReader::new(file)) as Box<dyn io::BufRead>;
+            return Ok(Some(buf_reader));
+        }
+
+        Ok(None)
+    }
 }
 
 pub trait NftConfigLoader {
@@ -150,6 +185,8 @@ pub struct FirewallConfig {
     host_config: HostConfig,
     guest_config: BTreeMap<Vmid, GuestConfig>,
     nft_config: BTreeMap<String, ListChain>,
+    sdn_config: Option<SdnConfig>,
+    ipam_config: Option<Ipam>,
 }
 
 impl FirewallConfig {
@@ -207,6 +244,28 @@ impl FirewallConfig {
         Ok(guests)
     }
 
+    pub fn parse_sdn(
+        firewall_loader: &dyn FirewallConfigLoader,
+    ) -> Result<Option<SdnConfig>, Error> {
+        Ok(match firewall_loader.sdn_running_config()? {
+            Some(data) => {
+                let running_config: RunningConfig = serde_json::from_reader(data)?;
+                Some(SdnConfig::try_from(running_config)?)
+            }
+            _ => None,
+        })
+    }
+
+    pub fn parse_ipam(firewall_loader: &dyn FirewallConfigLoader) -> Result<Option<Ipam>, Error> {
+        Ok(match firewall_loader.ipam()? {
+            Some(data) => {
+                let raw_ipam: IpamJson = serde_json::from_reader(data)?;
+                Some(Ipam::try_from(raw_ipam)?)
+            }
+            _ => None,
+        })
+    }
+
     pub fn parse_nft(
         nft_loader: &dyn NftConfigLoader,
     ) -> Result<BTreeMap<String, ListChain>, Error> {
@@ -233,6 +292,8 @@ impl FirewallConfig {
             cluster_config: Self::parse_cluster(firewall_loader)?,
             host_config: Self::parse_host(firewall_loader)?,
             guest_config: Self::parse_guests(firewall_loader)?,
+            sdn_config: Self::parse_sdn(firewall_loader)?,
+            ipam_config: Self::parse_ipam(firewall_loader)?,
             nft_config: Self::parse_nft(nft_loader)?,
         })
     }
@@ -253,6 +314,14 @@ impl FirewallConfig {
         &self.nft_config
     }
 
+    pub fn sdn(&self) -> Option<&SdnConfig> {
+        self.sdn_config.as_ref()
+    }
+
+    pub fn ipam(&self) -> Option<&Ipam> {
+        self.ipam_config.as_ref()
+    }
+
     pub fn is_enabled(&self) -> bool {
         self.cluster().is_enabled() && self.host().nftables()
     }
diff --git a/proxmox-firewall/tests/input/.running-config.json b/proxmox-firewall/tests/input/.running-config.json
new file mode 100644
index 0000000..a4511f0
--- /dev/null
+++ b/proxmox-firewall/tests/input/.running-config.json
@@ -0,0 +1,45 @@
+{
+  "subnets": {
+    "ids": {
+      "test-10.101.0.0-16": {
+        "gateway": "10.101.1.1",
+        "snat": 1,
+        "vnet": "public",
+        "dhcp-range": [
+          "start-address=10.101.99.100,end-address=10.101.99.200"
+        ],
+        "type": "subnet"
+      },
+      "test-fd80::-64": {
+        "snat": 1,
+        "gateway": "fd80::1",
+        "dhcp-range": [
+          "start-address=fd80::1000,end-address=fd80::ffff"
+        ],
+        "vnet": "public",
+        "type": "subnet"
+      }
+    }
+  },
+  "version": 49,
+  "vnets": {
+    "ids": {
+      "public": {
+        "zone": "test",
+        "type": "vnet"
+      }
+    }
+  },
+  "zones": {
+    "ids": {
+      "test": {
+        "dhcp": "dnsmasq",
+        "ipam": "pve",
+        "type": "simple"
+      }
+    }
+  },
+  "controllers": {
+    "ids": {}
+  }
+}
diff --git a/proxmox-firewall/tests/input/ipam.db b/proxmox-firewall/tests/input/ipam.db
new file mode 100644
index 0000000..ac2901e
--- /dev/null
+++ b/proxmox-firewall/tests/input/ipam.db
@@ -0,0 +1,32 @@
+{
+  "zones": {
+    "public": {
+      "subnets": {
+        "10.101.0.0/16": {
+          "ips": {
+            "10.101.1.1": {
+              "gateway": 1
+            },
+            "10.101.1.100": {
+              "vmid": "101",
+              "mac": "BC:24:11:11:22:33",
+              "hostname": null
+            }
+          }
+        },
+        "fd80::/64": {
+          "ips": {
+            "fd80::1": {
+              "gateway": 1
+            },
+            "fd80::1000": {
+              "mac": "BC:24:11:11:22:33",
+              "vmid": "101",
+              "hostname": "test-vm"
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/proxmox-firewall/tests/integration_tests.rs b/proxmox-firewall/tests/integration_tests.rs
index e9baffe..5de1a4e 100644
--- a/proxmox-firewall/tests/integration_tests.rs
+++ b/proxmox-firewall/tests/integration_tests.rs
@@ -69,6 +69,16 @@ impl FirewallConfigLoader for MockFirewallConfigLoader {
 
         Ok(None)
     }
+
+    fn sdn_running_config(&self) -> Result<Option<Box<dyn std::io::BufRead>>, Error> {
+        Ok(Some(Box::new(
+            include_str!("input/.running-config.json").as_bytes(),
+        )))
+    }
+
+    fn ipam(&self) -> Result<Option<Box<dyn std::io::BufRead>>, Error> {
+        Ok(Some(Box::new(include_str!("input/ipam.db").as_bytes())))
+    }
 }
 
 struct MockNftConfigLoader {}
diff --git a/proxmox-nftables/src/types.rs b/proxmox-nftables/src/types.rs
index a83e958..3101436 100644
--- a/proxmox-nftables/src/types.rs
+++ b/proxmox-nftables/src/types.rs
@@ -636,7 +636,7 @@ impl SetName {
         };
 
         let name = match name.scope() {
-            IpsetScope::Datacenter => name.to_string(),
+            IpsetScope::Datacenter | IpsetScope::Sdn => name.to_string(),
             IpsetScope::Guest => {
                 if let Some(vmid) = vmid {
                     format!("guest-{vmid}/{}", name.name())
-- 
2.39.5


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


  parent reply	other threads:[~2024-10-10 16:03 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-10 15:56 [pve-devel] [PATCH docs/firewall/manager/proxmox{-ve-rs, -firewall, -perl-rs} v2 00/25] autogenerate ipsets for sdn objects Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 01/25] debian: add files for packaging Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 02/25] bump serde_with to 3 Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 03/25] bump dependencies Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 04/25] firewall: add sdn scope for ipsets Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 05/25] firewall: add ip range types Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 06/25] firewall: address: use new iprange type for ip entries Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 07/25] ipset: add range variant to addresses Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 08/25] iprange: add methods for converting an ip range to cidrs Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 09/25] ipset: address: add helper methods Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 10/25] firewall: guest: derive traits according to rust api guidelines Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 11/25] common: add allowlist Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 12/25] sdn: add name types Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 13/25] sdn: add ipam module Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 14/25] sdn: ipam: add method for generating ipsets Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 15/25] sdn: add config module Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 16/25] sdn: config: add method for generating ipsets Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 17/25] tests: add sdn config tests Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-ve-rs v2 18/25] tests: add ipam tests Stefan Hanreich
2024-10-10 15:56 ` Stefan Hanreich [this message]
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-firewall v2 20/25] ipsets: autogenerate ipsets for vnets and ipam Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH pve-firewall v2 21/25] add support for loading sdn firewall configuration Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH pve-firewall v2 22/25] api: load sdn ipsets Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH proxmox-perl-rs v2 23/25] add PVE::RS::Firewall::SDN module Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH pve-manager v2 24/25] firewall: add sdn scope to IPRefSelector Stefan Hanreich
2024-10-10 15:56 ` [pve-devel] [PATCH pve-docs v2 25/25] sdn: add documentation for firewall integration Stefan Hanreich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241010155637.255451-20-s.hanreich@proxmox.com \
    --to=s.hanreich@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal