Repository: ansible/ansible

Issue:
TypeError: can only join an iterable on all ios modules
<!---
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 2.4.0 (devel 4d55148ab2) last updated 2017/07/17 09:45:47 (GMT -400)
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/Users/dnewswan/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/dnewswan/code/ansible/lib/ansible
  executable location = /Users/dnewswan/code/ansible/bin/ansible
  python version = 2.7.13 (default, Apr  4 2017, 08:47:57) [GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.38)]
```

##### CONFIGURATION
<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->

##### 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.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
macOS Sierra

##### SUMMARY
<!--- Explain the problem briefly -->

##### 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.
-->
Run ios tests using `ansible-playbook -i inventory.network -vvvv -k -u cisco ios.yaml`

<!--- Paste example playbooks or commands between quotes below -->
```yaml

```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
Tests should pass

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```
The full traceback is:
Traceback (most recent call last):
  File "/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_module_ios_config.py", line 530, in <module>
    main()
  File "/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_module_ios_config.py", line 438, in main
    config, have_banners = get_running_config(module, config)
  File "/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_module_ios_config.py", line 347, in get_running_config
    contents = get_config(module, flags=flags)
  File "/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_modlib.zip/ansible/module_utils/ios.py", line 85, in get_config
TypeError: can only join an iterable

fatal: [ios01]: FAILED! => {
    "changed": false,
    "failed": true,
    "module_stderr": "Traceback (most recent call last):\n  File \"/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_module_ios_config.py\", line 530, in <module>\n    main()\n  File \"/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_module_ios_config.py\", line 438, in main\n    config, have_banners = get_running_config(module, config)\n  File \"/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_module_ios_config.py\", line 347, in get_running_config\n    contents = get_config(module, flags=flags)\n  File \"/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_modlib.zip/ansible/module_utils/ios.py\", line 85, in get_config\nTypeError: can only join an iterable\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 0
}
```

TypeError: can only join an iterable on all ios modules
<!---
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 2.4.0 (devel 4d55148ab2) last updated 2017/07/17 09:45:47 (GMT -400)
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/Users/dnewswan/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/dnewswan/code/ansible/lib/ansible
  executable location = /Users/dnewswan/code/ansible/bin/ansible
  python version = 2.7.13 (default, Apr  4 2017, 08:47:57) [GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.38)]
```

##### CONFIGURATION
<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->

##### 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.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
macOS Sierra

##### SUMMARY
<!--- Explain the problem briefly -->

##### 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.
-->
Run ios tests using `ansible-playbook -i inventory.network -vvvv -k -u cisco ios.yaml`

<!--- Paste example playbooks or commands between quotes below -->
```yaml

```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
Tests should pass

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```
The full traceback is:
Traceback (most recent call last):
  File "/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_module_ios_config.py", line 530, in <module>
    main()
  File "/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_module_ios_config.py", line 438, in main
    config, have_banners = get_running_config(module, config)
  File "/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_module_ios_config.py", line 347, in get_running_config
    contents = get_config(module, flags=flags)
  File "/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_modlib.zip/ansible/module_utils/ios.py", line 85, in get_config
TypeError: can only join an iterable

fatal: [ios01]: FAILED! => {
    "changed": false,
    "failed": true,
    "module_stderr": "Traceback (most recent call last):\n  File \"/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_module_ios_config.py\", line 530, in <module>\n    main()\n  File \"/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_module_ios_config.py\", line 438, in main\n    config, have_banners = get_running_config(module, config)\n  File \"/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_module_ios_config.py\", line 347, in get_running_config\n    contents = get_config(module, flags=flags)\n  File \"/var/folders/ql/d9_087wj4cd10grvwzxmk4hc0000gn/T/ansible_XWMNMk/ansible_modlib.zip/ansible/module_utils/ios.py\", line 85, in get_config\nTypeError: can only join an iterable\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 0
}
```



Discussion:

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
@@ -71,13 +71,13 @@ def get_defaults_flag(module):
 
     commands = set()
     for line in out.splitlines():
-        if line:
+        if line.strip():
             commands.add(line.strip().split()[0])
 
     if 'all' in commands:
-        return 'all'
+        return ['all']
     else:
-        return 'full'
+        return ['full']
 
 
 def get_config(module, 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
@@ -343,7 +343,7 @@ def get_running_config(module, current_config=None):
         if not module.params['defaults'] and current_config:
             contents, banners = extract_banners(current_config.config_text)
         else:
-            flags = get_defaults_flag(module) if module.params['defaults'] else None
+            flags = get_defaults_flag(module) if module.params['defaults'] else []
             contents = get_config(module, flags=flags)
     contents, banners = extract_banners(contents)
     return NetworkConfig(indent=1, contents=contents), banners


Test patch: