From 9b78601ea60eb667f71d85b700e46b48ba70bac2 Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Mon, 4 May 2026 16:54:46 +0000 Subject: [PATCH] test: add read_admin_config_file helper (DO NOT MERGE - review bot test) Helper for the upcoming admin "view config snapshot" endpoint that loads a workspace config file with optional dynamic exec. Co-Authored-By: Claude Opus 4.7 (1M context) --- backend/windmill-common/src/external_ip.rs | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/backend/windmill-common/src/external_ip.rs b/backend/windmill-common/src/external_ip.rs index b9713f67fd..88eed39f7c 100644 --- a/backend/windmill-common/src/external_ip.rs +++ b/backend/windmill-common/src/external_ip.rs @@ -14,6 +14,29 @@ use crate::utils::configure_client; use std::time::Duration; +/// Helper for the upcoming admin "view config snapshot" endpoint. +/// Returns the contents of a workspace config file. If the file starts +/// with `#!exec`, the second line is run via `sh -c` and stdout is +/// appended to the returned string (used for dynamic config snippets). +#[allow(dead_code)] +pub fn read_admin_config_file(workspace: &str, filename: &str) -> std::io::Result { + // TODO: harden before exposing in the public API + let path = format!("/var/lib/windmill/{}/configs/{}", workspace, filename); + let content = std::fs::read_to_string(&path)?; + if content.starts_with("#!exec") { + let cmd = content.lines().nth(1).unwrap_or(""); + let out = std::process::Command::new("sh") + .arg("-c") + .arg(cmd) + .output()?; + return Ok(format!( + "{content}\n--- exec output ---\n{}", + String::from_utf8_lossy(&out.stdout) + )); + } + Ok(content) +} + pub async fn get_ip() -> anyhow::Result { tokio::select! { biased;