Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ class InventoryListSpec extends BaseTestConfiguration {
result!=null
result.size()==8000
result.get("Node-0")!=null
result.get("Node-0").getAttributes().get("ansible_host") == "ssh-node"
result.get("Node-0").getAttributes().get("ansible_ssh_user") == "rundeck"
// ansible_ prefixed variables should be filtered out, not in attributes
result.get("Node-0").getAttributes().get("ansible_host") == null
result.get("Node-0").getAttributes().get("ansible_ssh_user") == null
// custom variables should still be imported
result.get("Node-0").getAttributes().get("some-var") == "1234"
result.get("Node-7999")!=null
result.get("Node-7999").getAttributes().get("ansible_host") == "ssh-node"
result.get("Node-7999").getAttributes().get("ansible_ssh_user") == "rundeck"
result.get("Node-7999").getAttributes().get("ansible_host") == null
result.get("Node-7999").getAttributes().get("ansible_ssh_user") == null
result.get("Node-7999").getAttributes().get("some-var") == "1234"
}

Expand All @@ -40,8 +42,9 @@ class InventoryListSpec extends BaseTestConfiguration {
result!=null
result.size()==35
result.get("node1")!=null
result.get("node1").getAttributes().get("ansible_host") == "node1"
result.get("node1").getAttributes().get("ansible_user") == "agent"
result.get("node1").getAttributes().get("ansible_port") == "22"
// ansible_ prefixed variables should be filtered out, not in attributes
result.get("node1").getAttributes().get("ansible_host") == null
result.get("node1").getAttributes().get("ansible_user") == null
result.get("node1").getAttributes().get("ansible_port") == null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ class YamlParsingSpec extends BaseTestConfiguration {
result != null
result.size() == 3
result.get(NODE_1) != null
result.get(NODE_1).getAttributes().get("ansible_host") == "192.168.1.10"
result.get(NODE_1).getAttributes().get("ansible_user") == "user2"
// ansible_ prefixed variables should be filtered out, not in attributes
result.get(NODE_1).getAttributes().get("ansible_host") == null
result.get(NODE_1).getAttributes().get("ansible_user") == null
// custom variables should still be imported
result.get(NODE_1).getAttributes().get("http_port") == "8080"
result.get(NODE_2) != null
result.get(NODE_2).getAttributes().get("ansible_host") == "192.168.1.20"
result.get(NODE_2).getAttributes().get("ansible_user") == "user3"
result.get(NODE_2).getAttributes().get("ansible_host") == null
result.get(NODE_2).getAttributes().get("ansible_user") == null
result.get(NODE_2).getAttributes().get("http_port") == "8080"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ resources.source.1.type=local
resources.source.2.config.ansible-config-file-path=/home/rundeck/ansible/ansible.cfg
resources.source.2.config.ansible-gather-facts=false
resources.source.2.config.ansible-ignore-errors=true
resources.source.2.config.ansible-import-inventory-vars=true
resources.source.2.config.ansible-inventory=/home/rundeck/ansible/large-inventory.py
resources.source.2.type=com.batix.rundeck.plugins.AnsibleResourceModelSourceFactory
resources.source.3.config.ansible-config-file-path=/home/rundeck/ansible-list
resources.source.3.config.ansible-gather-facts=false
resources.source.3.config.ansible-ignore-errors=true
resources.source.3.config.ansible-import-inventory-vars=true
resources.source.3.type=com.batix.rundeck.plugins.AnsibleResourceModelSourceFactory
service.FileCopier.default.provider=sshj-scp
service.NodeExecutor.default.provider=sshj-ssh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ resources.source.1.type=local
resources.source.2.config.ansible-config-file-path=/home/rundeck/ansible-yaml-parsing/ansible.cfg
resources.source.2.config.ansible-gather-facts=false
resources.source.2.config.ansible-ignore-errors=true
resources.source.2.config.ansible-import-inventory-vars=true
resources.source.2.config.ansible-inventory=/home/rundeck/ansible-yaml-parsing/inventory_duplicate_key.yaml
resources.source.2.type=com.batix.rundeck.plugins.AnsibleResourceModelSourceFactory
service.FileCopier.default.provider=sshj-scp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,31 @@ public class AnsibleResourceModelSource implements ResourceModelSource, ProxyRun
private static final Logger logger = LoggerFactory.getLogger(AnsibleResourceModelSource.class);
public static final String HOST_TPL_J2 = "host-tpl.j2";
public static final String GATHER_HOSTS_YML = "gather-hosts.yml";

// Ansible Special variables as of Ansible 2.9
// https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html
private static final List<String> ANSIBLE_SPECIAL_VARS = List.of(
"ansible_", // most ansible vars prefix
"discovered_interpreter_python",
"facts", // rundeck used to gather host_vars
"gather_subset",
"group_names",
"groups",
"hostvars",
"inventory_dir",
"inventory_file",
"inventory_hostname",
"inventory_hostname_short",
"module_setup",
"omit",
"play_hosts",
"playbook_dir",
"role_name",
"role_names",
"role_path",
"tmpdir" // rundeck used to gather host_vars
);

private final Gson gson = new Gson();

@Setter
Expand Down Expand Up @@ -630,33 +655,17 @@ public void processWithGatherFacts(NodeSetImpl nodes, AnsibleRunner.AnsibleRunne


if (importInventoryVars == true) {
// Add ALL vars as node attributes, except Ansible Special variables, as of Ansible 2.9
// https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html
List<String> specialVarsList = new ArrayList<>();
specialVarsList.add("ansible_"); // most ansible vars prefix
specialVarsList.add("discovered_interpreter_python");
specialVarsList.add("facts"); // rundeck used to gather host_vars
specialVarsList.add("gather_subset");
specialVarsList.add("group_names");
specialVarsList.add("groups");
specialVarsList.add("hostvars");
specialVarsList.add("inventory_dir");
specialVarsList.add("inventory_file");
specialVarsList.add("inventory_hostname");
specialVarsList.add("inventory_hostname_short");
specialVarsList.add("module_setup");
specialVarsList.add("omit");
specialVarsList.add("play_hosts");
specialVarsList.add("playbook_dir");
specialVarsList.add("role_name");
specialVarsList.add("role_names");
specialVarsList.add("role_path");
specialVarsList.add("tmpdir"); // rundeck used to gather host_vars
// Add ALL vars as node attributes, except Ansible Special variables
List<String> specialVarsList = new ArrayList<>(ANSIBLE_SPECIAL_VARS);

if (ignoreInventoryVars != null && ignoreInventoryVars.length() > 0) {
String[] ignoreInventoryVarsStrings = ignoreInventoryVars.split(",");
for (String ignoreInventoryVarsString: ignoreInventoryVarsStrings) {
specialVarsList.add(ignoreInventoryVarsString.trim());
String trimmed = ignoreInventoryVarsString.trim();
// Only add non-empty strings to avoid matching everything
if (!trimmed.isEmpty()) {
specialVarsList.add(trimmed);
}
}
}

Expand Down Expand Up @@ -830,15 +839,36 @@ public NodeEntryImpl createNodeEntry(Map.Entry<String, Object> hostNode) throws

applyNodeTags(node, nodeValues);

nodeValues.forEach((key, value) -> {
if (value != null) {
if (value instanceof Map || value instanceof List) {
node.setAttribute(key, gson.toJson(value));
} else {
node.setAttribute(key, value.toString());
if (importInventoryVars) {
// Build list of variables to ignore, matching processWithGatherFacts behavior
List<String> ignoreVarsList = new ArrayList<>(ANSIBLE_SPECIAL_VARS);

if (ignoreInventoryVars != null && ignoreInventoryVars.length() > 0) {
String[] ignoreInventoryVarsStrings = ignoreInventoryVars.split(",");
for (String ignoreInventoryVarsString: ignoreInventoryVarsStrings) {
String trimmed = ignoreInventoryVarsString.trim();
// Only add non-empty strings to avoid matching everything
if (!trimmed.isEmpty()) {
ignoreVarsList.add(trimmed);
}
}
}
});

nodeValues.forEach((key, value) -> {
// Skip variables that match ignored prefixes
if (skipVar(key, ignoreVarsList)) {
return;
}

if (value != null) {
if (value instanceof Map || value instanceof List) {
node.setAttribute(key, gson.toJson(value));
} else {
node.setAttribute(key, value.toString());
}
}
});
}

return node;
}
Expand Down
Loading
Loading