Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eos_config: Fix test issues #56180

Merged
merged 7 commits into from May 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 15 additions & 4 deletions lib/ansible/module_utils/network/eos/eos.py
Expand Up @@ -121,6 +121,12 @@ def __init__(self, module):
self._session_support = None
self._connection = None

@property
def supports_sessions(self):
if self._session_support is None:
self._session_support = self._get_connection().supports_sessions()
return self._session_support

def _get_connection(self):
if self._connection:
return self._connection
Expand Down Expand Up @@ -230,10 +236,9 @@ def __init__(self, module):

@property
def supports_sessions(self):
if self._session_support:
return self._session_support
response = self.send_request(['show configuration sessions'])
self._session_support = 'error' not in response
if self._session_support is None:
response = self.send_request(['show configuration sessions'])
self._session_support = 'error' not in response
return self._session_support

def _request_builder(self, commands, output, reqid=None):
Expand Down Expand Up @@ -428,6 +433,12 @@ def _connection(self):

return self._connection_obj

@property
def supports_sessions(self):
if self._session_support is None:
self._session_support = self._connection.supports_sessions()
return self._session_support

def run_commands(self, commands, check_rc=True):
"""Runs list of commands on remote device and returns results
"""
Expand Down
4 changes: 4 additions & 0 deletions lib/ansible/modules/network/eos/eos_config.py
Expand Up @@ -396,6 +396,10 @@ def main():
flags = ['all'] if module.params['defaults'] else []
connection = get_connection(module)

# Refuse to diff_against: session if essions are disabled
if module.params['diff_against'] == 'session' and not connection.supports_sessions:
module.fail_json(msg="Cannot diff against sessions when sessions are disabled. Please change diff_against to another value")

if module.params['backup'] or (module._diff and module.params['diff_against'] == 'running'):
contents = get_config(module, flags=flags)
config = NetworkConfig(indent=1, contents=contents)
Expand Down
17 changes: 8 additions & 9 deletions lib/ansible/plugins/cliconf/eos.py
Expand Up @@ -83,12 +83,12 @@ def edit_config(self, candidate=None, commit=True, replace=None, comment=None):
operations = self.get_device_operations()
self.check_edit_config_capability(operations, candidate, commit, replace, comment)

if (commit is False) and (not self.supports_sessions):
if (commit is False) and (not self.supports_sessions()):
raise ValueError('check mode is not supported without configuration session')

resp = {}
session = None
if self.supports_sessions:
if self.supports_sessions():
session = 'ansible_%s' % int(time.time())
resp.update({'session': session})
self.send_command('configure session %s' % session)
Expand Down Expand Up @@ -125,7 +125,7 @@ def edit_config(self, candidate=None, commit=True, replace=None, comment=None):

resp['request'] = requests
resp['response'] = results
if self.supports_sessions:
if self.supports_sessions():
out = self.send_command('show session-config diffs')
if out:
resp['diff'] = out.strip()
Expand All @@ -148,7 +148,7 @@ def commit(self):

def discard_changes(self, session=None):
commands = ['end']
if self.supports_sessions:
if self.supports_sessions():
# to close session gracefully execute abort in top level session prompt.
commands.extend(['configure session %s' % session, 'abort'])

