From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 3B2D11FF183 for ; Wed, 16 Jul 2025 15:12:07 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 5166C10B33; Wed, 16 Jul 2025 15:09:42 +0200 (CEST) From: Gabriel Goller To: pve-devel@lists.proxmox.com Date: Wed, 16 Jul 2025 15:07:45 +0200 Message-Id: <20250716130837.585796-25-g.goller@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250716130837.585796-1-g.goller@proxmox.com> References: <20250716130837.585796-1-g.goller@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.014 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_MSPIKE_H2 0.001 Average reputation (+2) SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH proxmox-ve-rs v5 19/22] sdn: fabrics: config: add conversion from / to section config X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" From: Stefan Hanreich Add helper methods for populating a FabricConfig from the section config, as well as converting it back into the respective section config structs. By utilizing the Valid type, we can ensure that only valid configurations get written via the provided write_section_config method, since it is only implemented for Valid. Because validation can be expensive, particularly when doing multiple changes to the fabric config, we only validate the config directly before converting it into the section config. Co-authored-by: Gabriel Goller Signed-off-by: Stefan Hanreich --- proxmox-ve-config/src/sdn/fabric/mod.rs | 91 ++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/proxmox-ve-config/src/sdn/fabric/mod.rs b/proxmox-ve-config/src/sdn/fabric/mod.rs index 825f2346d9f3..7a185f8b1012 100644 --- a/proxmox-ve-config/src/sdn/fabric/mod.rs +++ b/proxmox-ve-config/src/sdn/fabric/mod.rs @@ -4,9 +4,12 @@ use std::collections::{BTreeMap, HashSet}; use std::marker::PhantomData; use std::ops::Deref; +use anyhow::Error; use serde::{Deserialize, Serialize}; -use crate::common::valid::Validatable; +use proxmox_section_config::typed::{ApiSectionDataEntry, SectionConfigData}; + +use crate::common::valid::{Valid, Validatable}; use crate::sdn::fabric::section_config::fabric::{ Fabric, FabricDeletableProperties, FabricId, FabricSection, FabricSectionUpdater, FabricUpdater, @@ -23,6 +26,7 @@ use crate::sdn::fabric::section_config::protocol::ospf::{ OspfDeletableProperties, OspfNodeDeletableProperties, OspfNodeProperties, OspfNodePropertiesUpdater, OspfProperties, OspfPropertiesUpdater, }; +use crate::sdn::fabric::section_config::{FabricOrNode, Section}; #[derive(thiserror::Error, Debug)] pub enum FabricConfigError { @@ -707,4 +711,89 @@ impl FabricConfig { _ => Err(FabricConfigError::ProtocolMismatch), } } + + /// Constructs a valid [`FabricConfig`] from section-config data. + /// + /// Iterates through the [`SectionConfigData
`] and matches on the [`Section`] enum. Then + /// construct the [`FabricConfig`] and validate it. + pub fn from_section_config( + config: SectionConfigData
, + ) -> Result, FabricConfigError> { + let mut fabrics = BTreeMap::new(); + let mut nodes = Vec::new(); + + for (_id, section) in config { + let fabric_or_node = FabricOrNode::from(section); + + match fabric_or_node { + FabricOrNode::Fabric(fabric) => { + fabrics.insert(fabric.id().clone(), FabricEntry::from(fabric)); + } + FabricOrNode::Node(node) => { + nodes.push(node); + } + }; + } + + for node in nodes { + fabrics + .get_mut(node.id().fabric_id()) + .ok_or_else(|| { + FabricConfigError::FabricDoesNotExist(node.id().fabric_id().to_string()) + })? + .add_node(node)?; + } + + let config = Self { fabrics }; + config.into_valid() + } + + /// Constructs a valid [`FabricConfig`] from the raw section-config file content. + /// + /// This will call the [`Section::parse_section_config`] function to parse the raw string into a + /// [`SectionConfigData
`] struct. Then construct the valid [`FabricConfig`] with + /// [`Self::from_section_config`]. + pub fn parse_section_config(config: &str) -> Result, Error> { + let data = Section::parse_section_config("fabrics.cfg", config)?; + Self::from_section_config(data).map_err(anyhow::Error::from) + } + + /// Validate [`FabricConfig`] and write the raw config to a String. + /// + /// Validates the config and calls [`Valid::write_section_config`]. + pub fn write_section_config(&self) -> Result { + self.clone().into_valid()?.write_section_config() + } +} + +impl Valid { + /// Converts a valid [`FabricConfig`] into a [`SectionConfigData
`]. + /// + /// This function is implemented on [`Valid`], ensuring that only a valid + /// [`FabricConfig`] can be written to the file. + pub fn into_section_config(self) -> SectionConfigData
{ + let config = self.into_inner(); + + let mut section_config = SectionConfigData::default(); + + for (fabric_id, fabric_entry) in config.fabrics { + let (fabric, fabric_nodes) = fabric_entry.into_section_config(); + + section_config.insert(fabric_id.to_string(), Section::from(fabric)); + + for node in fabric_nodes { + section_config.insert(node.id().to_string(), Section::from(node)); + } + } + + section_config + } + + /// Consumes the [`Valid`] and writes the raw section-config content to a String. + /// + /// This function is implemented on [`Valid`], ensuring that only a valid + /// [`FabricConfig`] can be written to the file. + pub fn write_section_config(self) -> Result { + Section::write_section_config("fabrics.cfg", &self.into_section_config()) + } } -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel