Skip to content

Commit

Permalink
Merge pull request #405 from rundeck-plugins/RPL-69-unable-to-modify-…
Browse files Browse the repository at this point in the history
…ansible-tmp-dir-path

RPL-69 Enable custom tmp on ansible
  • Loading branch information
Jesus-Osuna-M authored Dec 6, 2024
2 parents 2fb4c34 + 289211d commit 3a85dfa
Show file tree
Hide file tree
Showing 19 changed files with 150 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.dtolabs.rundeck.core.common.INodeEntry;
import com.dtolabs.rundeck.core.plugins.configuration.ConfigurationException;
import com.rundeck.plugins.ansible.util.AnsibleUtil;

import java.io.File;
import java.io.PrintWriter;
Expand All @@ -11,14 +12,16 @@
public class AnsibleInlineInventoryBuilder {

private final String inline_inventory;
private final String customTmpDirPath;

public AnsibleInlineInventoryBuilder(String inline_inventory) {
public AnsibleInlineInventoryBuilder(String inline_inventory,String customTmpDirPath) {
this.inline_inventory = inline_inventory;
this.customTmpDirPath = customTmpDirPath;
}

public File buildInventory() throws ConfigurationException {
try {
File file = File.createTempFile("ansible-inventory", ".inventory");
File file = AnsibleUtil.createTemporaryFile("ansible-inventory", ".inventory","",customTmpDirPath);
file.deleteOnExit();
PrintWriter writer = new PrintWriter(file);
writer.write(inline_inventory);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,21 @@
import java.util.HashMap;

import com.google.gson.Gson;
import com.rundeck.plugins.ansible.util.AnsibleUtil;

public class AnsibleInventoryBuilder {

private final Collection<INodeEntry> nodes;
private final String customTmpDirPath;

public AnsibleInventoryBuilder(Collection<INodeEntry> nodes) {
public AnsibleInventoryBuilder(Collection<INodeEntry> nodes, String customTmpDirPath ) {
this.nodes = nodes;
this.customTmpDirPath = customTmpDirPath;
}

public File buildInventory() throws ConfigurationException {
try {
File file = File.createTempFile("ansible-inventory", ".json");
File file = AnsibleUtil.createTemporaryFile("ansible-inventory", ".json","",customTmpDirPath);
file.deleteOnExit();
PrintWriter writer = new PrintWriter(file);
AnsibleInventory ai = new AnsibleInventory();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class AnsibleInventoryList {
private File tempVaultFile;
private File vaultPromptFile;
private File tempLimitFile;
private String customTmpDirPath;

public static final String ANSIBLE_INVENTORY_COMMAND = "ansible-inventory";

Expand Down Expand Up @@ -139,7 +140,7 @@ private void processAnsibleVault(List<VaultPrompt> stdinVariables, List<String>
if (vaultPrompt == null) { return; }

if(ansibleVault == null){
tempInternalVaultFile = AnsibleVault.createVaultScriptAuth("ansible-script-vault");
tempInternalVaultFile = AnsibleVault.createVaultScriptAuth("ansible-script-vault",customTmpDirPath);
ansibleVault = AnsibleVault.builder()
.masterPassword(vaultPrompt.getVaultPassword())
.vaultPasswordScriptFile(tempInternalVaultFile)
Expand All @@ -165,7 +166,7 @@ private void processLimit(List<String> procArgs) throws IOException {
for (String limit : limits) {
sb.append(limit).append("\n");
}
tempLimitFile = AnsibleUtil.createTemporaryFile("targets", sb.toString());
tempLimitFile = AnsibleUtil.createTemporaryFile("","targets", sb.toString(),customTmpDirPath);

procArgs.add("-l");
procArgs.add("@" + tempLimitFile.getAbsolutePath());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,8 @@ public static AnsibleRunner buildAnsibleRunner(AnsibleRunnerContextBuilder conte
File tempBecameVarsFile ;
File vaultPromptFile;

String customTmpDirPath;

public void deleteTempDirectory(Path tempDirectory) throws IOException {
Files.walkFileTree(tempDirectory, new SimpleFileVisitor<Path>() {
@Override
Expand Down Expand Up @@ -333,11 +335,11 @@ public int run() throws Exception {
if (baseDirectory == null) {
// Use a temporary directory and mark it for possible removal later
this.usingTempDirectory = true;
baseDirectory = Files.createTempDirectory("ansible-rundeck");
baseDirectory = Files.createTempDirectory(Path.of(customTmpDirPath),"ansible-rundeck");
}

if(ansibleVault==null){
tempInternalVaultFile = AnsibleVault.createVaultScriptAuth("ansible-script-vault");
tempInternalVaultFile = AnsibleVault.createVaultScriptAuth("ansible-script-vault",customTmpDirPath);
ansibleVault = AnsibleVault.builder()
.baseDirectory(baseDirectory)
.masterPassword(AnsibleUtil.randomString())
Expand Down Expand Up @@ -373,7 +375,7 @@ public int run() throws Exception {
} else if (type == AnsibleCommand.PlaybookPath) {
procArgs.add(playbook);
} else if (type == AnsibleCommand.PlaybookInline) {
tempPlaybook = AnsibleUtil.createTemporaryFile("playbook", playbook);
tempPlaybook = AnsibleUtil.createTemporaryFile("","playbook", playbook,customTmpDirPath);
procArgs.add(tempPlaybook.getAbsolutePath());
}

Expand Down Expand Up @@ -405,7 +407,7 @@ public int run() throws Exception {
for (String limit : limits) {
sb.append(limit).append("\n");
}
tempFile = AnsibleUtil.createTemporaryFile("targets", sb.toString());
tempFile = AnsibleUtil.createTemporaryFile("","targets", sb.toString(),customTmpDirPath);

procArgs.add("-l");
procArgs.add("@" + tempFile.getAbsolutePath());
Expand All @@ -422,13 +424,13 @@ public int run() throws Exception {
addeExtraVars = encryptExtraVarsKey(extraVars);
}

tempVarsFile = AnsibleUtil.createTemporaryFile("extra-vars", addeExtraVars);
tempVarsFile = AnsibleUtil.createTemporaryFile("","extra-vars", addeExtraVars,customTmpDirPath);
procArgs.add("--extra-vars" + "=" + "@" + tempVarsFile.getAbsolutePath());
}

if (sshPrivateKey != null && !sshPrivateKey.isEmpty()) {
String privateKeyData = sshPrivateKey.replaceAll("\r\n", "\n");
tempPkFile = AnsibleUtil.createTemporaryFile("id_rsa", privateKeyData);
tempPkFile = AnsibleUtil.createTemporaryFile("","id_rsa", privateKeyData,customTmpDirPath);

// Only the owner can read and write
Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
Expand All @@ -454,7 +456,7 @@ public int run() throws Exception {
finalextraVarsPassword = encryptExtraVarsKey(extraVarsPassword);
}

tempSshVarsFile = AnsibleUtil.createTemporaryFile("ssh-extra-vars", finalextraVarsPassword);
tempSshVarsFile = AnsibleUtil.createTemporaryFile("","ssh-extra-vars", finalextraVarsPassword,customTmpDirPath);
procArgs.add("--extra-vars" + "=" + "@" + tempSshVarsFile.getAbsolutePath());
}

Expand All @@ -473,7 +475,7 @@ public int run() throws Exception {
finalextraVarsPassword = encryptExtraVarsKey(extraVarsPassword);
}

tempBecameVarsFile = AnsibleUtil.createTemporaryFile("become-extra-vars", finalextraVarsPassword);
tempBecameVarsFile = AnsibleUtil.createTemporaryFile("","become-extra-vars", finalextraVarsPassword,customTmpDirPath);
procArgs.add("--extra-vars" + "=" + "@" + tempBecameVarsFile.getAbsolutePath());
}
}
Expand Down Expand Up @@ -531,7 +533,7 @@ public int run() throws Exception {
List<VaultPrompt> stdinVariables = new ArrayList<>();

if(useAnsibleVault || vaultPass != null ){
vaultPromptFile = File.createTempFile("vault-prompt", ".log");
vaultPromptFile = AnsibleUtil.createTemporaryFile("vault-prompt",".log","",customTmpDirPath);
}

if (useAnsibleVault) {
Expand Down Expand Up @@ -677,7 +679,7 @@ public boolean registerKeySshAgent(String keyPath) throws Exception {

File tempPassVarsFile = null;
if (sshPassphrase != null && sshPassphrase.length() > 0) {
tempPassVarsFile = File.createTempFile("ansible-runner", "ssh-add-check");
tempPassVarsFile = AnsibleUtil.createTemporaryFile("","ssh-add-check","",customTmpDirPath);
tempPassVarsFile.setExecutable(true);

List<String> passScript = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.nio.file.Paths;

import com.rundeck.plugins.ansible.plugin.AnsiblePluginGroup;
import com.rundeck.plugins.ansible.util.AnsibleUtil;
import lombok.Getter;
import org.rundeck.storage.api.Path;

Expand Down Expand Up @@ -605,7 +606,7 @@ public String getInventory() throws ConfigurationException {


if (isGenerated != null && isGenerated) {
File tempInventory = new AnsibleInventoryBuilder(this.nodes).buildInventory();
File tempInventory = new AnsibleInventoryBuilder(this.nodes, AnsibleUtil.getCustomTmpPathDir(framework)).buildInventory();
tempFiles.add(tempInventory);
inventory = tempInventory.getAbsolutePath();
return inventory;
Expand All @@ -625,7 +626,7 @@ public String getInventory() throws ConfigurationException {
the builder gets the nodes from rundeck in rundeck node format and converts to ansible inventory
we don't want that, we simply want the list we provided in ansible format
*/
File tempInventory = new AnsibleInlineInventoryBuilder(inline_inventory).buildInventory();
File tempInventory = new AnsibleInlineInventoryBuilder(inline_inventory,AnsibleUtil.getCustomTmpPathDir(framework)).buildInventory();
tempFiles.add(tempInventory);
inventory = tempInventory.getAbsolutePath();
return inventory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ public String encryptVariable(String key,
}


public static File createVaultScriptAuth(String suffix) throws IOException {
File tempInternalVaultFile = File.createTempFile("ansible-runner", suffix + "-client.py");
public static File createVaultScriptAuth(String suffix, String path) throws IOException {
File tempInternalVaultFile = AnsibleUtil.createTemporaryFile("ansible-runner", suffix + "-client.py","",path);

try {
Files.copy(AnsibleUtil.class.getClassLoader().getResourceAsStream("vault-client.py"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ private String doFileCopy(

try {
runner = AnsibleRunner.buildAnsibleRunner(contextBuilder);
runner.setCustomTmpDirPath(AnsibleUtil.getCustomTmpPathDir(contextBuilder.getFramework()));
} catch (ConfigurationException e) {
throw new FileCopierException("Error configuring Ansible.",AnsibleFailureReason.ParseArgumentsError, e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public void executeStep(PluginStepContext context, Map<String, Object> configura

try {
runner = AnsibleRunner.buildAnsibleRunner(contextBuilder);
runner.setCustomTmpDirPath(AnsibleUtil.getCustomTmpPathDir(contextBuilder.getFramework()));
} catch (ConfigurationException e) {
throw new StepException("Error configuring Ansible runner: " + e.getMessage(), e, AnsibleException.AnsibleFailureReason.ParseArgumentsError);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ public NodeExecutorResult executeCommand(ExecutionContext context, String[] comm

try {
runner = AnsibleRunner.buildAnsibleRunner(contextBuilder);
runner.setCustomTmpDirPath(AnsibleUtil.getCustomTmpPathDir(contextBuilder.getFramework()));
} catch (ConfigurationException e) {
return NodeExecutorResultImpl.createFailure(AnsibleException.AnsibleFailureReason.ParseArgumentsError, e.getMessage(), node);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public void executeNodeStep(

try {
runner = AnsibleRunner.buildAnsibleRunner(contextBuilder);
runner.setCustomTmpDirPath(AnsibleUtil.getCustomTmpPathDir(contextBuilder.getFramework()));
} catch (ConfigurationException e) {
throw new NodeStepException("Error configuring Ansible runner: "+e.getMessage(), AnsibleException.AnsibleFailureReason.ParseArgumentsError,e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public void executeStep(PluginStepContext context, Map<String, Object> configura

try {
runner = AnsibleRunner.buildAnsibleRunner(contextBuilder);
runner.setCustomTmpDirPath(AnsibleUtil.getCustomTmpPathDir(contextBuilder.getFramework()));
} catch (ConfigurationException e) {
throw new StepException("Error configuring Ansible runner: " + e.getMessage(), e, AnsibleException.AnsibleFailureReason.ParseArgumentsError);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public void executeNodeStep(

try {
runner = AnsibleRunner.buildAnsibleRunner(contextBuilder);
runner.setCustomTmpDirPath(AnsibleUtil.getCustomTmpPathDir(contextBuilder.getFramework()));
} catch (ConfigurationException e) {
throw new NodeStepException("Error configuring Ansible runner: "+e.getMessage(), AnsibleException.AnsibleFailureReason.ParseArgumentsError,e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public void executeStep(PluginStepContext context, Map<String, Object> configura

try {
runner = AnsibleRunner.buildAnsibleRunner(contextBuilder);
runner.setCustomTmpDirPath(AnsibleUtil.getCustomTmpPathDir(contextBuilder.getFramework()));
} catch (ConfigurationException e) {
throw new StepException("Error configuring Ansible runner: " + e.getMessage(), e, AnsibleException.AnsibleFailureReason.ParseArgumentsError);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.rundeck.plugins.ansible.ansible.AnsibleInventoryList;
import com.rundeck.plugins.ansible.ansible.AnsibleRunner;
import com.rundeck.plugins.ansible.ansible.InventoryList;
import com.rundeck.plugins.ansible.util.AnsibleUtil;
import com.rundeck.plugins.ansible.util.VaultPrompt;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -132,6 +133,8 @@ public class AnsibleResourceModelSource implements ResourceModelSource, ProxyRun

protected boolean encryptExtraVars = false;

protected String customTmpDirPath;

@Setter
private AnsibleInventoryList.AnsibleInventoryListBuilder ansibleInventoryListBuilder = null;

Expand Down Expand Up @@ -189,7 +192,7 @@ public void configure(Properties configuration) throws ConfigurationException {
configDataContext.put("context", configdata);
executionDataContext = ScriptDataContextUtil.createScriptDataContextForProject(framework, project);
executionDataContext.putAll(configDataContext);

customTmpDirPath = AnsibleUtil.getCustomTmpPathDir(framework);
inventory = resolveProperty(AnsibleDescribable.ANSIBLE_INVENTORY,null,configuration,executionDataContext);
gatherFacts = "true".equals(resolveProperty(AnsibleDescribable.ANSIBLE_GATHER_FACTS,null,configuration,executionDataContext));
ignoreErrors = "true".equals(resolveProperty(AnsibleDescribable.ANSIBLE_IGNORE_ERRORS,null,configuration,executionDataContext));
Expand Down Expand Up @@ -260,6 +263,7 @@ public AnsibleRunner.AnsibleRunnerBuilder buildAnsibleRunner() throws ResourceMo
if ("true".equals(System.getProperty("ansible.debug"))) {
runnerBuilder.debug(true);
}
runnerBuilder.customTmpDirPath(AnsibleUtil.getCustomTmpPathDir(framework));

if (limit != null && limit.length() > 0) {
List<String> limitList = new ArrayList<>();
Expand Down Expand Up @@ -420,7 +424,7 @@ public void processWithGatherFacts(NodeSetImpl nodes, AnsibleRunner.AnsibleRunne
final Gson gson = new Gson();
Path tempDirectory;
try {
tempDirectory = Files.createTempDirectory("ansible-hosts");
tempDirectory = Files.createTempDirectory(Path.of(customTmpDirPath),"ansible-hosts");
} catch (IOException e) {
throw new ResourceModelSourceException("Error creating temporary directory: " + e.getMessage(), e);
}
Expand All @@ -431,7 +435,7 @@ public void processWithGatherFacts(NodeSetImpl nodes, AnsibleRunner.AnsibleRunne
} catch (IOException e) {
throw new ResourceModelSourceException("Error copying files: " + e.getMessage(), e);
}

runnerBuilder.customTmpDirPath(customTmpDirPath);
runnerBuilder.tempDirectory(tempDirectory);
runnerBuilder.retainTempDirectory(true);

Expand Down Expand Up @@ -881,7 +885,7 @@ public String getNodesFromInventory(AnsibleRunner.AnsibleRunnerBuilder runnerBui
}

AnsibleInventoryList inventoryList = this.ansibleInventoryListBuilder.build();

inventoryList.setCustomTmpDirPath(customTmpDirPath);
try {
return inventoryList.getNodeList();
} catch (IOException | AnsibleException e) {
Expand Down
20 changes: 16 additions & 4 deletions src/main/groovy/com/rundeck/plugins/ansible/util/AnsibleUtil.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.rundeck.plugins.ansible.util;

import com.dtolabs.rundeck.core.common.Framework;
import com.dtolabs.rundeck.core.execution.ExecutionContext;
import com.dtolabs.rundeck.core.execution.proxy.DefaultSecretBundle;
import com.dtolabs.rundeck.core.execution.proxy.SecretBundle;
import com.dtolabs.rundeck.core.execution.workflow.steps.PluginStepContextImpl;
import com.dtolabs.rundeck.core.plugins.configuration.Property;
import com.dtolabs.rundeck.core.utils.PropertyLookup;
import com.dtolabs.rundeck.plugins.step.PluginStepContext;
import com.rundeck.plugins.ansible.ansible.AnsibleDescribable;
import com.rundeck.plugins.ansible.ansible.AnsibleRunnerContextBuilder;
import com.rundeck.plugins.ansible.plugin.AnsibleNodeExecutor;
Expand Down Expand Up @@ -103,19 +107,27 @@ public static Map<String, String> getRuntimeProperties(ExecutionContext context,
return filterProperties;
}


public static File createTemporaryFile(String suffix, String data) throws IOException {
File tempVarsFile = File.createTempFile("ansible-runner", suffix);
public static File createTemporaryFile(String prefix, String suffix, String data, String path) throws IOException {
if(prefix.isEmpty()){
prefix ="ansible-runner";
}
File tempVarsFile = File.createTempFile(prefix, suffix, new File(path));
Files.write(tempVarsFile.toPath(), data.getBytes());
return tempVarsFile;
}


public static String randomString(){
byte[] bytes = new byte[32];
new SecureRandom().nextBytes(bytes);
return Base64.getEncoder().encodeToString(bytes);
}

public static String getCustomTmpPathDir(Framework framework){
String customTmpDir = framework.getPropertyLookup().getProperty("framework.tmp.dir");
if (customTmpDir == null || customTmpDir.isEmpty()) {
customTmpDir = System.getProperty("java.io.tmpdir");
}
return customTmpDir;
}


Expand Down
Loading

0 comments on commit 3a85dfa

Please sign in to comment.