Repository: ansible/ansible

Issue:
Template lookup|from_yaml fails if template evaluates to '[]'
##### ISSUE TYPE
- Bug Report
##### COMPONENT NAME
- template lookup
- from_yaml
##### ANSIBLE VERSION

ansible 2.1.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides

```

```
##### SUMMARY

When using the template lookup on a template that evaluates to `[]`  and using the `from_yaml` filter on that, a `AttributeError: 'list' object has no attribute 'read` gets thrown.
##### STEPS TO REPRODUCE

``` shell
cat > var.j2 <<EOF
[]
{# comment #}
EOF

cat > playbook.yml <<EOF

---
- hosts: localhost
  gather_facts: false
  vars:
    var: "{{ lookup('template', 'var.j2')|from_yaml}}"
  tasks:
    - debug: var=var
EOF

```
##### ACTUAL RESULTS

```
TASK [debug] *******************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: AttributeError: {{ lookup('template', 'var.j2')|from_yaml}}: 'list' object has no attribute 'read'
fatal: [localhost]: FAILED! => {"failed": true, "msg": "Unexpected failure during module execution.", "stdout": ""}

```

Template lookup|from_yaml fails if template evaluates to '[]'
##### ISSUE TYPE
- Bug Report
##### COMPONENT NAME
- template lookup
- from_yaml
##### ANSIBLE VERSION

ansible 2.1.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides

```

```
##### SUMMARY

When using the template lookup on a template that evaluates to `[]`  and using the `from_yaml` filter on that, a `AttributeError: 'list' object has no attribute 'read` gets thrown.
##### STEPS TO REPRODUCE

``` shell
cat > var.j2 <<EOF
[]
{# comment #}
EOF

cat > playbook.yml <<EOF

---
- hosts: localhost
  gather_facts: false
  vars:
    var: "{{ lookup('template', 'var.j2')|from_yaml}}"
  tasks:
    - debug: var=var
EOF

```
##### ACTUAL RESULTS

```
TASK [debug] *******************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: AttributeError: {{ lookup('template', 'var.j2')|from_yaml}}: 'list' object has no attribute 'read'
fatal: [localhost]: FAILED! => {"failed": true, "msg": "Unexpected failure during module execution.", "stdout": ""}

```

Template lookup|from_yaml fails if template evaluates to '[]'
##### ISSUE TYPE
- Bug Report
##### COMPONENT NAME
- template lookup
- from_yaml
##### ANSIBLE VERSION

ansible 2.1.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides

```

```
##### SUMMARY

When using the template lookup on a template that evaluates to `[]`  and using the `from_yaml` filter on that, a `AttributeError: 'list' object has no attribute 'read` gets thrown.
##### STEPS TO REPRODUCE

``` shell
cat > var.j2 <<EOF
[]
{# comment #}
EOF

cat > playbook.yml <<EOF

---
- hosts: localhost
  gather_facts: false
  vars:
    var: "{{ lookup('template', 'var.j2')|from_yaml}}"
  tasks:
    - debug: var=var
EOF

```
##### ACTUAL RESULTS

```
TASK [debug] *******************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: AttributeError: {{ lookup('template', 'var.j2')|from_yaml}}: 'list' object has no attribute 'read'
fatal: [localhost]: FAILED! => {"failed": true, "msg": "Unexpected failure during module execution.", "stdout": ""}

```



Discussion:

Resolving patch:
diff --git a/lib/ansible/plugins/filter/core.py b/lib/ansible/plugins/filter/core.py
--- a/lib/ansible/plugins/filter/core.py
+++ b/lib/ansible/plugins/filter/core.py
@@ -193,6 +193,11 @@ def regex_escape(string):
     '''Escape all regular expressions special characters from STRING.'''
     return re.escape(string)
 
+def from_yaml(data):
+    if isinstance(data, string_types):
+        return yaml.safe_load(data)
+    return data
+
 @environmentfilter
 def rand(environment, end, start=None, step=None):
     r = SystemRandom()
@@ -396,7 +401,7 @@ def filters(self):
             # yaml
             'to_yaml': to_yaml,
             'to_nice_yaml': to_nice_yaml,
-            'from_yaml': yaml.safe_load,
+            'from_yaml': from_yaml,
 
             #date
             'to_datetime': to_datetime,


Test patch: