eos_config: Fix test issues (#56180)

* Alter tests to pass

* Change diff_against to make changed work again

* Add another diff_against

* Expose supports_sessions across all EOS connection types

* Change session warning to failure

* supports_sessions needs to be a method to survive the rpc boundary

* Alter tests to match
This commit is contained in:
Nathaniel Case 2019-05-09 08:32:25 -04:00 committed by Sumit Jaiswal
commit 0bead3672f
6 changed files with 109 additions and 69 deletions

View file

@ -121,6 +121,12 @@ class Cli:
self._session_support = None self._session_support = None
self._connection = 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): def _get_connection(self):
if self._connection: if self._connection:
return self._connection return self._connection
@ -230,10 +236,9 @@ class LocalEapi:
@property @property
def supports_sessions(self): def supports_sessions(self):
if self._session_support: if self._session_support is None:
return self._session_support response = self.send_request(['show configuration sessions'])
response = self.send_request(['show configuration sessions']) self._session_support = 'error' not in response
self._session_support = 'error' not in response
return self._session_support return self._session_support
def _request_builder(self, commands, output, reqid=None): def _request_builder(self, commands, output, reqid=None):
@ -428,6 +433,12 @@ class HttpApi:
return self._connection_obj 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): def run_commands(self, commands, check_rc=True):
"""Runs list of commands on remote device and returns results """Runs list of commands on remote device and returns results
""" """

View file

@ -396,6 +396,10 @@ def main():
flags = ['all'] if module.params['defaults'] else [] flags = ['all'] if module.params['defaults'] else []
connection = get_connection(module) 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'): if module.params['backup'] or (module._diff and module.params['diff_against'] == 'running'):
contents = get_config(module, flags=flags) contents = get_config(module, flags=flags)
config = NetworkConfig(indent=1, contents=contents) config = NetworkConfig(indent=1, contents=contents)

View file

@ -83,12 +83,12 @@ class Cliconf(CliconfBase):
operations = self.get_device_operations() operations = self.get_device_operations()
self.check_edit_config_capability(operations, candidate, commit, replace, comment) 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') raise ValueError('check mode is not supported without configuration session')
resp = {} resp = {}
session = None session = None
if self.supports_sessions: if self.supports_sessions():
session = 'ansible_%s' % int(time.time()) session = 'ansible_%s' % int(time.time())
resp.update({'session': session}) resp.update({'session': session})
self.send_command('configure session %s' % session) self.send_command('configure session %s' % session)
@ -125,7 +125,7 @@ class Cliconf(CliconfBase):
resp['request'] = requests resp['request'] = requests
resp['response'] = results resp['response'] = results
if self.supports_sessions: if self.supports_sessions():
out = self.send_command('show session-config diffs') out = self.send_command('show session-config diffs')
if out: if out:
resp['diff'] = out.strip() resp['diff'] = out.strip()
@ -148,7 +148,7 @@ class Cliconf(CliconfBase):
def discard_changes(self, session=None): def discard_changes(self, session=None):
commands = ['end'] commands = ['end']
if self.supports_sessions: if self.supports_sessions():
# to close session gracefully execute abort in top level session prompt. # to close session gracefully execute abort in top level session prompt.
commands.extend(['configure session %s' % session, 'abort']) commands.extend(['configure session %s' % session, 'abort'])
@ -213,7 +213,6 @@ class Cliconf(CliconfBase):
diff['config_diff'] = dumps(configdiffobjs, 'commands') if configdiffobjs else '' diff['config_diff'] = dumps(configdiffobjs, 'commands') if configdiffobjs else ''
return diff return diff
@property
def supports_sessions(self): def supports_sessions(self):
use_session = self.get_option('eos_use_sessions') use_session = self.get_option('eos_use_sessions')
try: try:
@ -262,16 +261,16 @@ class Cliconf(CliconfBase):
def get_device_operations(self): def get_device_operations(self):
return { return {
'supports_diff_replace': True, 'supports_diff_replace': True,
'supports_commit': True if self.supports_sessions else False, 'supports_commit': bool(self.supports_sessions()),
'supports_rollback': False, 'supports_rollback': False,
'supports_defaults': 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_commit_comment': False,
'supports_multiline_delimiter': False, 'supports_multiline_delimiter': False,
'supports_diff_match': True, 'supports_diff_match': True,
'supports_diff_ignore_lines': True, 'supports_diff_ignore_lines': True,
'supports_generate_diff': False if self.supports_sessions else True, 'supports_generate_diff': not bool(self.supports_sessions()),
'supports_replace': True if self.supports_sessions else False 'supports_replace': bool(self.supports_sessions()),
} }
def get_option_values(self): def get_option_values(self):

View file

