Repository: ansible/ansible

Issue:
eos_config: ANSIBLE_EOS_USE_SESSIONS causes changes on switch in check mode
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
eos_config

##### ANSIBLE VERSION
```
ansible 2.4.3.0
  config file = /home/user/.ansible.cfg
  configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/user/soft/ansible/lib/python3.6/site-packages/ansible
  executable location = /home/user/bin/ansible
  python version = 3.6.1 (default, Jun  2 2017, 15:55:17) [GCC 4.8.4]
```

##### CONFIGURATION
<!---
ANSIBLE_EOS_USE_SESSIONS=0
-->

##### OS / ENVIRONMENT
N/A

##### SUMMARY
When EOS do not support configure sessions or ANSIBLE_EOS_USE_SESSIONS=0 is provided to disable it - commands are applied even in check mode.

##### STEPS TO REPRODUCE
Run eos_config with ANSIBLE_EOS_USE_SESSIONS=0 in check mode.

```yaml
- name: testnosession
  eos_config:
    before:
      - "no ip access-list test"
    src: cmds.j2
    provider: "{{ arista_provider }}"
  check_mode: yes
  environment:
    ANSIBLE_EOS_USE_SESSIONS: 0
```

cmds.j2:
```
ip access-list test
   10 permit ip host 192.168.0.1 host 192.168.0.2
   20 permit ip host 192.168.0.2 host 192.168.0.1
!
```

##### EXPECTED RESULTS
Configuration on the switch remains unchanged.

##### ACTUAL RESULTS
Commands are applied to the switch.

Before ansible run:
```
switch#show running-config | section ip.access-list.test
ip access-list test
   10 permit ip host 192.168.0.2 host 192.168.0.1
   20 permit ip host 192.168.0.1 host 192.168.0.2
```

ansible run:
```
$ ansible-playbook -i hosts-test -l switch -CD test-nosess.yml 

PLAY [all] *********************************************************************

TASK [testsessionabort : testnosession] ****************************************
changed: [switch]

PLAY RECAP *********************************************************************
switch                  : ok=1    changed=1    unreachable=0    failed=0   
```
And switch config after run:
```
switch#show running-config | section ip.access-list.test
ip access-list test
   10 permit ip host 192.168.0.1 host 192.168.0.2
   20 permit ip host 192.168.0.2 host 192.168.0.1
```

load_config function in module_utils/eos.py falls back to function configure() if session is not supported or disabled:
```
        if not all((bool(use_session), self.supports_sessions)):
            return self.configure(commands)
```
And there is no checks if we want to commit changes or not.


Discussion:
Files identified in the description:
* [lib/ansible/modules/network/eos/eos_config.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/network/eos/eos_config.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @privateip @trishnaguha
[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/network/eos/eos.py b/lib/ansible/module_utils/network/eos/eos.py
--- a/lib/ansible/module_utils/network/eos/eos.py
+++ b/lib/ansible/module_utils/network/eos/eos.py
@@ -231,7 +231,12 @@ def load_config(self, commands, commit=False, replace=False):
             pass
 
         if not all((bool(use_session), self.supports_sessions)):
-            return self.configure(self, commands)
+            if commit:
+                return self.configure(self, commands)
+            else:
+                self._module.warn("EOS can not check config without config session")
+                result = {'changed': True}
+                return result
 
         conn = self._get_connection()
         session = 'ansible_%s' % int(time.time())
@@ -407,8 +412,19 @@ def load_config(self, config, commit=False, replace=False):
         fallback to using configure() to load the commands.  If that happens,
         there will be no returned diff or session values
         """
-        if not self.supports_sessions:
-            return self.configure(self, config)
+        use_session = os.getenv('ANSIBLE_EOS_USE_SESSIONS', True)
+        try:
+            use_session = int(use_session)
+        except ValueError:
+            pass
+
+        if not all((bool(use_session), self.supports_sessions)):
+            if commit:
+                return self.configure(self, config)
+            else:
+                self._module.warn("EOS can not check config without config session")
+                result = {'changed': True}
+                return result
 
         session = 'ansible_%s' % int(time.time())
         result = {'session': session}


Test patch:
diff --git a/test/integration/targets/eos_config/tests/cli/check_mode.yaml b/test/integration/targets/eos_config/tests/cli/check_mode.yaml
--- a/test/integration/targets/eos_config/tests/cli/check_mode.yaml
+++ b/test/integration/targets/eos_config/tests/cli/check_mode.yaml
@@ -37,4 +37,33 @@
    that:
      - "config.session not in result.stdout[0].sessions"
 
+- name: invalid configuration in check mode + no config session
+  eos_config:
+     lines:
+         - ip address 119.31.1.1 255.255.255.256
+     parents: interface Loopback911
+  check_mode: 1
+  environment:
+    ANSIBLE_EOS_USE_SESSIONS: 0
+  register: result
+  ignore_errors: yes
+
+- assert:
+   that:
+   - "result.changed == true"
+
+- name: valid configuration in check mode + no config session
+  eos_config:
+     lines:
+         - ip address 119.31.1.1 255.255.255.255
+     parents: interface Loopback911
+  check_mode: yes
+  register: result
+  environment:
+    ANSIBLE_EOS_USE_SESSIONS: 0
+
+- assert:
+   that:
+   - "result.changed == true"
+
 - debug: msg="END cli/check_mode.yaml on connection={{ ansible_connection }}"