Repository: ansible/ansible

Issue:
authorize to yes should enter privileged mode eos_banner 
##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report

##### COMPONENT NAME
<!--- Name of the module/plugin/task/feature -->
eos_banner
##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
```
2.4.0 devel (latest)
```

##### 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.
-->
Fedora 25 Workstation

##### 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.
-->
```
- name: Configure the login banner
  eos_banner:
    banner: login
    text: |
      this is my login banner
      that contains a multiline
      string
    state: present
    authorize: yes
```

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
Should enter priveleged mode and returns list 
```['banner login', 'this is my login banner', 'that contains a multiline', 'string', 'EOF']```
##### ACTUAL RESULTS
Verbose Output
```
The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_ovFb9b/ansible_module_eos_banner.py", line 184, in <module>
    main()
  File "/tmp/ansible_ovFb9b/ansible_module_eos_banner.py", line 175, in main
    response = load_config(module, commands, commit=commit)
  File "/tmp/ansible_ovFb9b/ansible_modlib.zip/ansible/module_utils/eos.py", line 459, in load_config
  File "/tmp/ansible_ovFb9b/ansible_modlib.zip/ansible/module_utils/eos.py", line 233, in load_config
  File "/tmp/ansible_ovFb9b/ansible_modlib.zip/ansible/module_utils/eos.py", line 176, in send_config
AttributeError: 'dict' object has no attribute 'startswith'

fatal: [172.26.4.24]: FAILED! => {
    "changed": false, 
    "failed": true, 
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_ovFb9b/ansible_module_eos_banner.py\", line 184, in <module>\n    main()\n  File \"/tmp/ansible_ovFb9b/ansible_module_eos_banner.py\", line 175, in main\n    response = load_config(module, commands, commit=commit)\n  File \"/tmp/ansible_ovFb9b/ansible_modlib.zip/ansible/module_utils/eos.py\", line 459, in load_config\n  File \"/tmp/ansible_ovFb9b/ansible_modlib.zip/ansible/module_utils/eos.py\", line 233, in load_config\n  File \"/tmp/ansible_ovFb9b/ansible_modlib.zip/ansible/module_utils/eos.py\", line 176, in send_config\nAttributeError: 'dict' object has no attribute 'startswith'\n", 
    "module_stdout": "", 
    "msg": "MODULE FAILURE", 
    "rc": 0
}
```


Discussion:
cc @privateip
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
FYI there are integration tests for this https://github.com/ansible/ansible/tree/devel/test/integration/targets/eos_banner/tests
```
cd test/integration
ANSIBLE_ROLES_PATH=targets  ansible-playbook  -vvvvvv  -i  inventory.network eos.yaml   "limit_to=eos_banner"
```
It could be an issue with failure to read the prompt from the CLI, but in that case the error message should be more specific.
Ah, I see. The issue is that there is not a default value for `transport` in eos. The module_utils only checks if transport is 'eapi' to set the connection, and eos_banner only checks if transport is 'cli' to determine how to interpret responses from the machine. Thus, if `transport` is unspecified, it gets a cli connection (transport is not eapi) and tries to interpret the commands as if it were coming from eapi (transport is not cli).

Resolving patch:
diff --git a/lib/ansible/module_utils/eos.py b/lib/ansible/module_utils/eos.py
--- a/lib/ansible/module_utils/eos.py
+++ b/lib/ansible/module_utils/eos.py
@@ -59,6 +59,7 @@
 
 # Add argument's default value here
 ARGS_DEFAULT_VALUE = {
+    'transport': 'cli',
     'port': 443,
     'use_ssl': True,
     'validate_certs': True
@@ -94,9 +95,7 @@ def get_connection(module):
     global _DEVICE_CONNECTION
     if not _DEVICE_CONNECTION:
         load_params(module)
-        transport = module.params['transport']
-        provider_transport = (module.params['provider'] or {}).get('transport')
-        if 'eapi' in (transport, provider_transport):
+        if is_eapi(module):
             conn = Eapi(module)
         else:
             conn = Cli(module)


Test patch: