Skip to content

[Feature Request] Allow customization of whitelisted facts for import #409

@kamakazikamikaze

Description

@kamakazikamikaze

A static listing of "interesting items" is defined inside the plugin for variables to retain, as well as a static listing of variables to exclude. Any fact with ansible_ prepended is skipped over if it is not explicitly listed in the "interesting items."

Map<String, String> interestingItems = new HashMap<>();
interestingItems.put("ansible_form_factor", "form_factor");
interestingItems.put("ansible_system_vendor", "system_vendor");
interestingItems.put("ansible_product_name", "product_name");
interestingItems.put("ansible_product_version", "product_version");
interestingItems.put("ansible_product_serial", "product_serial");
interestingItems.put("ansible_bios_version", "bios_version");
interestingItems.put("ansible_bios_date", "bios_date");
interestingItems.put("ansible_machine_id", "machine_id");
interestingItems.put("ansible_virtualization_type", "virtualization_type");
interestingItems.put("ansible_virtualization_role", "virtualization_role");
interestingItems.put("ansible_selinux", "selinux");
interestingItems.put("ansible_fips", "fips");
interestingItems.put("ansible_service_mgr", "service_mgr");
interestingItems.put("ansible_pkg_mgr", "pkg_mgr");
interestingItems.put("ansible_distribution", "distribution");
interestingItems.put("ansible_distribution_version", "distribution_version");
interestingItems.put("ansible_distribution_major_version", "distribution_major_version");
interestingItems.put("ansible_distribution_release", "distribution_release");
interestingItems.put("ansible_lsb.codename", "lsb_codename");
interestingItems.put("ansible_domain", "domain");
interestingItems.put("ansible_date_time.tz", "tz");
interestingItems.put("ansible_date_time.tz_offset", "tz_offset");
interestingItems.put("ansible_processor_count", "processor_count");
interestingItems.put("ansible_processor_cores", "processor_cores");
interestingItems.put("ansible_processor_vcpus", "processor_vcpus");
interestingItems.put("ansible_processor_threads_per_core", "processor_threads_per_core");
interestingItems.put("ansible_userspace_architecture", "userspace_architecture");
interestingItems.put("ansible_userspace_bits", "userspace_bits");
interestingItems.put("ansible_memtotal_mb", "memtotal_mb");
interestingItems.put("ansible_swaptotal_mb", "swaptotal_mb");
interestingItems.put("ansible_processor.0", "processor0");
interestingItems.put("ansible_processor.1", "processor1");
for (Map.Entry<String, String> item : interestingItems.entrySet()) {
String[] itemParts = item.getKey().split("\\.");
if (itemParts.length > 1) {
JsonElement ele = root;
for (String itemPart : itemParts) {
if (ele.isJsonArray() && itemPart.matches("^\\d+$") && ele.getAsJsonArray().size() > Integer.parseInt(itemPart)) {
ele = ele.getAsJsonArray().get(Integer.parseInt(itemPart));
} else if (ele.isJsonObject() && ele.getAsJsonObject().has(itemPart)) {
ele = ele.getAsJsonObject().get(itemPart);
} else {
ele = null;
break;
}
}
if (ele != null && ele.isJsonPrimitive() && ele.getAsString().length() > 0) {
node.setAttribute(item.getValue(), ele.getAsString());
}
} else {
if (root.has(item.getKey())
&& root.get(item.getKey()).isJsonPrimitive()
&& root.get(item.getKey()).getAsString().length() > 0) {
node.setAttribute(item.getValue(), root.get(item.getKey()).getAsString());
}
}
}
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

Some skipped facts may be desired by the user. For example, Cisco equipment will return facts regarding serial number (ansible_net_serialnum), image name (ansible_net_image), and image version (ansible_net_version).

The plugin should extend the configuration to include a user-definable whitelist of facts with the option to define a name reassignment. For example, the field can be a semicolon-delimited string where each result is further split on commas. Given the following input:

ansible_net_version,version;ansible_net_serialnum,serialnum;ansible_net_model;ansible_system,osFamily

The following behavior would result:

Ansible Fact Name Node Attribute Name
ansible_net_version version
ansible_net_serialnum serialnum
ansible_net_model ansible_net_model
ansible_system osFamily

Implementation may be done similar to how the variable blacklist is implemented on line 652.

if (ignoreInventoryVars != null && ignoreInventoryVars.length() > 0) {
String[] ignoreInventoryVarsStrings = ignoreInventoryVars.split(",");
for (String ignoreInventoryVarsString: ignoreInventoryVarsStrings) {
specialVarsList.add(ignoreInventoryVarsString.trim());
}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions