diff --git a/changelogs/fragments/advanced-host-list-ref-before-assignment.yml b/changelogs/fragments/advanced-host-list-ref-before-assignment.yml new file mode 100644 index 00000000000..b4a442d67fe --- /dev/null +++ b/changelogs/fragments/advanced-host-list-ref-before-assignment.yml @@ -0,0 +1,2 @@ +bugfixes: + - advanced_host_list inventory plugin - Fixed variable referenced before assignment when hostname/range could not be parsed. diff --git a/lib/ansible/plugins/inventory/advanced_host_list.py b/lib/ansible/plugins/inventory/advanced_host_list.py index c61a4656cb4..1b5d8684b8e 100644 --- a/lib/ansible/plugins/inventory/advanced_host_list.py +++ b/lib/ansible/plugins/inventory/advanced_host_list.py @@ -53,7 +53,7 @@ class InventoryModule(BaseInventoryPlugin): (hostnames, port) = self._expand_hostpattern(h) except AnsibleError as e: self.display.vvv("Unable to parse address from hostname, leaving unchanged: %s" % to_text(e)) - host = [h] + hostnames = [h] port = None for host in hostnames: diff --git a/test/integration/targets/inventory_advanced_host_list/aliases b/test/integration/targets/inventory_advanced_host_list/aliases new file mode 100644 index 00000000000..a6dafcf8cd8 --- /dev/null +++ b/test/integration/targets/inventory_advanced_host_list/aliases @@ -0,0 +1 @@ +shippable/posix/group1 diff --git a/test/integration/targets/inventory_advanced_host_list/runme.sh b/test/integration/targets/inventory_advanced_host_list/runme.sh new file mode 100755 index 00000000000..41b1f8b9530 --- /dev/null +++ b/test/integration/targets/inventory_advanced_host_list/runme.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +set -eux + +export ANSIBLE_INVENTORY_ENABLED=advanced_host_list + +# A few things to make it easier to grep against adhoc +export ANSIBLE_LOAD_CALLBACK_PLUGINS=True +export ANSIBLE_STDOUT_CALLBACK=oneline + +adhoc="$(ansible -i 'local[0:10],' -m ping --connection=local -e ansible_python_interpreter="{{ ansible_playbook_python }}" all -v)" + +for i in $(seq 0 10); do + grep -qE "local${i} \| SUCCESS.*\"ping\": \"pong\"" <<< "$adhoc" +done + +set +e +parse_fail="$(ansible -i 'local[1:j],' -m ping --connection=local all -v 2>&1)" +set -e + +grep -q "Failed to parse local\[1:j\], with advanced_host_list" <<< "$parse_fail" + +# Intentionally missing comma, ensure we don't fatal. +no_comma="$(ansible -i 'local[1:5]' -m ping --connection=local all -v 2>&1)" +grep -q "No inventory was parsed" <<< "$no_comma" + +# Intentionally botched range (missing end number), ensure we don't fatal. +no_end="$(ansible -i 'local[1:],' -m ping --connection=local -e ansible_python_interpreter="{{ ansible_playbook_python }}" all -vvv 2>&1)" +grep -q "Unable to parse address from hostname, leaving unchanged:" <<< "$no_end" +grep -q "host range must specify end value" <<< "$no_end" +grep -q "local\[3:\] \| SUCCESS" <<< "$no_end" + +# Unset adhoc stuff +unset ANSIBLE_LOAD_CALLBACK_PLUGINS ANSIBLE_STDOUT_CALLBACK + +ansible-playbook -i 'local100,local[100:110:2]' test_advanced_host_list.yml -v "$@" diff --git a/test/integration/targets/inventory_advanced_host_list/test_advanced_host_list.yml b/test/integration/targets/inventory_advanced_host_list/test_advanced_host_list.yml new file mode 100644 index 00000000000..918078aecdb --- /dev/null +++ b/test/integration/targets/inventory_advanced_host_list/test_advanced_host_list.yml @@ -0,0 +1,9 @@ +- hosts: all + connection: local + vars: + ansible_python_interpreter: "{{ ansible_playbook_python }}" + tasks: + - assert: + that: + - inventory_hostname in ["local100", "local102", "local104", "local106", "local108", "local110", "local118"] + - inventory_hostname not in ["local101", "local103", "local105", "local107", "local109", "local111"]