Repository: ansible/ansible-modules-core

Issue:
Junos Facts Does Not Support "Set" Config Format
<!--- 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/module/task -->
`junos_facts`

##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
```
ansible 2.2.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
```

##### CONFIGURATION
<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->
N/A

##### 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.
-->
CentOS Linux release 7.2.1511 (Core)

##### SUMMARY
<!--- Explain the problem briefly -->
`junos_facts` does not support the `set` config_format` as stated in http://docs.ansible.com/ansible/junos_facts_module.html

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem.
For new features, show how the feature would be used.
-->
use the following config within a playbook assuming the proper `netconf_auth` is set for your environment.

```
- name: Collect default set of facts and configuration in set format
  register: juniper_config
  junos_facts:
    config: yes
    config_format: set
    port: 22
    provider: "{{ netconf_auth }}"
```

This results in:

```
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ansible.module_utils.network.NetworkError: invalid config format.  Valid options are text, xml
fatal: [my.router.url]: FAILED! => {"changed": false, "failed": true, "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_reFxNi/ansible_module_junos_facts.py\", line 130, in <module>\n    main()\n  File \"/tmp/ansible_reFxNi/ansible_module_junos_facts.py\", line 117, in main\n    resp_config = module.config.get_config(config_format=config_format)\n  File \"/tmp/ansible_reFxNi/ansible_modlib.zip/ansible/module_utils/netcfg.py\", line 61, in get_config\n  File \"/tmp/ansible_reFxNi/ansible_modlib.zip/ansible/module_utils/junos.py\", line 167, in get_config\n  File \"/tmp/ansible_reFxNi/ansible_modlib.zip/ansible/module_utils/junos.py\", line 93, in raise_exc\nansible.module_utils.network.NetworkError: invalid config format.  Valid options are text, xml\n", "module_stdout": "", "msg": "MODULE FAILURE"}
```

<!--- Paste example playbooks or commands between quotes below -->
```
- name: Collect default set of facts and configuration in set format
  register: juniper_config
  junos_facts:
    config: yes
    config_format: set
    port: 22
    provider: "{{ netconf_auth }}"
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
The `junos_facts` module would retrieve the configuration in set format.

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
An exception is raised stating that the `set` config type is not supported.

<!--- Paste verbatim command output between quotes below -->
```
TASK [router : Collect default set of facts and configuration in set format] ***
task path: /mnt/hgfs/python/backups/ansible/roles/router/tasks/main.yml:26
Using module file /usr/lib/python2.7/site-packages/ansible/modules/core/network/junos/junos_facts.py
<my.router.url> ESTABLISH LOCAL CONNECTION FOR USER: myusername
<my.router.url> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1479314958.15-144948237437035 `" && echo ansible-tmp-1479314958.15-144948237437035="` echo $HOME/.ansible/tmp/ansible-tmp-1479314958.15-144948237437035 `" ) && sleep 0'
<my.router.url> PUT /tmp/tmpbq__s7 TO /home/myusername/.ansible/tmp/ansible-tmp-1479314958.15-144948237437035/junos_facts.py
<my.router.url> EXEC /bin/sh -c 'chmod u+x /home/myusername/.ansible/tmp/ansible-tmp-1479314958.15-144948237437035/ /home/myusername/.ansible/tmp/ansible-tmp-1479314958.15-144948237437035/junos_facts.py && sleep 0'
<my.router.url> EXEC /bin/sh -c '/usr/bin/python /home/myusername/.ansible/tmp/ansible-tmp-1479314958.15-144948237437035/junos_facts.py; rm -rf "/home/myusername/.ansible/tmp/ansible-tmp-1479314958.15-144948237437035/" > /dev/null 2>&1 && sleep 0'
An exception occurred during task execution. The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_GCRADR/ansible_module_junos_facts.py", line 130, in <module>
    main()
  File "/tmp/ansible_GCRADR/ansible_module_junos_facts.py", line 117, in main
    resp_config = module.config.get_config(config_format=config_format)
  File "/tmp/ansible_GCRADR/ansible_modlib.zip/ansible/module_utils/netcfg.py", line 61, in get_config
  File "/tmp/ansible_GCRADR/ansible_modlib.zip/ansible/module_utils/junos.py", line 167, in get_config
  File "/tmp/ansible_GCRADR/ansible_modlib.zip/ansible/module_utils/junos.py", line 93, in raise_exc
ansible.module_utils.network.NetworkError: invalid config format.  Valid options are text, xml
fatal: [my.router.url]: FAILED! => {
    "changed": false, 
    "failed": true, 
    "invocation": {
        "module_name": "junos_facts"
    }, 
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_GCRADR/ansible_module_junos_facts.py\", line 130, in <module>\n    main()\n  File \"/tmp/ansible_GCRADR/ansible_module_junos_facts.py\", line 117, in main\n    resp_config = module.config.get_config(config_format=config_format)\n  File \"/tmp/ansible_GCRADR/ansible_modlib.zip/ansible/module_utils/netcfg.py\", line 61, in get_config\n  File \"/tmp/ansible_GCRADR/ansible_modlib.zip/ansible/module_utils/junos.py\", line 167, in get_config\n  File \"/tmp/ansible_GCRADR/ansible_modlib.zip/ansible/module_utils/junos.py\", line 93, in raise_exc\nansible.module_utils.network.NetworkError: invalid config format.  Valid options are text, xml\n", 
    "module_stdout": "", 
    "msg": "MODULE FAILURE"
}
```



Discussion:
<!-- @kkirsche: Thanks for filing this bug report! -->

@privateip, @gundalow, @qalthos, ping. This issue is waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_bug_new --->

@kkirsche AFAIK Ansible uses JUNOS 'get-configuration' RPC to retrieve facts from device. As per JUNOS documentation 'get-configuration' supports text or xml format only. So I think the error message displayed is correct.

Which would be fine, but that means the documentation is wrong as it says it supports set


Resolving patch:
diff --git a/network/junos/junos_facts.py b/network/junos/junos_facts.py
--- a/network/junos/junos_facts.py
+++ b/network/junos/junos_facts.py
@@ -44,12 +44,12 @@
       - The C(config_format) argument is used to specify the desired
         format of the configuration file.  Devices support three
         configuration file formats.  By default, the configuration
-        from the device is returned as text.  The other options include
-        set and xml.  If the xml option is chosen, the configuration file
-        is returned as both xml and json.
+        from the device is returned as text.  The other option xml.
+        If the xml option is chosen, the configuration file is 
+        returned as both xml and json.
     required: false
     default: text
-    choices: ['xml', 'text', 'set']
+    choices: ['xml', 'text']
 requirements:
   - junos-eznc
 notes:
@@ -68,10 +68,10 @@
   junos_facts:
     config: yes
 
-- name: collect default set of facts and configuration in set format
+- name: collect default set of facts and configuration in text format
   junos_facts:
     config: yes
-    config_format: set
+    config_format: text
 
 - name: collect default set of facts and configuration in XML and JSON format
   junos_facts:
@@ -95,7 +95,7 @@ def main():
     """
     spec = dict(
         config=dict(type='bool'),
-        config_format=dict(default='text', choices=['xml', 'set', 'text']),
+        config_format=dict(default='text', choices=['xml', 'text']),
         transport=dict(default='netconf', choices=['netconf'])
     )
 
@@ -116,7 +116,7 @@ def main():
         config_format = module.params['config_format']
         resp_config = module.config.get_config(config_format=config_format)
 
-        if config_format in ['text', 'set']:
+        if config_format in ['text']:
             facts['config'] = resp_config
         elif config_format == "xml":
             facts['config'] = xml_to_string(resp_config)


Test patch: