[pve-devel] [PATCH proxmox-ve-rs v2 09/15] ve-config: add common section-config types for OpenFabric and OSPF

Gabriel Goller g.goller at proxmox.com
Fri Apr 4 18:28:21 CEST 2025


Introduce shared types for SDN fabric configuration:
- FabricId: String identifier used in both OpenFabric and OSPF configurations
- NodeId: Composite identifier for fabric nodes consisting of FabricId and Hostname
- SectionType: Enum differentiating between fabric and node sections, automatically
  added as a "type" property

These allow us to be somewhat generic over the protocol type (in e.g.
permissions).

Signed-off-by: Gabriel Goller <g.goller at proxmox.com>
---
 proxmox-ve-config/src/sdn/fabric/mod.rs | 111 ++++++++++++++++++++++++
 1 file changed, 111 insertions(+)
 create mode 100644 proxmox-ve-config/src/sdn/fabric/mod.rs

diff --git a/proxmox-ve-config/src/sdn/fabric/mod.rs b/proxmox-ve-config/src/sdn/fabric/mod.rs
new file mode 100644
index 000000000000..5b24a3be8c17
--- /dev/null
+++ b/proxmox-ve-config/src/sdn/fabric/mod.rs
@@ -0,0 +1,111 @@
+pub mod openfabric;
+pub mod ospf;
+
+use proxmox_network_types::debian::Hostname;
+use proxmox_section_config::typed::ApiSectionDataEntry;
+use proxmox_section_config::typed::SectionConfigData;
+
+use std::ops::Deref;
+
+use serde::de::DeserializeOwned;
+use serde_with::{DeserializeFromStr, SerializeDisplay};
+
+#[derive(
+    SerializeDisplay, DeserializeFromStr, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
+)]
+pub struct FabricId(String);
+
+impl FabricId {
+    pub fn new(id: impl Into<String>) -> Result<Self, anyhow::Error> {
+        let value = id.into();
+        if value.len() <= 8 {
+            Ok(Self(value))
+        } else {
+            anyhow::bail!("FabricId has to be shorter than 8 characters");
+        }
+    }
+}
+
+impl AsRef<str> for FabricId {
+    fn as_ref(&self) -> &str {
+        &self.0
+    }
+}
+
+impl std::str::FromStr for FabricId {
+    type Err = anyhow::Error;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        Self::new(s)
+    }
+}
+
+impl std::fmt::Display for FabricId {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+#[derive(SerializeDisplay, DeserializeFromStr, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct NodeId {
+    pub fabric_id: FabricId,
+    pub node_id: Hostname,
+}
+
+impl std::fmt::Display for NodeId {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}_{}", self.fabric_id, self.node_id)
+    }
+}
+
+impl NodeId {
+    pub fn new(fabric_id: FabricId, node_id: Hostname) -> NodeId {
+        NodeId { fabric_id, node_id }
+    }
+}
+
+impl std::str::FromStr for NodeId {
+    type Err = anyhow::Error;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        if let Some((fabric_id, node_id)) = s.split_once('_') {
+            return Ok(NodeId {
+                fabric_id: fabric_id.parse()?,
+                node_id: node_id.parse()?,
+            });
+        }
+
+        anyhow::bail!("invalid node id");
+    }
+}
+
+#[derive(
+    SerializeDisplay, DeserializeFromStr, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
+)]
+pub enum SectionType {
+    Fabric,
+    Node,
+}
+
+impl std::fmt::Display for SectionType {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        let name = match self {
+            Self::Fabric => "fabric",
+            Self::Node => "node",
+        };
+
+        write!(f, "{name}")
+    }
+}
+
+impl std::str::FromStr for SectionType {
+    type Err = anyhow::Error;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        Ok(match s {
+            "fabric" => Self::Fabric,
+            "node" => Self::Node,
+            _ => anyhow::bail!("invalid fabric type: {s}"),
+        })
+    }
+}
-- 
2.39.5





More information about the pve-devel mailing list