From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <pve-devel-bounces@lists.proxmox.com> Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id AFEFE1FF164 for <inbox@lore.proxmox.com>; Fri, 28 Mar 2025 18:14:58 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id A1DC9853B; Fri, 28 Mar 2025 18:14:00 +0100 (CET) From: Gabriel Goller <g.goller@proxmox.com> To: pve-devel@lists.proxmox.com Date: Fri, 28 Mar 2025 18:13:10 +0100 Message-Id: <20250328171340.885413-23-g.goller@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250328171340.885413-1-g.goller@proxmox.com> References: <20250328171340.885413-1-g.goller@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.025 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 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-perl-rs 3/7] perl-rs: sdn: OpenFabric perlmod methods X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com> List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe> List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/> List-Post: <mailto:pve-devel@lists.proxmox.com> List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help> List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe> Reply-To: Proxmox VE development discussion <pve-devel@lists.proxmox.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" <pve-devel-bounces@lists.proxmox.com> Add perlmod methods that call the previously introduced CRUD helpers. Also add a method that returns the FRR daemons to be enabled by pve-network and a method to validate and generate the FRR config. Signed-off-by: Gabriel Goller <g.goller@proxmox.com> Co-authored-by: Stefan Hanreich <s.hanreich@proxmox.com> --- pve-rs/src/sdn/openfabric.rs | 166 +++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/pve-rs/src/sdn/openfabric.rs b/pve-rs/src/sdn/openfabric.rs index 65d92d313b2a..680b3d081e47 100644 --- a/pve-rs/src/sdn/openfabric.rs +++ b/pve-rs/src/sdn/openfabric.rs @@ -221,4 +221,170 @@ mod export { OpenFabricSectionConfig::write_section_config("sdn/fabrics/openfabric.cfg", &guard) } } + + #[export(raw_return)] + fn running_config( + #[raw] class: Value, + raw_config: HashMap<String, OpenFabricSectionConfig>, + ) -> Result<perlmod::Value, anyhow::Error> { + // we cannot just construct it from the HashMap via From, since then the order is empty + let section_config = raw_config.into_iter().collect(); + + let return_value = PerlSectionConfig { + section_config: Mutex::new(section_config), + }; + + Ok(perlmod::instantiate_magic!(&class, MAGIC => Box::new( + return_value + ))) + } + + #[export(raw_return)] + fn config(#[raw] class: Value, raw_config: &[u8]) -> Result<perlmod::Value, anyhow::Error> { + let raw_config = std::str::from_utf8(raw_config)?; + + let config = OpenFabricSectionConfig::parse_section_config("openfabric.cfg", raw_config)?; + let return_value = PerlSectionConfig { + section_config: Mutex::new(config), + }; + + Ok(perlmod::instantiate_magic!(&class, MAGIC => Box::new( + return_value + ))) + } + + /// Writes the config to a string and returns the configuration and the protocol. + #[export] + fn write( + #[try_from_ref] this: &PerlSectionConfig<OpenFabricSectionConfig>, + ) -> Result<(String, String), Error> { + let full_new_config = this.write()?; + + // We return the protocol here as well, so that in perl we can write to + // the correct config file + Ok((full_new_config, "openfabric".to_string())) + } + + #[export] + fn add_fabric( + #[try_from_ref] this: &PerlSectionConfig<OpenFabricSectionConfig>, + new_config: AddFabric, + ) -> Result<(), Error> { + this.add_fabric(new_config)?; + + Ok(()) + } + + #[export] + fn add_node( + #[try_from_ref] this: &PerlSectionConfig<OpenFabricSectionConfig>, + new_config: AddNode, + ) -> Result<(), Error> { + this.add_node(new_config) + } + + #[export] + fn edit_fabric( + #[try_from_ref] this: &PerlSectionConfig<OpenFabricSectionConfig>, + new_config: EditFabric, + ) -> Result<(), Error> { + this.edit_fabric(new_config) + } + + #[export] + fn edit_node( + #[try_from_ref] this: &PerlSectionConfig<OpenFabricSectionConfig>, + new_config: EditNode, + ) -> Result<(), Error> { + this.edit_node(new_config) + } + + #[export] + fn delete_fabric( + #[try_from_ref] this: &PerlSectionConfig<OpenFabricSectionConfig>, + delete_config: DeleteFabric, + ) -> Result<(), Error> { + this.delete_fabric(delete_config)?; + + Ok(()) + } + + #[export] + fn delete_node( + #[try_from_ref] this: &PerlSectionConfig<OpenFabricSectionConfig>, + delete_config: DeleteNode, + ) -> Result<(), Error> { + this.delete_node(delete_config)?; + + Ok(()) + } + + #[export] + fn get_inner( + #[try_from_ref] this: &PerlSectionConfig<OpenFabricSectionConfig>, + ) -> HashMap<String, OpenFabricSectionConfig> { + let guard = this.section_config.lock().unwrap(); + guard.clone().into_iter().collect() + } + + #[export] + fn get_fabric( + #[try_from_ref] this: &PerlSectionConfig<OpenFabricSectionConfig>, + fabric: FabricId, + ) -> Result<OpenFabricSectionConfig, Error> { + let guard = this.section_config.lock().unwrap(); + guard + .get(fabric.as_ref()) + .cloned() + .ok_or(anyhow::anyhow!("fabric not found")) + } + + #[export] + fn get_node( + #[try_from_ref] this: &PerlSectionConfig<OpenFabricSectionConfig>, + fabric: FabricId, + node: Hostname, + ) -> Result<OpenFabricSectionConfig, Error> { + let guard = this.section_config.lock().unwrap(); + let nodeid = NodeId::new(fabric, node).to_string(); + guard + .get(&nodeid) + .cloned() + .ok_or(anyhow::anyhow!("node not found")) + } + + #[export] + pub fn enabled_daemons( + #[try_from_ref] this: &PerlSectionConfig<OpenFabricSectionConfig>, + host_name: Hostname, + ) -> Vec<String> { + let config = this.section_config.lock().unwrap(); + + for (_, section) in config.iter() { + if let OpenFabricSectionConfig::Node(node) = section { + if node.node_id.node == host_name { + return vec!["fabricd".to_string()]; + } + } + } + + Vec::new() + } + + #[export] + pub fn get_frr_raw_config( + #[try_from_ref] this: &PerlSectionConfig<OpenFabricSectionConfig>, + node: Hostname, + ) -> Result<Vec<String>, Error> { + let config = this.section_config.lock().unwrap(); + let openfabric_config: Valid<OpenFabricSectionConfig> = + OpenFabricSectionConfig::validate(config.clone())?; + + let config = FabricConfig::with_openfabric(openfabric_config); + let frr_config = FrrConfigBuilder::default() + .add_fabrics(config) + .build(node)?; + + to_raw_config(&frr_config) + } } -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel