public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Gabriel Goller <g.goller@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH proxmox-ve-rs 3/9] ve-config: remove FrrConfigBuilder struct
Date: Tue,  3 Feb 2026 17:01:10 +0100	[thread overview]
Message-ID: <20260203160246.353351-4-g.goller@proxmox.com> (raw)
In-Reply-To: <20260203160246.353351-1-g.goller@proxmox.com>

Instead of using the FrrConfigBuilder, derive bon::Builder on FrrConfig
and directly build the FrrConfig there. Update the tests accordingly.

Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
---
 proxmox-ve-config/src/sdn/frr.rs       |  42 ----------
 proxmox-ve-config/src/sdn/mod.rs       |   2 -
 proxmox-ve-config/tests/fabric/main.rs | 101 +++++++++++++++----------
 3 files changed, 61 insertions(+), 84 deletions(-)
 delete mode 100644 proxmox-ve-config/src/sdn/frr.rs

diff --git a/proxmox-ve-config/src/sdn/frr.rs b/proxmox-ve-config/src/sdn/frr.rs
deleted file mode 100644
index 5d4e4b2ebdbd..000000000000
--- a/proxmox-ve-config/src/sdn/frr.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-use std::collections::{BTreeMap, BTreeSet};
-
-use proxmox_frr::ser::FrrConfig;
-
-use crate::common::valid::Valid;
-use crate::sdn::fabric::{section_config::node::NodeId, FabricConfig};
-
-/// Builder that helps constructing the FrrConfig.
-///
-/// The goal is to have one struct collect all the rust-based configurations and then construct the
-/// [`FrrConfig`] from it using the build method. In the future the controller configuration will
-/// be added here as well.
-#[derive(Default)]
-pub struct FrrConfigBuilder {
-    fabrics: Valid<FabricConfig>,
-}
-
-impl FrrConfigBuilder {
-    /// Add fabric configuration to the builder
-    pub fn add_fabrics(mut self, fabric: Valid<FabricConfig>) -> FrrConfigBuilder {
-        self.fabrics = fabric;
-        self
-    }
-
-    /// Build the complete [`FrrConfig`] from this builder configuration given the hostname of the
-    /// node for which we want to build the config. We also inject the common fabric-level options
-    /// into the interfaces here. (e.g. the fabric-level "hello-interval" gets added to every
-    /// interface if there isn't a more specific one.)
-    pub fn build(self, current_node: NodeId) -> Result<FrrConfig, anyhow::Error> {
-        let mut frr_config = FrrConfig {
-            router: BTreeMap::new(),
-            interfaces: BTreeMap::new(),
-            access_lists: Vec::new(),
-            routemaps: Vec::new(),
-            protocol_routemaps: BTreeSet::new(),
-        };
-
-        crate::sdn::fabric::frr::build_fabric(current_node, self.fabrics, &mut frr_config)?;
-
-        Ok(frr_config)
-    }
-}
diff --git a/proxmox-ve-config/src/sdn/mod.rs b/proxmox-ve-config/src/sdn/mod.rs
index 4586c56358ef..86dcd938c92c 100644
--- a/proxmox-ve-config/src/sdn/mod.rs
+++ b/proxmox-ve-config/src/sdn/mod.rs
@@ -1,7 +1,5 @@
 pub mod config;
 pub mod fabric;
-#[cfg(feature = "frr")]
-pub mod frr;
 pub mod ipam;
 
 use std::{error::Error, fmt::Display, str::FromStr};
diff --git a/proxmox-ve-config/tests/fabric/main.rs b/proxmox-ve-config/tests/fabric/main.rs
index 09629d406449..755592ff7482 100644
--- a/proxmox-ve-config/tests/fabric/main.rs
+++ b/proxmox-ve-config/tests/fabric/main.rs
@@ -1,8 +1,7 @@
 #![cfg(feature = "frr")]
-use proxmox_frr::ser::serializer::dump;
-use proxmox_ve_config::sdn::{
-    fabric::{section_config::node::NodeId, FabricConfig},
-    frr::FrrConfigBuilder,
+use proxmox_frr::ser::{serializer::dump, FrrConfig};
+use proxmox_ve_config::sdn::fabric::{
+    frr::build_fabric, section_config::node::NodeId, FabricConfig,
 };
 
 mod helper;
@@ -17,20 +16,25 @@ mod helper;
 #[test]
 fn openfabric_default() {
     let config = FabricConfig::parse_section_config(helper::get_fabrics_config!()).unwrap();
-
-    let mut frr_config = FrrConfigBuilder::default()
-        .add_fabrics(config.clone())
-        .build(NodeId::from_string("pve".to_owned()).expect("invalid nodeid"))
-        .expect("error building frr config");
+    let mut frr_config = FrrConfig::default();
+    build_fabric(
+        NodeId::from_string("pve".to_owned()).expect("invalid nodeid"),
+        config.clone(),
+        &mut frr_config,
+    )
+    .unwrap();
 
     let mut output = dump(&frr_config).expect("error dumping stuff");
 
     insta::assert_snapshot!(helper::reference_name!("pve"), output);
 
-    frr_config = FrrConfigBuilder::default()
-        .add_fabrics(config.clone())
-        .build(NodeId::from_string("pve1".to_owned()).expect("invalid nodeid"))
-        .expect("error building frr config");
+    frr_config = FrrConfig::default();
+    build_fabric(
+        NodeId::from_string("pve1".to_owned()).expect("invalid nodeid"),
+        config,
+        &mut frr_config,
+    )
+    .unwrap();
 
     output = dump(&frr_config).expect("error dumping stuff");
 
@@ -40,20 +44,26 @@ fn openfabric_default() {
 #[test]
 fn ospf_default() {
     let config = FabricConfig::parse_section_config(helper::get_fabrics_config!()).unwrap();
+    let mut frr_config = FrrConfig::default();
 
-    let mut frr_config = FrrConfigBuilder::default()
-        .add_fabrics(config.clone())
-        .build(NodeId::from_string("pve".to_owned()).expect("invalid nodeid"))
-        .expect("error building frr config");
+    build_fabric(
+        NodeId::from_string("pve".to_owned()).expect("invalid nodeid"),
+        config.clone(),
+        &mut frr_config,
+    )
+    .unwrap();
 
     let mut output = dump(&frr_config).expect("error dumping stuff");
 
     insta::assert_snapshot!(helper::reference_name!("pve"), output);
 
-    frr_config = FrrConfigBuilder::default()
-        .add_fabrics(config)
-        .build(NodeId::from_string("pve1".to_owned()).expect("invalid nodeid"))
-        .expect("error building frr config");
+    frr_config = FrrConfig::default();
+    build_fabric(
+        NodeId::from_string("pve1".to_owned()).expect("invalid nodeid"),
+        config,
+        &mut frr_config,
+    )
+    .unwrap();
 
     output = dump(&frr_config).expect("error dumping stuff");
 
@@ -87,11 +97,14 @@ fn ospf_loopback_prefix_fail() {
 #[test]
 fn openfabric_multi_fabric() {
     let config = FabricConfig::parse_section_config(helper::get_fabrics_config!()).unwrap();
+    let mut frr_config = FrrConfig::default();
 
-    let frr_config = FrrConfigBuilder::default()
-        .add_fabrics(config)
-        .build(NodeId::from_string("pve1".to_owned()).expect("invalid nodeid"))
-        .expect("error building frr config");
+    build_fabric(
+        NodeId::from_string("pve1".to_owned()).expect("invalid nodeid"),
+        config,
+        &mut frr_config,
+    )
+    .unwrap();
 
     let output = dump(&frr_config).expect("error dumping stuff");
 
@@ -101,12 +114,14 @@ fn openfabric_multi_fabric() {
 #[test]
 fn ospf_multi_fabric() {
     let config = FabricConfig::parse_section_config(helper::get_fabrics_config!()).unwrap();
-
-    let frr_config = FrrConfigBuilder::default()
-        .add_fabrics(config)
-        .build(NodeId::from_string("pve1".to_owned()).expect("invalid nodeid"))
-        .expect("error building frr config");
-
+    let mut frr_config = FrrConfig::default();
+
+    build_fabric(
+        NodeId::from_string("pve1".to_owned()).expect("invalid nodeid"),
+        config,
+        &mut frr_config,
+    )
+    .unwrap();
     let output = dump(&frr_config).expect("error dumping stuff");
 
     insta::assert_snapshot!(helper::reference_name!("pve1"), output);
@@ -115,11 +130,14 @@ fn ospf_multi_fabric() {
 #[test]
 fn openfabric_dualstack() {
     let config = FabricConfig::parse_section_config(helper::get_fabrics_config!()).unwrap();
+    let mut frr_config = FrrConfig::default();
 
-    let frr_config = FrrConfigBuilder::default()
-        .add_fabrics(config)
-        .build(NodeId::from_string("pve".to_owned()).expect("invalid nodeid"))
-        .expect("error building frr config");
+    build_fabric(
+        NodeId::from_string("pve".to_owned()).expect("invalid nodeid"),
+        config,
+        &mut frr_config,
+    )
+    .unwrap();
 
     let output = dump(&frr_config).expect("error dumping stuff");
 
@@ -129,11 +147,14 @@ fn openfabric_dualstack() {
 #[test]
 fn openfabric_ipv6_only() {
     let config = FabricConfig::parse_section_config(helper::get_fabrics_config!()).unwrap();
-
-    let frr_config = FrrConfigBuilder::default()
-        .add_fabrics(config)
-        .build(NodeId::from_string("pve".to_owned()).expect("invalid nodeid"))
-        .expect("error building frr config");
+    let mut frr_config = FrrConfig::default();
+
+    build_fabric(
+        NodeId::from_string("pve".to_owned()).expect("invalid nodeid"),
+        config,
+        &mut frr_config,
+    )
+    .unwrap();
 
     let output = dump(&frr_config).expect("error dumping stuff");
 
-- 
2.47.3





  parent reply	other threads:[~2026-02-03 16:02 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-03 16:01 [PATCH docs/manager/network/proxmox{-ve-rs,-perl-rs} 00/23] Generate frr config using jinja templates and rust types Gabriel Goller
2026-02-03 16:01 ` [PATCH proxmox-ve-rs 1/9] ve-config: firewall: cargo fmt Gabriel Goller
2026-02-03 16:01 ` [PATCH proxmox-ve-rs 2/9] frr: add proxmox-frr-templates package that contains templates Gabriel Goller
2026-02-03 16:01 ` Gabriel Goller [this message]
2026-02-03 16:01 ` [PATCH proxmox-ve-rs 4/9] sdn-types: support variable-length NET identifier Gabriel Goller
2026-02-03 16:01 ` [PATCH proxmox-ve-rs 5/9] frr: add template serializer and serialize fabrics using templates Gabriel Goller
2026-02-03 16:01 ` [PATCH proxmox-ve-rs 6/9] frr: add isis configuration and templates Gabriel Goller
2026-02-03 16:01 ` [PATCH proxmox-ve-rs 7/9] frr: support custom frr configuration lines Gabriel Goller
2026-02-03 16:01 ` [PATCH proxmox-ve-rs 8/9] frr: add bgp support with templates and serialization Gabriel Goller
2026-02-03 16:01 ` [PATCH proxmox-ve-rs 9/9] frr: store frr template content as a const map Gabriel Goller
2026-02-03 16:01 ` [PATCH proxmox-perl-rs 1/2] sdn: add function to generate the frr config for all daemons Gabriel Goller
2026-02-03 16:01 ` [PATCH proxmox-perl-rs 2/2] sdn: add method to get a frr template Gabriel Goller
2026-02-03 16:01 ` [PATCH pve-network 01/10] sdn: remove duplicate comment line '!' in frr config Gabriel Goller
2026-02-03 16:01 ` [PATCH pve-network 02/10] sdn: tests: add missing comment " Gabriel Goller
2026-02-03 16:01 ` [PATCH pve-network 03/10] tests: use Test::Differences to make test assertions Gabriel Goller
2026-02-03 16:01 ` [PATCH pve-network 04/10] sdn: write structured frr config that can be rendered using templates Gabriel Goller
2026-02-03 16:01 ` [PATCH pve-network 05/10] tests: rearrange some statements in the frr config Gabriel Goller
2026-02-03 16:01 ` [PATCH pve-network 06/10] sdn: adjust frr.conf.local merging to rust template types Gabriel Goller
2026-02-03 16:01 ` [PATCH pve-network 07/10] cli: add pvesdn cli tool for managing frr template overrides Gabriel Goller
2026-02-03 16:01 ` [PATCH pve-network 08/10] debian: handle user modifications to FRR templates via ucf Gabriel Goller
2026-02-03 16:01 ` [PATCH pve-network 09/10] api: add dry-run endpoint for sdn apply to preview changes Gabriel Goller
2026-02-03 16:01 ` [PATCH pve-network 10/10] test: add test for frr.conf.local merging Gabriel Goller
2026-02-03 16:01 ` [PATCH pve-manager 1/1] sdn: add dry-run view for sdn apply Gabriel Goller
2026-02-03 16:01 ` [PATCH pve-docs 1/1] docs: add man page for the `pvesdn` cli Gabriel Goller

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=20260203160246.353351-4-g.goller@proxmox.com \
    --to=g.goller@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