Expand Down Expand Up @@ -213,7 +213,6 @@ def get_diff(self, candidate=None, running=None, diff_match='line', diff_ignore_
diff['config_diff'] = dumps(configdiffobjs, 'commands') if configdiffobjs else ''
return diff

@property
def supports_sessions(self):
use_session = self.get_option('eos_use_sessions')
try:
Expand Down Expand Up @@ -262,16 +261,16 @@ def get_device_info(self):
def get_device_operations(self):
return {
'supports_diff_replace': True,
'supports_commit': True if self.supports_sessions else False,
'supports_commit': bool(self.supports_sessions()),
'supports_rollback': False,
'supports_defaults': False,
'supports_onbox_diff': True if self.supports_sessions else False,
'supports_onbox_diff': bool(self.supports_sessions()),
'supports_commit_comment': False,
'supports_multiline_delimiter': False,
'supports_diff_match': True,
'supports_diff_ignore_lines': True,
'supports_generate_diff': False if self.supports_sessions else True,
'supports_replace': True if self.supports_sessions else False
'supports_generate_diff': not bool(self.supports_sessions()),
'supports_replace': bool(self.supports_sessions()),
}

def get_option_values(self):
Expand Down
9 changes: 4 additions & 5 deletions lib/ansible/plugins/httpapi/eos.py
Expand Up @@ -48,7 +48,6 @@ def __init__(self, *args, **kwargs):
self._device_info = None
self._session_support = None

@property
def supports_sessions(self):
use_session = self.get_option('eos_use_sessions')
try:
Expand Down Expand Up @@ -119,16 +118,16 @@ def get_device_info(self):
def get_device_operations(self):
return {
'supports_diff_replace': True,
'supports_commit': bool(self.supports_sessions),
'supports_commit': bool(self.supports_sessions()),
'supports_rollback': False,
'supports_defaults': False,
'supports_onbox_diff': bool(self.supports_sessions),
'supports_onbox_diff': bool(self.supports_sessions()),
'supports_commit_comment': False,
'supports_multiline_delimiter': False,
'supports_diff_match': True,
'supports_diff_ignore_lines': True,
'supports_generate_diff': not bool(self.supports_sessions),
'supports_replace': bool(self.supports_sessions),
'supports_generate_diff': not bool(self.supports_sessions()),
'supports_replace': bool(self.supports_sessions()),
}

def get_capabilities(self):
Expand Down
21 changes: 20 additions & 1 deletion test/integration/targets/eos_config/tests/cli/check_mode.yaml
@@ -1,5 +1,6 @@
---
- debug: msg="START cli/check_mode.yaml on connection={{ ansible_connection }}"
- debug:
msg: "START cli/check_mode.yaml on connection={{ ansible_connection }}"

- name: invalid configuration in check mode
eos_config:
Expand Down Expand Up @@ -39,11 +40,28 @@
that:
- "config.session not in result.stdout[0].sessions"

- name: configuration in check mode + no config session
eos_config:
lines:
- ip address 119.31.1.1 255.255.255.254
parents: interface Loopback911
become: yes
check_mode: 1
vars:
ansible_eos_use_sessions: 0
register: result
ignore_errors: yes

- assert:
that:
- "result.failed == true"

- 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
diff_against: running
become: yes
check_mode: 1
vars:
Expand All @@ -60,6 +78,7 @@
lines:
- ip address 119.31.1.1 255.255.255.255
parents: interface Loopback911
diff_against: running
become: yes
check_mode: yes
register: result
Expand Down
@@ -1,5 +1,6 @@
---
- debug: msg="START cli/sublevel_strict_mul_parents.yaml on connection={{ ansible_connection }}"
- debug:
msg: "START cli/sublevel_strict_mul_parents.yaml on connection={{ ansible_connection }}"

- name: setup
eos_config:
Expand All @@ -12,60 +13,67 @@
match: none
become: yes

- name: configure sub level command using strict match
eos_config:
lines:
- set cos 1
- set dscp 62
parents: ['policy-map type qos p1', 'class c1']
match: strict
register: result
become: yes
- block:
- name: configure sub level command using strict match
eos_config:
lines:
- set cos 1
- set dscp 62
parents: ['policy-map type qos p1', 'class c1']
match: strict
# session-config diffs does not produce a diff here for some reason.
# check against running-config instead.
diff_against: running
register: result
become: yes

- assert:
that:
- "result.changed == true"
- "'set cos 1' in result.updates"
- "'set dscp 62' in result.updates"
- assert:
that:
- "result.changed == true"
- "'set cos 1' in result.updates"
- "'set dscp 62' in result.updates"

- name: change sub level command order and config with strict match
eos_config:
lines:
- set dscp 62
- set cos 1
parents: ['policy-map type qos p1', 'class c1']
match: strict
register: result
become: yes
- name: change sub level command order and config with strict match
eos_config:
lines:
- set dscp 62
- set cos 1
parents: ['policy-map type qos p1', 'class c1']
match: strict
diff_against: running
register: result
become: yes

- assert:
that:
- "result.changed == true"
- "'set cos 1' in result.updates"
- "'set dscp 62' in result.updates"
- assert:
that:
- "result.changed == true"
- "'set cos 1' in result.updates"
- "'set dscp 62' in result.updates"

- name: Config sub level command with strict match (Idempotency)
eos_config:
lines:
#EOS does not change order of class action if reconfigured
#so we have to use old order for Idempotency
- set cos 1
- set dscp 62
parents: ['policy-map type qos p1', 'class c1']
match: strict
register: result
become: yes
- name: Config sub level command with strict match (Idempotency)
eos_config:
lines:
#EOS does not change order of class action if reconfigured
#so we have to use old order for Idempotency
- set cos 1
- set dscp 62
parents: ['policy-map type qos p1', 'class c1']
match: strict
diff_against: running
register: result
become: yes

- assert:
that:
- "result.changed == false"
- assert:
that:
- "result.changed == false"

- name: teardown
eos_config:
lines:
- no policy-map type qos p1
- no class-map type qos match-any c1
match: none
become: yes
always:
- name: teardown
eos_config:
lines:
- no policy-map type qos p1
- no class-map type qos match-any c1
match: none
become: yes

- debug: msg="END cli/sublevel_strict_mul_parents.yaml on connection={{ ansible_connection }}"