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
next prev 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