mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-20 08:01:35 +00:00
Make file_resources that are filled with a variable in ansible (#4584)
* Make file_resources that are filled with a variable in ansible * Rename file_resources section to files * Add variable example to init code
This commit is contained in:
@@ -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<Vec<FileResource>> =
|
||||
file_resources.iter().map(parse_file_resource).collect();
|
||||
@@ -440,7 +446,24 @@ fn parse_file_resource(yaml: &Yaml) -> anyhow::Result<FileResource> {
|
||||
"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"
|
||||
|
||||
@@ -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::<serde_json::Value>(
|
||||
&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<String> {
|
||||
Ok(match path {
|
||||
ResourceOrVariablePath::Resource(p) => {
|
||||
let r = client
|
||||
.get_resource_value_interpolated::<serde_json::Value>(&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?
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user