diff --git a/backend/parsers/windmill-parser-yaml/src/lib.rs b/backend/parsers/windmill-parser-yaml/src/lib.rs index f008f2f34a..8c29c97b7e 100644 --- a/backend/parsers/windmill-parser-yaml/src/lib.rs +++ b/backend/parsers/windmill-parser-yaml/src/lib.rs @@ -188,9 +188,15 @@ pub struct AnsiblePlaybookOptions { pub force_handlers: Option<()>, } +#[derive(Debug, Clone)] +pub enum ResourceOrVariablePath { + Resource(String), + Variable(String), +} + #[derive(Debug, Clone)] pub struct FileResource { - pub resource_path: String, + pub resource_path: ResourceOrVariablePath, pub target_path: String, } @@ -309,7 +315,7 @@ pub fn parse_ansible_reqs( } } } - Yaml::String(key) if key == "file_resources" => { + Yaml::String(key) if key == "files" || key == "file_resources" => { if let Yaml::Array(file_resources) = value { let resources: anyhow::Result> = file_resources.iter().map(parse_file_resource).collect(); @@ -440,7 +446,24 @@ fn parse_file_resource(yaml: &Yaml) -> anyhow::Result { "No `target` provided for file resource {}. Please input a target relative path for the ansible playbook to see this file.", resource_path ))?; - return Ok(FileResource { resource_path: resource_path.clone(), target_path }); + return Ok(FileResource { + resource_path: ResourceOrVariablePath::Resource(resource_path.clone()), + target_path, + }); + } + if let Some(Yaml::String(resource_path)) = f.get(&Yaml::String("variable".to_string())) { + let target_path = f + .get(&Yaml::String("target".to_string())) + .and_then(|x| x.as_str()) + .map(|x| x.to_string()) + .ok_or(anyhow!( + "No `target` provided for file resource {}. Please input a target relative path for the ansible playbook to see this file.", + resource_path + ))?; + return Ok(FileResource { + resource_path: ResourceOrVariablePath::Variable(resource_path.clone()), + target_path, + }); } return Err(anyhow!( "File resource should have a `resource` field, linking to a text file resource" diff --git a/backend/windmill-worker/src/ansible_executor.rs b/backend/windmill-worker/src/ansible_executor.rs index ef18ddba13..e897b86321 100644 --- a/backend/windmill-worker/src/ansible_executor.rs +++ b/backend/windmill-worker/src/ansible_executor.rs @@ -23,7 +23,7 @@ use windmill_common::{ jobs::QueuedJob, worker::{to_raw_value, write_file, write_file_at_user_defined_location, WORKER_CONFIG}, }; -use windmill_parser_yaml::AnsibleRequirements; +use windmill_parser_yaml::{AnsibleRequirements, ResourceOrVariablePath}; use windmill_queue::{append_logs, CanceledBy}; use crate::{ @@ -556,20 +556,17 @@ async fn create_file_resources( } for file_res in &r.file_resources { - let r = client - .get_resource_value_interpolated::( - &file_res.resource_path, - Some(job_id.to_string()), - ) - .await?; + let r = get_resource_or_variable_content( + client, + &file_res.resource_path, + job_id.to_string(), + ) + .await?; let path = file_res.target_path.clone(); let validated_path = write_file_at_user_defined_location( job_dir, path.as_str(), - r.get("content").and_then(|v| v.as_str()).ok_or(anyhow!( - "Invalid text file resource {}, `content` field absent or invalid", - &file_res.resource_path - ))?, + &r, ) .map_err(|e| anyhow!("Couldn't write text file at {}: {}", path, e))?; @@ -579,7 +576,7 @@ async fn create_file_resources( ); logs.push_str(&format!( - "\nCreated {} from {}", + "\nCreated {} from {:?}", file_res.target_path, file_res.resource_path )); } @@ -587,3 +584,25 @@ async fn create_file_resources( Ok(nsjail_mounts) } + +async fn get_resource_or_variable_content( + client: &crate::AuthedClient, + path: &ResourceOrVariablePath, + job_id: String, +) -> anyhow::Result { + Ok(match path { + ResourceOrVariablePath::Resource(p) => { + let r = client + .get_resource_value_interpolated::(&p, Some(job_id)) + .await?; + + r.get("content").and_then(|v| v.as_str()).ok_or(anyhow!( + "Invalid text file resource {}, `content` field absent or invalid", + p + ))?.to_string() + } + ResourceOrVariablePath::Variable(p) => { + client.get_variable_value(&p).await? + } + }) +} diff --git a/frontend/src/lib/script_helpers.ts b/frontend/src/lib/script_helpers.ts index f584ee9f19..a4bd376c34 100644 --- a/frontend/src/lib/script_helpers.ts +++ b/frontend/src/lib/script_helpers.ts @@ -635,9 +635,11 @@ inventory: # File resources will be written in the relative \`target\` location before # running the playbook -# file_resources: +# files: # - resource: u/user/fabulous_jinja_template # target: ./config_template.j2 + # - variable: u/user/ssh_key + # target: ./ssh_key # Define the arguments of the windmill script extra_vars: