Repository: ansible/ansible

Issue:
Weird error on group_vars syntax fault
<!---
Please do not report issues/requests related to Ansible modules here !!

Report them to the appropriate modules-core or modules-extras project:
  - https://github.com/ansible/ansible-modules-core/issues
  - https://github.com/ansible/ansible-modules-extras/issues

Also verify first that your issue/request is not already reported in GitHub
-->


##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report

##### COMPONENT NAME
<!--- Name of the plugin/task/feature -->
load_inventory_file

##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
v2.2

##### CONFIGURATION
<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->
*hosts*
```ini
[test]
localhost
```

The below syntax error is on purpose (INI syntax instead of YAML syntax).
*group_vars/test*
```yaml
ansible_python_interpreter=/foo/bar
```

##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say “N/A” for anything that is not platform-specific.
-->
Any

##### SUMMARY
<!--- Explain the problem briefly -->
Ansible returns a weird error when group_vars files have a syntax error (like the example above).

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem.
For new features, show how the feature would be used.
-->

<!--- Paste example playbooks or commands between quotes below -->

Use the above configuration files to run an ansible command.
```
[dag@moria ansible.testing]$ ansible localhost -m setup -vvv
Using /home/dag/home-made/ansible.testing/ansible.cfg as config file
ERROR! Unexpected Exception: dictionary update sequence element #0 has length 1; 2 is required
the full traceback was:

Traceback (most recent call last):
  File "/opt/ansible/default/bin/ansible", line 103, in <module>
    exit_code = cli.run()
  File "/opt/ansible/ansible-2.2.0.0/lib/ansible/cli/adhoc.py", line 131, in run
    inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=self.options.inventory)
  File "/opt/ansible/ansible-2.2.0.0/lib/ansible/inventory/__init__.py", line 97, in __init__
    self.parse_inventory(host_list)
  File "/opt/ansible/ansible-2.2.0.0/lib/ansible/inventory/__init__.py", line 164, in parse_inventory
    group.vars = combine_vars(group.vars, self.get_group_variables(group.name))
  File "/opt/ansible/ansible-2.2.0.0/lib/ansible/inventory/__init__.py", line 554, in get_group_variables
    self._vars_per_group[groupname] = self._get_group_variables(groupname, vault_password=vault_password)
  File "/opt/ansible/ansible-2.2.0.0/lib/ansible/inventory/__init__.py", line 572, in _get_group_variables
    vars = combine_vars(vars, self.get_group_vars(group))
  File "/opt/ansible/ansible-2.2.0.0/lib/ansible/inventory/__init__.py", line 774, in get_group_vars
    return self._get_hostgroup_vars(host=None, group=group, new_pb_basedir=new_pb_basedir, return_results=return_results)
  File "/opt/ansible/ansible-2.2.0.0/lib/ansible/inventory/__init__.py", line 835, in _get_hostgroup_vars
    host_results = self._variable_manager.add_group_vars_file(base_path, self._loader)
  File "/opt/ansible/ansible-2.2.0.0/lib/ansible/vars/__init__.py", line 615, in add_group_vars_file
    data = self._load_inventory_file(path, loader)
  File "/opt/ansible/ansible-2.2.0.0/lib/ansible/vars/__init__.py", line 573, in _load_inventory_file
    rval.update(data)
ValueError: dictionary update sequence element #0 has length 1; 2 is required
```
This does not happen on *group_vars/all*

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
Proper facts output.

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```
[dag@moria ansible.testing]$ ansible localhost -m setup 
ERROR! Unexpected Exception: dictionary update sequence element #0 has length 1; 2 is required
to see the full traceback, use -vvv
```


Discussion:
Same problem happens with playbooks BTW, so not specific to ansible-cli.

Resolving patch:
diff --git a/lib/ansible/vars/__init__.py b/lib/ansible/vars/__init__.py
--- a/lib/ansible/vars/__init__.py
+++ b/lib/ansible/vars/__init__.py
@@ -575,8 +575,13 @@ def _load_inventory_file(self, path, loader):
 
         rval = AnsibleInventoryVarsData()
         rval.path = path
+
         if data is not None:
-            rval.update(data)
+            if not isinstance(data, dict):
+                raise AnsibleError("Problem parsing file '%s': line %d, column %d" % data.ansible_pos)
+            else:
+                rval.update(data)
+
         return rval
 
     def add_host_vars_file(self, path, loader):


Test patch: