Repository: ansible/ansible

Issue:
ios_config defaults: yes doesnt work for version 12.4(25b)
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report

##### COMPONENT NAME
<!--- Name of the module/plugin/task/feature -->
ios_config

##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
```
$ ansible --version
ansible 2.2.1.0
  config file = /home/jmighion/git/blank-ansible-repo/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).
-->
inventory = inventory
forks = 1400
roles_path = roles
retry_files_enabled = False

##### 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.
-->
From RHEL 7.3 to Cisco IOS 12.4(25b)

##### SUMMARY
<!--- Explain the problem briefly -->
Using `defaults` causes an error stating that the command ran is incorrect. `defaults` runs `show running-config all` and the all option is not in 12.4(25b). I believe this could error more gracefully stating that `default` isn't a valid option for the version of IOS or potentially fall back to using the full option like `show running-config full`. 

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->
IOS device
<!--- Paste example playbooks or commands between quotes below -->
```
#show running-config ?
  brief       configuration without certificate data
  class-map   Show class-map information
  full        full configuration
  interface   Show interface configuration
  linenum     Display line numbers in output
  map-class   Show map class information
  policy-map  Show policy-map information
  view        View options
  |           Output modifiers
  <cr>

#show version
Cisco IOS Software, 3700 Software (C3745-ADVIPSERVICESK9-M), Version 12.4(25b), RELEASE SOFTWARE (fc1)
```

Task
```
- name: Config NTP
  ios_config:
    defaults: yes
    lines: ntp authenticate
    provider: "{{ cli }}"
```
<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
Either run `show running-config full` or explain that the all option is not available for the version of IOS.

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```
Invalid input detected at '^' marker
```



Discussion:
cc @privateip @rcarrillocruz
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/lib/ansible/module_utils/ios.py b/lib/ansible/module_utils/ios.py
--- a/lib/ansible/module_utils/ios.py
+++ b/lib/ansible/module_utils/ios.py
@@ -50,6 +50,16 @@ def check_args(module, warnings):
             warnings.append('argument %s has been deprecated and will be '
                     'removed in a future version' % key)
 
+def get_defaults_flag(module):
+    rc, out, err = exec_command(module, 'show running-config ?')
+
+    commands = set()
+    for line in out.splitlines():
+        if line:
+            commands.add(line.strip().split()[0])
+
+    return 'all' if 'all' in commands else 'full'
+
 def get_config(module, flags=[]):
     cmd = 'show running-config '
     cmd += ' '.join(flags)
diff --git a/lib/ansible/modules/network/ios/ios_config.py b/lib/ansible/modules/network/ios/ios_config.py
--- a/lib/ansible/modules/network/ios/ios_config.py
+++ b/lib/ansible/modules/network/ios/ios_config.py
@@ -206,6 +206,7 @@
 import time
 
 from ansible.module_utils.ios import run_commands, get_config, load_config
+from ansible.module_utils.ios import get_defaults_flag
 from ansible.module_utils.ios import ios_argument_spec
 from ansible.module_utils.ios import check_args as ios_check_args
 from ansible.module_utils.basic import AnsibleModule
@@ -266,7 +267,7 @@ def get_running_config(module):
     if not contents:
         flags = []
         if module.params['defaults']:
-            flags.append('all')
+            flags.append(get_defaults_flag(module))
         contents = get_config(module, flags=flags)
     contents, banners = extract_banners(contents)
     return NetworkConfig(indent=1, contents=contents), banners


Test patch: