Repository: ansible/ansible

Issue:
edgeos config fact retrieval fails
##### ISSUE TYPE

 - Bug Report

##### COMPONENT NAME
`edgeos_facts`

##### ANSIBLE VERSION
```
ansible 2.5.0rc1
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/celebdor/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.14 (default, Jan  5 2018, 10:41:29) [GCC 7.2.1 20171224]
```

##### CONFIGURATION
##### OS / ENVIRONMENT
```
Arch Linux managing 
        "ansible_net_hostname": "ubnt", 
        "ansible_net_model": "EdgeRouter X 5-Port", 
        "ansible_net_serialnum": "F09FC2608F10", 
        "ansible_net_version": "1.10.0", 
        "ansible_network_os": "edgeos", 
        "ansible_playbook_python": "/usr/bin/python2", 
        "ansible_run_tags": [
            "all"
        ], 
```

##### SUMMARY
When trying to gather config facts I get an error due to trying to:

https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/network/edgeos/edgeos_facts.py#L174

Which is trying to assign some string to a dictionary that was not created in the current
execution branch. The naive fix is to just change that to:

     entry= {'comment': line.strip()}

##### STEPS TO REPRODUCE

```yaml
- name: Demonstrate connecting to netdevs
  hosts: switches
  gather_facts: no

  tasks:
    - name: Gather facts (edgeos)
      edgeos_facts:
        gather_subset: config
      when: "'edgeos' in group_names"
    - name: Display facts
      debug:
        var: hostvars['my-router.home.lan']
```
```
[switches:children]
edgeos

[edgeos]
my-router.home.lan ansible_connection=network_cli ansible_network_os=edgeos ansible_user=admin ansible_ssh_private_key_file=/home/me/routers/id_rsa
```

##### EXPECTED RESULTS
Facts are gathered with the field 'ansible_net_config' containing all the commands to set the config of the router.

##### ACTUAL RESULTS
```
celebdor@s21 ~/ansible_networking $ ansible-playbook -vvv -i inventory fetch-facts.yml
ansible-playbook 2.5.0rc1
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/celebdor/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible-playbook
  python version = 2.7.14 (default, Jan  5 2018, 10:41:29) [GCC 7.2.1 20171224]
Using /etc/ansible/ansible.cfg as config file
Parsed /home/celebdor/ansible_networking/inventory inventory source with ini plugin
 ___________________________ 
< PLAYBOOK: fetch-facts.yml >
 --------------------------- 
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

1 plays in fetch-facts.yml
 __________________________________________ 
< PLAY [Demonstrate connecting to netdevs] >
 ------------------------------------------ 
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

META: ran handlers
 ______________________________ 
< TASK [Gather facts (edgeos)] >
 ------------------------------ 
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

task path: /home/celebdor/ansible_networking/fetch-facts.yml:6
Using module file /usr/lib/python2.7/site-packages/ansible/modules/network/edgeos/edgeos_facts.py
<erx.home.sepu.cz> ESTABLISH LOCAL CONNECTION FOR USER: celebdor
<erx.home.sepu.cz> EXEC /bin/sh -c 'echo ~ && sleep 0'
<erx.home.sepu.cz> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/celebdor/.ansible/tmp/ansible-tmp-1520435074.83-180899695818189 `" && echo ansible-tmp-1520435074.83-180899695818189="` echo /home/celebdor/.ansible/tmp/ansible-tmp-1520435074.83-180899695818189 `" ) && sleep 0'                                                                                                                                          
<erx.home.sepu.cz> PUT /home/celebdor/.ansible/tmp/ansible-local-251093D4MoI/tmpKTLQLZ TO /home/celebdor/.ansible/tmp/ansible-tmp-1520435074.83-180899695818189/edgeos_facts.py
<erx.home.sepu.cz> EXEC /bin/sh -c 'chmod u+x /home/celebdor/.ansible/tmp/ansible-tmp-1520435074.83-180899695818189/ /home/celebdor/.ansible/tmp/ansible-tmp-1520435074.83-180899695818189/edgeos_facts.py && sleep 0'                                                                                                                                                                                                                
<erx.home.sepu.cz> EXEC /bin/sh -c '/usr/bin/python /home/celebdor/.ansible/tmp/ansible-tmp-1520435074.83-180899695818189/edgeos_facts.py && sleep 0'
<erx.home.sepu.cz> EXEC /bin/sh -c 'rm -f -r /home/celebdor/.ansible/tmp/ansible-tmp-1520435074.83-180899695818189/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_my96l988/ansible_module_edgeos_facts.py", line 311, in <module>
    main()
  File "/tmp/ansible_my96l988/ansible_module_edgeos_facts.py", line 299, in main
    inst.populate()
  File "/tmp/ansible_my96l988/ansible_module_edgeos_facts.py", line 174, in populate
    entry['comment'] = line.strip()
TypeError: 'NoneType' object does not support item assignment

fatal: [my-router.home.lan]: FAILED! => {
    "changed": false, 
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_my96l988/ansible_module_edgeos_facts.py\", line 311, in <module>\n    main()\n  File \"/tmp/ansible_my96l988/ansible_module_edgeos_facts.py\", line 299, in main\n    inst.populate()\n  File \"/tmp/ansible_my96l988/ansible_module_edgeos_facts.py\", line 174, in populate\n    entry['comment'] = line.strip()\nTypeError: 'NoneType' object does not support item assignment\n",                                                                                                                                                                                    
    "module_stdout": "", 
    "msg": "MODULE FAILURE", 
    "rc": 1
}
        to retry, use: --limit @/home/celebdor/ansible_networking/fetch-facts.retry
 ____________ 
< PLAY RECAP >
 ------------ 
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

my-router.home.lan           : ok=0    changed=0    unreachable=0    failed=1
```



Discussion:
@samdoran Doing the naive change I proposed let me get the config. Is that enough?
cc @qalthos
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
I'm able to duplicate this by disabling system commit message tracking, then removing `/config/archive/commits`. Essentially, this fails when there are no commit messages in `show system commit`.

Can you verify by running `show system commit` and `show configuration commands | match commit`?

I'll work on a fix. Thanks for reporting this!
Thanks for the quick response @samdoran ! Here's the output

```
celebdor@ubnt:~$ show system commit
commit-revisions is not configured.
celebdor@ubnt:~$ show configuration commands | match commit
celebdor@ubnt:~$
```
So yes, it's like in your reproduction.
Ok, that's very helpful. Thank you for confirming!
you're most welcome :-)

Resolving patch:
diff --git a/lib/ansible/modules/network/edgeos/edgeos_config.py b/lib/ansible/modules/network/edgeos/edgeos_config.py
--- a/lib/ansible/modules/network/edgeos/edgeos_config.py
+++ b/lib/ansible/modules/network/edgeos/edgeos_config.py
@@ -27,6 +27,9 @@
     in the device configuration.
 notes:
   - Tested against EdgeOS 1.9.7
+  - Setting C(ANSIBLE_PERSISTENT_COMMAND_TIMEOUT) to 30 is recommended since
+    the save command can take longer than the default of 10 seconds on
+    some EdgeOS hardware.
 options:
   lines:
     description:
diff --git a/lib/ansible/modules/network/edgeos/edgeos_facts.py b/lib/ansible/modules/network/edgeos/edgeos_facts.py
--- a/lib/ansible/modules/network/edgeos/edgeos_facts.py
+++ b/lib/ansible/modules/network/edgeos/edgeos_facts.py
@@ -170,7 +170,7 @@ def populate(self):
                              by=str(match.group(3)).strip(),
                              via=str(match.group(4)).strip(),
                              comment=None)
-            else:
+            elif entry:
                 entry['comment'] = line.strip()
 
         self.facts['commits'] = entries


Test patch: