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 95C071FF13C for ; Thu, 19 Feb 2026 15:58:52 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 91DEF19D63; Thu, 19 Feb 2026 15:57:46 +0100 (CET) From: Stefan Hanreich To: pve-devel@lists.proxmox.com Subject: [PATCH proxmox-ve-rs 7/9] ve-config: sdn: fabrics: add wireguard to the fabric config Date: Thu, 19 Feb 2026 15:56:26 +0100 Message-ID: <20260219145649.441418-10-s.hanreich@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260219145649.441418-1-s.hanreich@proxmox.com> References: <20260219145649.441418-1-s.hanreich@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.175 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 Message-ID-Hash: L3C6K2ZG2INLHOKATPVYBLGV4J7MDWX2 X-Message-ID-Hash: L3C6K2ZG2INLHOKATPVYBLGV4J7MDWX2 X-MailFrom: hoan@cray.proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Use the newly created WireGuard section types to add the WireGuard variants to the existing fabrics section config enum. By adding the new WireGuard variants, they are automatically exposed via the API methods defined in proxmox-perl-rs and are available for the existing CRUD endpoints in pve-network. Originally-by: Christoph Heiss Signed-off-by: Stefan Hanreich --- proxmox-ve-config/src/sdn/fabric/frr.rs | 1 + proxmox-ve-config/src/sdn/fabric/mod.rs | 168 ++++++++++++++++++ .../src/sdn/fabric/section_config/fabric.rs | 25 +++ .../src/sdn/fabric/section_config/mod.rs | 58 ++++++ .../src/sdn/fabric/section_config/node.rs | 44 ++++- 5 files changed, 292 insertions(+), 4 deletions(-) diff --git a/proxmox-ve-config/src/sdn/fabric/frr.rs b/proxmox-ve-config/src/sdn/fabric/frr.rs index 10025b3..fc41410 100644 --- a/proxmox-ve-config/src/sdn/fabric/frr.rs +++ b/proxmox-ve-config/src/sdn/fabric/frr.rs @@ -232,6 +232,7 @@ pub fn build_fabric( frr_config.protocol_routemaps.insert(protocol_routemap); } + FabricEntry::WireGuard(_) => {} // not a frr fabric } } Ok(()) diff --git a/proxmox-ve-config/src/sdn/fabric/mod.rs b/proxmox-ve-config/src/sdn/fabric/mod.rs index d0add92..53ce87f 100644 --- a/proxmox-ve-config/src/sdn/fabric/mod.rs +++ b/proxmox-ve-config/src/sdn/fabric/mod.rs @@ -7,6 +7,7 @@ use std::marker::PhantomData; use std::ops::Deref; use anyhow::Error; +use section_config::protocol::wireguard::WireGuardProperties; use serde::{Deserialize, Serialize}; use proxmox_section_config::typed::{ApiSectionDataEntry, SectionConfigData}; @@ -28,6 +29,10 @@ use crate::sdn::fabric::section_config::protocol::ospf::{ OspfDeletableProperties, OspfNodeDeletableProperties, OspfNodeProperties, OspfNodePropertiesUpdater, OspfProperties, OspfPropertiesUpdater, }; +use crate::sdn::fabric::section_config::protocol::wireguard::{ + WireGuardDeletableProperties, WireGuardNode, WireGuardNodeDeletableProperties, + WireGuardNodeUpdater, WireGuardPropertiesUpdater, +}; use crate::sdn::fabric::section_config::{FabricOrNode, Section}; #[derive(thiserror::Error, Debug)] @@ -189,6 +194,7 @@ macro_rules! impl_entry { impl_entry!(Openfabric, OpenfabricProperties, OpenfabricNodeProperties); impl_entry!(Ospf, OspfProperties, OspfNodeProperties); +impl_entry!(WireGuard, WireGuardProperties, WireGuardNode); /// All possible entries in a [`FabricConfig`]. /// @@ -198,6 +204,7 @@ impl_entry!(Ospf, OspfProperties, OspfNodeProperties); pub enum FabricEntry { Openfabric(Entry), Ospf(Entry), + WireGuard(Entry), } impl FabricEntry { @@ -209,6 +216,9 @@ impl FabricEntry { entry.add_node(node_section) } (FabricEntry::Ospf(entry), Node::Ospf(node_section)) => entry.add_node(node_section), + (FabricEntry::WireGuard(entry), Node::WireGuard(node_section)) => { + entry.add_node(node_section) + } _ => Err(FabricConfigError::ProtocolMismatch), } } @@ -219,6 +229,7 @@ impl FabricEntry { match self { FabricEntry::Openfabric(entry) => entry.get_node(id), FabricEntry::Ospf(entry) => entry.get_node(id), + FabricEntry::WireGuard(entry) => entry.get_node(id), } } @@ -228,6 +239,7 @@ impl FabricEntry { match self { FabricEntry::Openfabric(entry) => entry.get_node_mut(id), FabricEntry::Ospf(entry) => entry.get_node_mut(id), + FabricEntry::WireGuard(entry) => entry.get_node_mut(id), } } @@ -307,6 +319,109 @@ impl FabricEntry { Ok(()) } + (Node::WireGuard(node_section), NodeUpdater::WireGuard(updater)) => { + let NodeDataUpdater:: { + ip, + ip6, + properties, + delete, + } = updater; + + if let Some(ip) = ip { + node_section.ip = Some(ip); + } + + if let Some(ip) = ip6 { + node_section.ip6 = Some(ip); + } + + for property in &delete { + match property { + NodeDeletableProperties::Ip => node_section.ip = None, + NodeDeletableProperties::Ip6 => node_section.ip6 = None, + // handled below, since internal / external nodes have different properties + NodeDeletableProperties::Protocol(_) => continue, + } + } + + match (node_section.properties_mut(), properties) { + ( + WireGuardNode::Internal(internal_wireguard_node), + WireGuardNodeUpdater::Internal(internal_wireguard_node_updater), + ) => { + if let Some(interfaces) = internal_wireguard_node_updater.interfaces { + internal_wireguard_node.interfaces = interfaces; + } + + if let Some(endpoint) = internal_wireguard_node_updater.endpoint { + internal_wireguard_node.endpoint = Some(endpoint); + } + + if let Some(peers) = internal_wireguard_node_updater.peers { + internal_wireguard_node.peers = peers; + } + + if let Some(allowed_ips) = internal_wireguard_node_updater.allowed_ips { + internal_wireguard_node.allowed_ips = allowed_ips; + } + + for property in &delete { + match property { + NodeDeletableProperties::Protocol(protocol_property) => { + match protocol_property { + WireGuardNodeDeletableProperties::Interfaces => { + internal_wireguard_node.interfaces = Vec::new() + } + WireGuardNodeDeletableProperties::Endpoint => { + internal_wireguard_node.endpoint = None + } + WireGuardNodeDeletableProperties::Peers => { + internal_wireguard_node.peers = Vec::new() + } + WireGuardNodeDeletableProperties::AllowedIps => { + internal_wireguard_node.allowed_ips = Vec::new() + } + } + } + _ => continue, + } + } + } + ( + WireGuardNode::External(external_wire_guard_node), + WireGuardNodeUpdater::External(external_wire_guard_node_updater), + ) => { + if let Some(endpoint) = external_wire_guard_node_updater.endpoint { + external_wire_guard_node.endpoint = endpoint; + } + + if let Some(public_key) = external_wire_guard_node_updater.public_key { + external_wire_guard_node.public_key = public_key; + } + + if let Some(allowed_ips) = external_wire_guard_node_updater.allowed_ips { + external_wire_guard_node.allowed_ips = allowed_ips; + } + + for property in &delete { + match property { + NodeDeletableProperties::Protocol(protocol_property) => { + match protocol_property { + WireGuardNodeDeletableProperties::AllowedIps => { + external_wire_guard_node.allowed_ips = Vec::new() + } + _ => return Err(FabricConfigError::ProtocolMismatch), + } + } + _ => continue, + } + } + } + _ => return Err(FabricConfigError::ProtocolMismatch), + } + + Ok(()) + } _ => Err(FabricConfigError::ProtocolMismatch), } } @@ -316,6 +431,7 @@ impl FabricEntry { match self { FabricEntry::Openfabric(entry) => entry.nodes.iter(), FabricEntry::Ospf(entry) => entry.nodes.iter(), + FabricEntry::WireGuard(entry) => entry.nodes.iter(), } } @@ -324,6 +440,7 @@ impl FabricEntry { match self { FabricEntry::Openfabric(entry) => entry.delete_node(id), FabricEntry::Ospf(entry) => entry.delete_node(id), + FabricEntry::WireGuard(entry) => entry.delete_node(id), } } @@ -333,6 +450,7 @@ impl FabricEntry { match self { FabricEntry::Openfabric(entry) => entry.into_pair(), FabricEntry::Ospf(entry) => entry.into_pair(), + FabricEntry::WireGuard(entry) => entry.into_pair(), } } @@ -341,6 +459,7 @@ impl FabricEntry { match self { FabricEntry::Openfabric(entry) => &entry.fabric, FabricEntry::Ospf(entry) => &entry.fabric, + FabricEntry::WireGuard(entry) => &entry.fabric, } } @@ -349,6 +468,7 @@ impl FabricEntry { match self { FabricEntry::Openfabric(entry) => &mut entry.fabric, FabricEntry::Ospf(entry) => &mut entry.fabric, + FabricEntry::WireGuard(entry) => &mut entry.fabric, } } } @@ -360,6 +480,7 @@ impl From for FabricEntry { FabricEntry::Openfabric(Entry::new(fabric_section)) } Fabric::Ospf(fabric_section) => FabricEntry::Ospf(Entry::new(fabric_section)), + Fabric::WireGuard(fabric_section) => FabricEntry::WireGuard(Entry::new(fabric_section)), } } } @@ -541,6 +662,9 @@ impl Validatable for FabricConfig { return Err(FabricConfigError::DuplicateInterface); } } + Node::WireGuard(_node_section) => { + return Ok(()); + } } } @@ -695,6 +819,50 @@ impl FabricConfig { Ok(()) } + (Fabric::WireGuard(fabric_section), FabricUpdater::WireGuard(updater)) => { + let FabricSectionUpdater::< + WireGuardPropertiesUpdater, + WireGuardDeletableProperties, + > { + ip_prefix, + ip6_prefix, + properties: + WireGuardPropertiesUpdater { + persistent_keepalive, + }, + delete, + } = updater; + + if let Some(prefix) = ip_prefix { + fabric_section.ip_prefix = Some(prefix); + } + + if let Some(prefix) = ip6_prefix { + fabric_section.ip6_prefix = Some(prefix); + } + + if let Some(keepalive) = persistent_keepalive { + fabric_section.properties.persistent_keepalive = Some(keepalive); + } + + for property in delete { + match property { + FabricDeletableProperties::IpPrefix => { + fabric_section.ip_prefix = None; + } + FabricDeletableProperties::Ip6Prefix => { + fabric_section.ip6_prefix = None; + } + FabricDeletableProperties::Protocol( + WireGuardDeletableProperties::PersistentKeepalive, + ) => { + fabric_section.properties.persistent_keepalive = None; + } + } + } + + Ok(()) + } _ => Err(FabricConfigError::ProtocolMismatch), } } diff --git a/proxmox-ve-config/src/sdn/fabric/section_config/fabric.rs b/proxmox-ve-config/src/sdn/fabric/section_config/fabric.rs index 38911a6..e92074c 100644 --- a/proxmox-ve-config/src/sdn/fabric/section_config/fabric.rs +++ b/proxmox-ve-config/src/sdn/fabric/section_config/fabric.rs @@ -16,6 +16,10 @@ use crate::sdn::fabric::section_config::protocol::ospf::{ }; use crate::sdn::fabric::FabricConfigError; +use super::protocol::wireguard::{ + WireGuardDeletableProperties, WireGuardProperties, WireGuardPropertiesUpdater, +}; + pub const FABRIC_ID_REGEX_STR: &str = r"(?:[a-zA-Z0-9])(?:[a-zA-Z0-9\-]){0,6}(?:[a-zA-Z0-9])?"; const_regex! { @@ -139,6 +143,10 @@ impl UpdaterType for FabricSection { type Updater = FabricSectionUpdater; } +impl UpdaterType for FabricSection { + type Updater = FabricSectionUpdater; +} + /// Enum containing all types of fabrics. /// /// It utilizes [`FabricSection`] to define all possible types of fabrics. For parsing the @@ -159,6 +167,8 @@ impl UpdaterType for FabricSection { pub enum Fabric { Openfabric(FabricSection), Ospf(FabricSection), + #[serde(rename = "wireguard")] + WireGuard(FabricSection), } impl UpdaterType for Fabric { @@ -173,6 +183,7 @@ impl Fabric { match self { Self::Openfabric(fabric_section) => fabric_section.id(), Self::Ospf(fabric_section) => fabric_section.id(), + Self::WireGuard(fabric_section) => fabric_section.id(), } } @@ -183,6 +194,7 @@ impl Fabric { match self { Fabric::Openfabric(fabric_section) => fabric_section.ip_prefix(), Fabric::Ospf(fabric_section) => fabric_section.ip_prefix(), + Fabric::WireGuard(fabric_section) => fabric_section.ip_prefix(), } } @@ -193,6 +205,7 @@ impl Fabric { match self { Fabric::Openfabric(fabric_section) => fabric_section.ip_prefix = Some(ipv4_cidr), Fabric::Ospf(fabric_section) => fabric_section.ip_prefix = Some(ipv4_cidr), + Fabric::WireGuard(fabric_section) => fabric_section.ip_prefix = Some(ipv4_cidr), } } @@ -203,6 +216,7 @@ impl Fabric { match self { Fabric::Openfabric(fabric_section) => fabric_section.ip6_prefix(), Fabric::Ospf(fabric_section) => fabric_section.ip6_prefix(), + Fabric::WireGuard(fabric_section) => fabric_section.ip6_prefix(), } } @@ -213,6 +227,7 @@ impl Fabric { match self { Fabric::Openfabric(fabric_section) => fabric_section.ip6_prefix = Some(ipv6_cidr), Fabric::Ospf(fabric_section) => fabric_section.ip6_prefix = Some(ipv6_cidr), + Fabric::WireGuard(fabric_section) => fabric_section.ip6_prefix = Some(ipv6_cidr), } } } @@ -225,6 +240,7 @@ impl Validatable for Fabric { match self { Fabric::Openfabric(fabric_section) => fabric_section.validate(), Fabric::Ospf(fabric_section) => fabric_section.validate(), + Fabric::WireGuard(_fabric_section) => Ok(()), } } } @@ -241,12 +257,20 @@ impl From> for Fabric { } } +impl From> for Fabric { + fn from(section: FabricSection) -> Self { + Fabric::WireGuard(section) + } +} + /// Enum containing all updater types for fabrics #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "snake_case", tag = "protocol")] pub enum FabricUpdater { Openfabric( as UpdaterType>::Updater), Ospf( as UpdaterType>::Updater), + #[serde(rename = "wireguard")] + WireGuard( as UpdaterType>::Updater), } impl Updater for FabricUpdater { @@ -254,6 +278,7 @@ impl Updater for FabricUpdater { match self { FabricUpdater::Openfabric(updater) => updater.is_empty(), FabricUpdater::Ospf(updater) => updater.is_empty(), + FabricUpdater::WireGuard(updater) => updater.is_empty(), } } } diff --git a/proxmox-ve-config/src/sdn/fabric/section_config/mod.rs b/proxmox-ve-config/src/sdn/fabric/section_config/mod.rs index d02d4ae..f47a522 100644 --- a/proxmox-ve-config/src/sdn/fabric/section_config/mod.rs +++ b/proxmox-ve-config/src/sdn/fabric/section_config/mod.rs @@ -4,6 +4,7 @@ pub mod node; pub mod protocol; use const_format::concatcp; +use protocol::wireguard::WireGuardProperties; use serde::{Deserialize, Serialize}; use crate::sdn::fabric::section_config::{ @@ -12,6 +13,7 @@ use crate::sdn::fabric::section_config::{ protocol::{ openfabric::{OpenfabricNodeProperties, OpenfabricProperties}, ospf::{OspfNodeProperties, OspfProperties}, + wireguard::WireGuardNode, }, }; @@ -31,8 +33,10 @@ impl From
for FabricOrNode { match section { Section::OpenfabricFabric(fabric_section) => Self::Fabric(fabric_section.into()), Section::OspfFabric(fabric_section) => Self::Fabric(fabric_section.into()), + Section::WireGuardFabric(fabric_section) => Self::Fabric(fabric_section.into()), Section::OpenfabricNode(node_section) => Self::Node(node_section.into()), Section::OspfNode(node_section) => Self::Node(node_section.into()), + Section::WireGuardNode(node_section) => Self::Node(node_section.into()), } } } @@ -62,8 +66,12 @@ pub const SECTION_ID_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&SECTION pub enum Section { OpenfabricFabric(FabricSection), OspfFabric(FabricSection), + #[serde(rename = "wireguard_fabric")] + WireGuardFabric(FabricSection), OpenfabricNode(NodeSection), OspfNode(NodeSection), + #[serde(rename = "wireguard_node")] + WireGuardNode(NodeSection), } impl From> for Section { @@ -78,6 +86,12 @@ impl From> for Section { } } +impl From> for Section { + fn from(section: FabricSection) -> Self { + Self::WireGuardFabric(section) + } +} + impl From> for Section { fn from(section: NodeSection) -> Self { Self::OpenfabricNode(section) @@ -90,11 +104,18 @@ impl From> for Section { } } +impl From> for Section { + fn from(section: NodeSection) -> Self { + Self::WireGuardNode(section) + } +} + impl From for Section { fn from(fabric: Fabric) -> Self { match fabric { Fabric::Openfabric(fabric_section) => fabric_section.into(), Fabric::Ospf(fabric_section) => fabric_section.into(), + Fabric::WireGuard(fabric_section) => fabric_section.into(), } } } @@ -104,6 +125,43 @@ impl From for Section { match node { Node::Openfabric(node_section) => node_section.into(), Node::Ospf(node_section) => node_section.into(), + Node::WireGuard(node_section) => node_section.into(), } } } + +#[cfg(test)] +mod tests { + use crate::sdn::fabric::FabricConfig; + use proxmox_section_config::typed::ApiSectionDataEntry; + + use super::*; + + #[test] + fn test_wireguard_fabric() -> Result<(), anyhow::Error> { + let section_config = r#" +wireguard_fabric: wireg + +wireguard_node: wireg_external + role external + endpoint 192.0.2.1:123 + public_key Kay64UG8yvCyLhqU000LxzYeUm0L/hLIl5S8kyKWbdc= + +wireguard_node: wireg_pve1 + role internal + endpoint 192.0.2.2 + interfaces name=wg0,listen_port=51111,public_key=Kay64UG8yvCyLhqU000LxzYeUm0L/hLIl5S8kyKWbdc= + peers type=internal,node=pve2,node_iface=wg0,iface=wg0 + +wireguard_node: wireg_pve2 + role internal + endpoint 192.0.2.3 + interfaces name=wg0,listen_port=51111,public_key=Kay64UG8yvCyLhqU000LxzYeUm0L/hLIl5S8kyKWbdc= + peers type=internal,node=pve1,node_iface=wg0,iface=wg0 +"#; + let parsed_config = Section::parse_section_config("fabrics.cfg", section_config)?; + FabricConfig::from_section_config(parsed_config).expect("valid wireguard configuration"); + + Ok(()) + } +} diff --git a/proxmox-ve-config/src/sdn/fabric/section_config/node.rs b/proxmox-ve-config/src/sdn/fabric/section_config/node.rs index 17d2f0b..77ce15f 100644 --- a/proxmox-ve-config/src/sdn/fabric/section_config/node.rs +++ b/proxmox-ve-config/src/sdn/fabric/section_config/node.rs @@ -10,6 +10,7 @@ use proxmox_schema::{ }; use crate::common::valid::Validatable; +use crate::sdn::fabric::section_config::protocol::wireguard::WireGuardNode; use crate::sdn::fabric::section_config::{ fabric::{FabricId, FABRIC_ID_REGEX_STR}, protocol::{openfabric::OpenfabricNodeProperties, ospf::OspfNodeProperties}, @@ -36,6 +37,18 @@ api_string_type! { pub struct NodeId(String); } +impl std::str::FromStr for NodeId { + type Err = anyhow::Error; + + fn from_str(value: &str) -> Result { + Self::API_SCHEMA + .unwrap_string_schema() + .check_constraints(value)?; + + Ok(unsafe { Self::from_string_unchecked(value.to_string()) }) + } +} + /// ID of a node in the section config. /// /// This corresponds to the ID of the fabric, that contains this node, as well as the hostname of @@ -147,8 +160,8 @@ impl NodeSection { /// Get the IPv4 address (Router-ID) of the [`NodeSection`]. /// /// Either the [`NodeSection::ip`] (IPv4) address or the [`NodeSection::ip6`] (IPv6) address *must* - /// be set. This is checked during the validation, so it's guaranteed. OpenFabric can also be - /// used dual-stack, so both IPv4 and IPv6 addresses can be set. + /// be set. This is checked during the validation, so it's guaranteed. OpenFabric and WireGuard + /// can also be used dual-stack, so both IPv4 and IPv6 addresses can be set. pub fn ip(&self) -> Option { self.ip.as_deref().copied() } @@ -156,8 +169,8 @@ impl NodeSection { /// Get the IPv6 address (Router-ID) of the [`NodeSection`]. /// /// Either the [`NodeSection::ip`] (IPv4) address or the [`NodeSection::ip6`] (IPv6) address *must* - /// be set. This is checked during the validation, so it's guaranteed. OpenFabric can also be - /// used dual-stack, so both IPv4 and IPv6 addresses can be set. + /// be set. This is checked during the validation, so it's guaranteed. OpenFabric and WireGuard + /// can also be used dual-stack, so both IPv4 and IPv6 addresses can be set. pub fn ip6(&self) -> Option { self.ip6.as_deref().copied() } @@ -186,6 +199,8 @@ impl ApiType for NodeSection { pub enum Node { Openfabric(NodeSection), Ospf(NodeSection), + #[serde(rename = "wireguard")] + WireGuard(NodeSection), } impl Node { @@ -194,6 +209,7 @@ impl Node { match self { Node::Openfabric(node_section) => node_section.id(), Node::Ospf(node_section) => node_section.id(), + Node::WireGuard(node_section) => node_section.id(), } } @@ -202,6 +218,7 @@ impl Node { match self { Node::Openfabric(node_section) => node_section.ip(), Node::Ospf(node_section) => node_section.ip(), + Node::WireGuard(node_section) => node_section.ip(), } } @@ -210,6 +227,7 @@ impl Node { match self { Node::Openfabric(node_section) => node_section.ip6(), Node::Ospf(node_section) => node_section.ip6(), + Node::WireGuard(node_section) => node_section.ip6(), } } } @@ -221,6 +239,7 @@ impl Validatable for Node { match self { Node::Openfabric(node_section) => node_section.validate(), Node::Ospf(node_section) => node_section.validate(), + Node::WireGuard(_node_section) => Ok(()), } } } @@ -237,6 +256,12 @@ impl From> for Node { } } +impl From> for Node { + fn from(value: NodeSection) -> Self { + Self::WireGuard(value) + } +} + /// API types for SDN fabric node configurations. /// /// This module provides specialized types that are used for API interactions when retrieving, @@ -263,6 +288,7 @@ pub mod api { OpenfabricNodePropertiesUpdater, }, ospf::{OspfNodeDeletableProperties, OspfNodeProperties, OspfNodePropertiesUpdater}, + wireguard::{WireGuardNodeDeletableProperties, WireGuardNodeUpdater}, }; use super::*; @@ -320,6 +346,8 @@ pub mod api { pub enum Node { Openfabric(NodeData), Ospf(NodeData), + #[serde(rename = "wireguard")] + WireGuard(NodeData), } impl From for Node { @@ -327,6 +355,7 @@ pub mod api { match value { super::Node::Openfabric(node_section) => Self::Openfabric(node_section.into()), super::Node::Ospf(node_section) => Self::Ospf(node_section.into()), + super::Node::WireGuard(node_section) => Self::WireGuard(node_section.into()), } } } @@ -336,6 +365,7 @@ pub mod api { match value { Node::Openfabric(node_section) => Self::Openfabric(node_section.into()), Node::Ospf(node_section) => Self::Ospf(node_section.into()), + Node::WireGuard(node_section) => Self::WireGuard(node_section.into()), } } } @@ -349,6 +379,10 @@ pub mod api { type Updater = NodeDataUpdater; } + impl UpdaterType for NodeData { + type Updater = NodeDataUpdater; + } + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NodeDataUpdater { #[serde(skip_serializing_if = "Option::is_none")] @@ -384,6 +418,8 @@ pub mod api { NodeDataUpdater, ), Ospf(NodeDataUpdater), + #[serde(rename = "wireguard")] + WireGuard(NodeDataUpdater), } #[derive(Debug, Clone, Serialize, Deserialize)] -- 2.47.3