From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 058C11FF165 for ; Thu, 22 May 2025 18:21:42 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 29974AD25; Thu, 22 May 2025 18:18:23 +0200 (CEST) From: Stefan Hanreich To: pve-devel@lists.proxmox.com Date: Thu, 22 May 2025 18:16:40 +0200 Message-Id: <20250522161731.537011-25-s.hanreich@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250522161731.537011-1-s.hanreich@proxmox.com> References: <20250522161731.537011-1-s.hanreich@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.228 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 KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods RDNS_NONE 0.793 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Subject: [pve-devel] [PATCH proxmox-ve-rs v3 19/21] 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" 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 b7d1f2d..57e2e6f 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::{ @@ -28,6 +31,7 @@ use crate::sdn::fabric::section_config::{ OspfNodePropertiesUpdater, OspfProperties, OspfPropertiesUpdater, }, }, + Either, Section, }; #[derive(thiserror::Error, Debug)] @@ -638,4 +642,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 = Either::from(section); + + match fabric_or_node { + Either::Left(fabric) => { + fabrics.insert(fabric.id().clone(), FabricEntry::from(fabric)); + } + Either::Right(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::msg) + } + + /// 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