@ -48,7 +48,6 @@ class HttpApi(HttpApiBase):
self._device_info = None self._device_info = None
self._session_support = None self._session_support = None
@property
def supports_sessions(self): def supports_sessions(self):
use_session = self.get_option('eos_use_sessions') use_session = self.get_option('eos_use_sessions')
try: try:
@ -119,16 +118,16 @@ class HttpApi(HttpApiBase):
def get_device_operations(self): def get_device_operations(self):
return { return {
'supports_diff_replace': True, 'supports_diff_replace': True,
'supports_commit': bool(self.supports_sessions), 'supports_commit': bool(self.supports_sessions()),
'supports_rollback': False, 'supports_rollback': False,
'supports_defaults': False, 'supports_defaults': False,
'supports_onbox_diff': bool(self.supports_sessions), 'supports_onbox_diff': bool(self.supports_sessions()),
'supports_commit_comment': False, 'supports_commit_comment': False,
'supports_multiline_delimiter': False, 'supports_multiline_delimiter': False,
'supports_diff_match': True, 'supports_diff_match': True,
'supports_diff_ignore_lines': True, 'supports_diff_ignore_lines': True,
'supports_generate_diff': not bool(self.supports_sessions), 'supports_generate_diff': not bool(self.supports_sessions()),
'supports_replace': bool(self.supports_sessions), 'supports_replace': bool(self.supports_sessions()),
} }
def get_capabilities(self): def get_capabilities(self):

View file

@ -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 - name: invalid configuration in check mode
eos_config: eos_config:
@ -39,11 +40,28 @@
that: that:
- "config.session not in result.stdout[0].sessions" - "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 - name: invalid configuration in check mode + no config session
eos_config: eos_config:
lines: lines:
- ip address 119.31.1.1 255.255.255.256 - ip address 119.31.1.1 255.255.255.256
parents: interface Loopback911 parents: interface Loopback911
diff_against: running
become: yes become: yes
check_mode: 1 check_mode: 1
vars: vars:
@ -60,6 +78,7 @@
lines: lines:
- ip address 119.31.1.1 255.255.255.255 - ip address 119.31.1.1 255.255.255.255
parents: interface Loopback911 parents: interface Loopback911
diff_against: running
become: yes become: yes
check_mode: yes check_mode: yes
register: result register: result

View file

@ -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 - name: setup
eos_config: eos_config:
@ -12,60 +13,67 @@
match: none match: none
become: yes become: yes
- name: configure sub level command using strict match - block:
eos_config: - name: configure sub level command using strict match
lines: eos_config:
- set cos 1 lines:
- set dscp 62 - set cos 1
parents: ['policy-map type qos p1', 'class c1'] - set dscp 62
match: strict parents: ['policy-map type qos p1', 'class c1']
register: result match: strict
become: yes # 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: - assert:
that: that:
- "result.changed == true" - "result.changed == true"
- "'set cos 1' in result.updates" - "'set cos 1' in result.updates"
- "'set dscp 62' in result.updates" - "'set dscp 62' in result.updates"
- name: change sub level command order and config with strict match - name: change sub level command order and config with strict match
eos_config: eos_config:
lines: lines:
- set dscp 62 - set dscp 62
- set cos 1 - set cos 1
parents: ['policy-map type qos p1', 'class c1'] parents: ['policy-map type qos p1', 'class c1']
match: strict match: strict
register: result diff_against: running
become: yes register: result
become: yes
- assert: - assert:
that: that:
- "result.changed == true" - "result.changed == true"
- "'set cos 1' in result.updates" - "'set cos 1' in result.updates"
- "'set dscp 62' in result.updates" - "'set dscp 62' in result.updates"
- name: Config sub level command with strict match (Idempotency) - name: Config sub level command with strict match (Idempotency)
eos_config: eos_config:
lines: lines:
#EOS does not change order of class action if reconfigured #EOS does not change order of class action if reconfigured
#so we have to use old order for Idempotency #so we have to use old order for Idempotency
- set cos 1 - set cos 1
- set dscp 62 - set dscp 62
parents: ['policy-map type qos p1', 'class c1'] parents: ['policy-map type qos p1', 'class c1']
match: strict match: strict
register: result diff_against: running
become: yes register: result
become: yes
- assert: - assert:
that: that:
- "result.changed == false" - "result.changed == false"
- name: teardown always:
eos_config: - name: teardown
lines: eos_config:
- no policy-map type qos p1 lines:
- no class-map type qos match-any c1 - no policy-map type qos p1
match: none - no class-map type qos match-any c1
become: yes match: none
become: yes
- debug: msg="END cli/sublevel_strict_mul_parents.yaml on connection={{ ansible_connection }}" - debug: msg="END cli/sublevel_strict_mul_parents.yaml on connection={{ ansible_connection }}"