1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Additional feature enhancements to nxos_logging (#45844)

* Various changes to nxos_logging.  Plus added purge capibility.

* Made a few new nxapi_logging test cases conditional based on version
and/or platform.

* Addressed PR comments and ansibot shippable.  Fixed up nxos_logging documentation format.

* Addressed ansibot shippable issues with whitespaces and documentation.

* Resolved ansibot codestyle trailing whitespace
This commit is contained in:
tstoner 2018-09-25 01:32:09 -04:00 committed by Trishna Guha
parent e26861435f
commit e74e8b8e75
6 changed files with 758 additions and 41 deletions

View file

@ -224,6 +224,24 @@ class Cli:
self._module._capabilities = json.loads(capabilities) self._module._capabilities = json.loads(capabilities)
return self._module._capabilities return self._module._capabilities
def read_module_context(self, module_key):
connection = self._get_connection()
try:
module_context = connection.read_module_context(module_key)
except ConnectionError as exc:
self._module.fail_json(msg=to_text(exc, errors='surrogate_then_replace'))
return module_context
def save_module_context(self, module_key, module_context):
connection = self._get_connection()
try:
connection.save_module_context(module_key, module_context)
except ConnectionError as exc:
self._module.fail_json(msg=to_text(exc, errors='surrogate_then_replace'))
return None
class Nxapi: class Nxapi:
@ -238,6 +256,7 @@ class Nxapi:
self._module = module self._module = module
self._nxapi_auth = None self._nxapi_auth = None
self._device_configs = {} self._device_configs = {}
self._module_context = {}
self._module.params['url_username'] = self._module.params['username'] self._module.params['url_username'] = self._module.params['username']
self._module.params['url_password'] = self._module.params['password'] self._module.params['url_password'] = self._module.params['password']
@ -464,6 +483,17 @@ class Nxapi:
result['network_api'] = 'nxapi' result['network_api'] = 'nxapi'
return result return result
def read_module_context(self, module_key):
if self._module_context.get(module_key):
return self._module_context[module_key]
return None
def save_module_context(self, module_key, module_context):
self._module_context[module_key] = module_context
return None
def is_json(cmd): def is_json(cmd):
return str(cmd).endswith('| json') return str(cmd).endswith('| json')
@ -589,3 +619,13 @@ def get_interface_type(interface):
return 'nve' return 'nve'
else: else:
return 'unknown' return 'unknown'
def read_module_context(module):
conn = get_connection(module)
return conn.read_module_context(module._name)
def save_module_context(module, module_context):
conn = get_connection(module)
return conn.save_module_context(module._name, module_context)

View file

@ -69,6 +69,38 @@ options:
- State of the logging configuration. - State of the logging configuration.
default: present default: present
choices: ['present', 'absent'] choices: ['present', 'absent']
event:
description:
- Link/trunk enable/default interface configuration logging
choices: ['link-enable', 'link-default', 'trunk-enable', 'trunk-default']
version_added: '2.8'
message:
description:
- Add interface description to interface syslogs.
Does not work with version 6.0 images using nxapi as a transport.
choices: ['add-interface-description']
version_added: '2.8'
file_size:
description:
- Set logfile size
version_added: '2.8'
facility_link_status:
description:
- Set logging facility ethpm link status.
Not idempotent with version 6.0 images.
choices: ['link-down-notif', 'link-down-error', 'link-up-notif', 'link-up-error']
version_added: '2.8'
timestamp:
description:
- Set logging timestamp format
choices: ['microseconds', 'milliseconds', 'seconds']
version_added: '2.8'
purge:
description:
- Remove any switch logging configuration that does not match what has been configured
type: bool
default: no
version_added: '2.8'
extends_documentation_fragment: nxos extends_documentation_fragment: nxos
""" """
@ -89,6 +121,12 @@ EXAMPLES = """
name: testfile name: testfile
dest_level: 3 dest_level: 3
state: present state: present
- name: Configure logging logfile with size
nxos_logging:
dest: logfile
name: testfile
dest_level: 3
file_size: 16384
- name: configure facility level logging - name: configure facility level logging
nxos_logging: nxos_logging:
facility: daemon facility: daemon
@ -111,7 +149,26 @@ EXAMPLES = """
nxos_logging: nxos_logging:
interface: mgmt0 interface: mgmt0
state: present state: present
- name: Purge nxos_logging configuration not managed by this playbook
nxos_logging:
purge: true
- name: Configure logging timestamp
nxos_logging:
timestamp: milliseconds
state: present
- name: Configure logging facility ethpm link status
nxos_logging:
facility: ethpm
facility_link_status: link-up-notif
state: present
- name: Configure logging message ethernet description
nxos_logging:
message: add-interface-description
state: present
- name: Configure logging event link enable
nxos_logging:
event: link-enable
state: present
- name: Configure logging using aggregate - name: Configure logging using aggregate
nxos_logging: nxos_logging:
aggregate: aggregate:
@ -133,11 +190,33 @@ commands:
""" """
import re import re
import copy
from ansible.module_utils.network.nxos.nxos import get_config, load_config, run_commands from ansible.module_utils.network.nxos.nxos import get_config, load_config, run_commands, save_module_context, read_module_context
from ansible.module_utils.network.nxos.nxos import nxos_argument_spec, check_args, normalize_interface from ansible.module_utils.network.nxos.nxos import nxos_argument_spec, check_args, normalize_interface
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
STATIC_CLI = {'link-enable': 'logging event link-status enable',
'link-default': 'logging event link-status default',
'trunk-enable': 'logging event trunk-status enable',
'trunk-default': 'logging event trunk-status default',
'microseconds': 'logging timestamp microseconds',
'milliseconds': 'logging timestamp milliseconds',
'seconds': 'logging timestamp seconds',
'link-up-error': 'link-up error',
'link-up-notif': 'link-up notif',
'link-down-error': 'link-down error',
'link-down-notif': 'link-down notif',
'add-interface-description': 'logging message interface type ethernet description'}
DEFAULT_LOGGING_LEVEL = {0: [],
1: [],
2: [],
3: ['adjmgr', 'arp', 'icmpv6', 'l2rib', 'netstack'],
4: [],
5: [],
6: [],
7: []}
DEST_GROUP = ['console', 'logfile', 'module', 'monitor', 'server'] DEST_GROUP = ['console', 'logfile', 'module', 'monitor', 'server']
@ -152,8 +231,11 @@ def map_obj_to_commands(updates):
if state == 'absent' and w in have: if state == 'absent' and w in have:
if w['facility'] is not None: if w['facility'] is not None:
if not w['dest']: if not w['dest'] and not w['facility_link_status'] and w['facility'] not in DEFAULT_LOGGING_LEVEL[int(w['facility_level'])]:
commands.append('no logging level {}'.format(w['facility'])) commands.append('no logging level {} {}'.format(w['facility'], w['facility_level']))
if w['facility_link_status'] and w['facility'] in ('ethpm'):
commands.append('no logging level {} {}'.format(w['facility'], STATIC_CLI[w['facility_link_status']]))
if w['name'] is not None: if w['name'] is not None:
commands.append('no logging logfile') commands.append('no logging logfile')
@ -167,6 +249,15 @@ def map_obj_to_commands(updates):
if w['interface']: if w['interface']:
commands.append('no logging source-interface') commands.append('no logging source-interface')
if w['event'] and w['event'] in STATIC_CLI:
commands.append('no ' + STATIC_CLI[w['event']])
if w['message'] and w['message'] in STATIC_CLI:
commands.append('no ' + STATIC_CLI[w['message']])
if w['timestamp'] and w['timestamp'] in STATIC_CLI:
commands.append('no ' + STATIC_CLI[w['timestamp']])
if state == 'present' and w not in have: if state == 'present' and w not in have:
if w['facility'] is None: if w['facility'] is None:
if w['dest']: if w['dest']:
@ -174,7 +265,12 @@ def map_obj_to_commands(updates):
commands.append('logging {} {}'.format(w['dest'], w['dest_level'])) commands.append('logging {} {}'.format(w['dest'], w['dest_level']))
elif w['dest'] == 'logfile': elif w['dest'] == 'logfile':
commands.append('logging logfile {} {}'.format(w['name'], w['dest_level'])) if w['file_size']:
commands.append('logging logfile {} {} size {}'.format(
w['name'], w['dest_level'], w['file_size']))
else:
commands.append('logging logfile {} {}'.format(
w['name'], w['dest_level']))
elif w['dest'] == 'server': elif w['dest'] == 'server':
if w['facility_level']: if w['facility_level']:
@ -208,6 +304,10 @@ def map_obj_to_commands(updates):
else: else:
commands.append('logging server {0} facility {1}'.format(w['remote_server'], commands.append('logging server {0} facility {1}'.format(w['remote_server'],
w['facility'])) w['facility']))
else:
if w['facility_link_status']:
commands.append('logging level {} {}'.format(
w['facility'], STATIC_CLI[w['facility_link_status']]))
else: else:
commands.append('logging level {} {}'.format(w['facility'], commands.append('logging level {} {}'.format(w['facility'],
w['facility_level'])) w['facility_level']))
@ -215,6 +315,15 @@ def map_obj_to_commands(updates):
if w['interface']: if w['interface']:
commands.append('logging source-interface {0} {1}'.format(*split_interface(w['interface']))) commands.append('logging source-interface {0} {1}'.format(*split_interface(w['interface'])))
if w['event'] and w['event'] in STATIC_CLI:
commands.append(STATIC_CLI[w['event']])
if w['message'] and w['message'] in STATIC_CLI:
commands.append(STATIC_CLI[w['message']])
if w['timestamp'] and w['timestamp'] in STATIC_CLI:
commands.append(STATIC_CLI[w['timestamp']])
return commands return commands
@ -224,6 +333,75 @@ def split_interface(interface):
return match.group(1), match.group(2) return match.group(1), match.group(2)
def parse_facility_link_status(line, facility, status):
facility_link_status = None
if facility is not None:
match = re.search(r'logging level {} {} (\S+)'.format(facility, status), line, re.M)
if match:
facility_link_status = status + "-" + match.group(1)
return facility_link_status
def parse_event_status(line, event):
status = None
match = re.search(r'logging event {} (\S+)'.format(event + '-status'), line, re.M)
if match:
state = match.group(1)
if state:
status = state
return status
def parse_event(line):
event = None
match = re.search(r'logging event (\S+)', line, re.M)
if match:
state = match.group(1)
if state == 'link-status':
event = 'link'
elif state == 'trunk-status':
event = 'trunk'
return event
def parse_message(line):
message = None
match = re.search(r'logging message interface type ethernet description', line, re.M)
if match:
message = 'add-interface-description'
return message
def parse_file_size(line, name, level):
file_size = None
match = re.search(r'logging logfile {} {} size (\S+)'.format(name, level), line, re.M)
if match:
file_size = match.group(1)
if file_size == '8192':
file_size = None
return file_size
def parse_timestamp(line):
timestamp = None
match = re.search(r'logging timestamp (\S+)', line, re.M)
if match:
timestamp = match.group(1)
return timestamp
def parse_name(line, dest): def parse_name(line, dest):
name = None name = None
@ -329,36 +507,76 @@ def parse_interface(line):
def map_config_to_obj(module): def map_config_to_obj(module):
obj = [] obj = []
data = get_config(module, flags=['| section logging']) data = get_config(module, flags=[' all | section logging'])
for line in data.split('\n'): for line in data.split('\n'):
match = re.search(r'logging (\S+)', line, re.M) if re.search(r'no (\S+)', line, re.M):
state = 'absent'
else:
state = 'present'
match = re.search(r'logging (\S+)', line, re.M)
if state == 'present' and match:
event_status = None
name = None
dest_level = None
dest = None
facility = None
remote_server = None
facility_link_status = None
file_size = None
facility_level = None
if match:
if match.group(1) in DEST_GROUP: if match.group(1) in DEST_GROUP:
dest = match.group(1) dest = match.group(1)
facility = None
name = parse_name(line, dest)
remote_server = parse_remote_server(line, dest)
dest_level = parse_dest_level(line, dest, name)
if dest == 'server': if dest == 'server':
facility = parse_facility(line) facility = parse_facility(line)
facility_level = parse_facility_level(line, facility, dest)
if dest == 'logfile':
file_size = parse_file_size(line, name, dest_level)
elif match.group(1) == 'level': elif match.group(1) == 'level':
match_facility = re.search(r'logging level (\S+)', line, re.M) match_facility = re.search(r'logging level (\S+)', line, re.M)
facility = match_facility.group(1) facility = match_facility.group(1)
dest = None
level = parse_facility_level(line, facility, dest)
if level.isdigit():
facility_level = level
else:
facility_link_status = parse_facility_link_status(line, facility, level)
elif match.group(1) == 'event' and state == 'present':
event = parse_event(line)
if event:
status = parse_event_status(line, event)
if status:
event_status = event + '-' + status
else:
continue
else: else:
dest = None pass
facility = None
obj.append({'dest': dest, obj.append({'dest': dest,
'remote_server': parse_remote_server(line, dest), 'remote_server': remote_server,
'use_vrf': parse_use_vrf(line, dest), 'use_vrf': parse_use_vrf(line, dest),
'name': parse_name(line, dest), 'name': name,
'facility': facility, 'facility': facility,
'dest_level': parse_dest_level(line, dest, parse_name(line, dest)), 'dest_level': dest_level,
'facility_level': parse_facility_level(line, facility, dest), 'facility_level': facility_level,
'interface': parse_interface(line)}) 'interface': parse_interface(line),
'facility_link_status': facility_link_status,
'event': event_status,
'file_size': file_size,
'message': parse_message(line),
'timestamp': parse_timestamp(line)})
cmd = [{'command': 'show logging | section enabled | section console', 'output': 'text'}, cmd = [{'command': 'show logging | section enabled | section console', 'output': 'text'},
{'command': 'show logging | section enabled | section monitor', 'output': 'text'}] {'command': 'show logging | section enabled | section monitor', 'output': 'text'}]
@ -383,7 +601,12 @@ def map_config_to_obj(module):
'dest_level': dest_level, 'dest_level': dest_level,
'facility_level': None, 'facility_level': None,
'use_vrf': None, 'use_vrf': None,
'interface': None}) 'interface': None,
'facility_link_status': None,
'event': None,
'file_size': None,
'message': None,
'timestamp': None})
return obj return obj
@ -399,7 +622,12 @@ def map_params_to_obj(module):
'facility': '', 'facility': '',
'dest_level': '', 'dest_level': '',
'facility_level': '', 'facility_level': '',
'interface': ''} 'interface': '',
'facility_link_status': None,
'event': None,
'file_size': None,
'message': None,
'timestamp': None}
for c in module.params['aggregate']: for c in module.params['aggregate']:
d = c.copy() d = c.copy()
@ -420,11 +648,15 @@ def map_params_to_obj(module):
if 'state' not in d: if 'state' not in d:
d['state'] = module.params['state'] d['state'] = module.params['state']
if d['file_size']:
d['file_size'] = str(d['file_size'])
obj.append(d) obj.append(d)
else: else:
dest_level = None dest_level = None
facility_level = None facility_level = None
file_size = None
if module.params['dest_level'] is not None: if module.params['dest_level'] is not None:
dest_level = str(module.params['dest_level']) dest_level = str(module.params['dest_level'])
@ -432,6 +664,9 @@ def map_params_to_obj(module):
if module.params['facility_level'] is not None: if module.params['facility_level'] is not None:
facility_level = str(module.params['facility_level']) facility_level = str(module.params['facility_level'])
if module.params['file_size'] is not None:
file_size = str(module.params['file_size'])
obj.append({ obj.append({
'dest': module.params['dest'], 'dest': module.params['dest'],
'remote_server': module.params['remote_server'], 'remote_server': module.params['remote_server'],
@ -441,11 +676,44 @@ def map_params_to_obj(module):
'dest_level': dest_level, 'dest_level': dest_level,
'facility_level': facility_level, 'facility_level': facility_level,
'interface': normalize_interface(module.params['interface']), 'interface': normalize_interface(module.params['interface']),
'state': module.params['state'] 'state': module.params['state'],
'facility_link_status': module.params['facility_link_status'],
'event': module.params['event'],
'message': module.params['message'],
'file_size': file_size,
'timestamp': module.params['timestamp']
}) })
return obj return obj
def merge_wants(wants, want):
if not wants:
wants = list()
for w in want:
w = copy.copy(w)
state = w['state']
del w['state']
if state == 'absent':
if w in wants:
wants.remove(w)
elif w not in wants:
wants.append(w)
return wants
def absent(h):
h['state'] = 'absent'
return h
def outliers(haves, wants):
wants = list(wants)
return [absent(h) for h in haves if not (h in wants or wants.append(h))]
def main(): def main():
""" main entry point for module execution """ main entry point for module execution
""" """
@ -458,8 +726,14 @@ def main():
dest_level=dict(type='int', aliases=['level']), dest_level=dict(type='int', aliases=['level']),
facility_level=dict(type='int'), facility_level=dict(type='int'),
interface=dict(), interface=dict(),
facility_link_status=dict(choices=['link-down-notif', 'link-down-error', 'link-up-notif', 'link-up-error']),
event=dict(choices=['link-enable', 'link-default', 'trunk-enable', 'trunk-default']),
message=dict(choices=['add-interface-description']),
file_size=dict(type='int'),
timestamp=dict(choices=['microseconds', 'milliseconds', 'seconds']),
state=dict(default='present', choices=['present', 'absent']), state=dict(default='present', choices=['present', 'absent']),
aggregate=dict(type='list') aggregate=dict(type='list'),
purge=dict(default=False, type='bool')
) )
argument_spec.update(nxos_argument_spec) argument_spec.update(nxos_argument_spec)
@ -479,6 +753,7 @@ def main():
result['warnings'] = warnings result['warnings'] = warnings
want = map_params_to_obj(module) want = map_params_to_obj(module)
merged_wants = merge_wants(read_module_context(module), want)
have = map_config_to_obj(module) have = map_config_to_obj(module)
commands = map_obj_to_commands((want, have)) commands = map_obj_to_commands((want, have))
@ -489,6 +764,16 @@ def main():
load_config(module, commands) load_config(module, commands)
result['changed'] = True result['changed'] = True
save_module_context(module, merged_wants)
if module.params.get('purge'):
pcommands = map_obj_to_commands((outliers(have, merged_wants), have))
if pcommands:
if not module.check_mode:
load_config(module, pcommands)
result['changed'] = True
result['commands'] += pcommands
module.exit_json(**result) module.exit_json(**result)

View file

@ -36,8 +36,20 @@ from ansible.plugins.connection.httpapi import Connection as HttpApi
class Cliconf(CliconfBase): class Cliconf(CliconfBase):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self._module_context = {}
super(Cliconf, self).__init__(*args, **kwargs) super(Cliconf, self).__init__(*args, **kwargs)
def read_module_context(self, module_key):
if self._module_context.get(module_key):
return self._module_context[module_key]
return None
def save_module_context(self, module_key, module_context):
self._module_context[module_key] = module_context
return None
def send_command(self, command, **kwargs): def send_command(self, command, **kwargs):
"""Executes a cli command and returns the results """Executes a cli command and returns the results
This method will execute the CLI command on the connection and return This method will execute the CLI command on the connection and return

View file

@ -48,7 +48,7 @@ class TerminalModule(TerminalBase):
re.compile(br"unknown command"), re.compile(br"unknown command"),
re.compile(br"user not present"), re.compile(br"user not present"),
re.compile(br"invalid (.+?)at '\^' marker", re.I), re.compile(br"invalid (.+?)at '\^' marker", re.I),
re.compile(br"baud rate of console should be (\d*) to increase severity level", re.I), re.compile(br"[B|b]aud rate of console should be.* (\d*) to increase [a-z]* level", re.I),
] ]
def on_become(self, passwd=None): def on_become(self, passwd=None):

View file

@ -78,6 +78,7 @@
- 'result.changed == true' - 'result.changed == true'
- '"logging console 3" in result.commands' - '"logging console 3" in result.commands'
- block:
- name: Logfile logging with level - name: Logfile logging with level
nxos_logging: &llog nxos_logging: &llog
dest: logfile dest: logfile
@ -92,12 +93,15 @@
- 'result.changed == true' - 'result.changed == true'
- '"logging logfile test 1" in result.commands' - '"logging logfile test 1" in result.commands'
- name: Logfile logging with level (idempotent) - name: Logfile logging with level (idempotent)
nxos_logging: *llog nxos_logging: *llog
register: result register: result
- assert: *false - assert: *false
when: platform is not search('N5K|N7K') and imagetag is not search("A8")
- name: Configure module with level - name: Configure module with level
nxos_logging: &molog nxos_logging: &molog
dest: module dest: module
@ -228,11 +232,22 @@
that: that:
- 'result.changed == true' - 'result.changed == true'
- '"no logging logfile" in result.commands' - '"no logging logfile" in result.commands'
- '"no logging level daemon" in result.commands' - '"no logging level daemon 4" in result.commands'
- '"no logging monitor" in result.commands' - '"no logging monitor" in result.commands'
- '"no logging module" in result.commands' - '"no logging module" in result.commands'
- '"no logging server test-syslogserver.com" in result.commands' - '"no logging server test-syslogserver.com" in result.commands'
- '"no logging source-interface" in result.commands' - '"no logging source-interface" in result.commands'
when: platform is not search('N5K|N7K') and imagetag is not search("A8")
- assert:
that:
- 'result.changed == true'
- '"no logging level daemon 4" in result.commands'
- '"no logging monitor" in result.commands'
- '"no logging module" in result.commands'
- '"no logging server test-syslogserver.com" in result.commands'
- '"no logging source-interface" in result.commands'
when: platform is search('N5K|N7K') or imagetag is search("A8")
- name: remove aggregate logging (idempotent) - name: remove aggregate logging (idempotent)
nxos_logging: *agg nxos_logging: *agg
@ -240,4 +255,260 @@
- assert: *false - assert: *false
- block:
- name: Configure Logging message
nxos_logging: &logm
message: add-interface-description
state: present
provider: "{{ connection }}"
register: result
- assert: &true
that:
- 'result.changed == true'
- name: Configure Logging message (idempotent)
nxos_logging: *logm
register: result
- assert: *false
- name: Remove Logging message
nxos_logging:
message: add-interface-description
state: absent
provider: "{{ connection }}"
register: result
- assert: *true
when: platform is not search('N5K') and imagetag is not search("A8")
- name: Logfile logging with level and size
nxos_logging: &llogs
dest: logfile
name: test
dest_level: 1
file_size: 16384
provider: "{{ connection }}"
state: present
register: result
- assert:
that:
- 'result.changed == true'
- '"logging logfile test 1 size 16384" in result.commands'
- name: Logfile logging with level and size (idempotent)
nxos_logging: *llogs
register: result
- assert: *false
- name: Remove logfile logging with level and size
nxos_logging:
dest: logfile
name: test
dest_level: 1
file_size: 16384
provider: "{{ connection }}"
state: absent
register: result
- assert: *true
- name: Set up logging event link enable
nxos_logging: &logle
event: link-enable
register: result
- assert:
that:
- 'result.changed == true'
- '"logging event link-status enable" in result.commands'
- name: Set up logging event link enable again (idempotent)
nxos_logging: *logle
register: result
- assert: *false
- name: Remove logging event link enable
nxos_logging: &rlogle
event: link-enable
state: absent
register: result
- assert: *true
- name: Remove logging event link enable again (idempotent)
nxos_logging: *rlogle
register: result
- assert: *false
- name: Set up logging event link default
nxos_logging: &logld
event: link-default
register: result
- assert:
that:
- 'result.changed == true'
- '"logging event link-status default" in result.commands'
- name: Set up logging event link default again (idempotent)
nxos_logging: *logld
register: result
- assert: *false
- name: Remove logging event link default
nxos_logging: &rlogld
event: link-default
state: absent
register: result
- assert: *true
- name: Remove logging event link default again (idempotent)
nxos_logging: *rlogld
register: result
- assert: *false
- name: Set up logging event trunk enable
nxos_logging: &logte
event: trunk-enable
register: result
- assert:
that:
- 'result.changed == true'
- '"logging event trunk-status enable" in result.commands'
- name: Set up logging event trunk enable again (idempotent)
nxos_logging: *logte
register: result
- assert: *false
- name: Remove logging event trunk enable
nxos_logging: &rlogte
event: trunk-enable
state: absent
register: result
- assert: *true
- name: Remove logging event trunk enable again (idempotent)
nxos_logging: *rlogte
register: result
- assert: *false
- name: Set up logging event trunk default
nxos_logging: &logtd
event: trunk-default
register: result
- assert:
that:
- 'result.changed == true'
- '"logging event trunk-status default" in result.commands'
- name: Set up logging event trunk default again (idempotent)
nxos_logging: *logtd
register: result
- assert: *false
- name: Remove logging event trunk default
nxos_logging: &rlogtd
event: trunk-default
state: absent
register: result
- assert: *true
- name: Remove logging event trunk default again (idempotent)
nxos_logging: *rlogtd
register: result
- assert: *false
- name: Set up Logging Timestamp
nxos_logging: &ltms
timestamp: microseconds
provider: "{{ connection }}"
state: present
register: result
- assert: *true
- name: Set up Logging Timestamp (idempotent)
nxos_logging: *ltms
register: result
- assert: *false
- name: Remove Logging Timestamp
nxos_logging:
timestamp: microseconds
state: absent
register: result
- assert: *true
- name: Set up Facility ethpm Link UP Error
nxos_logging: &felue
facility: ethpm
facility_link_status: link-up-error
provider: "{{ connection }}"
state: present
register: result
- assert: *true
- name: Set up Facility ethpm Link UP Error (idempotent)
nxos_logging: *felue
register: result
- assert: *false
- name: Remove Facility ethpm Link UP Error
nxos_logging:
facility: ethpm
facility_link_status: link-up-error
state: absent
register: result
- assert: *true
- name: Set up Facility ethpm Link DOWN Error
nxos_logging: &felde
facility: ethpm
facility_link_status: link-down-error
provider: "{{ connection }}"
state: present
register: result
- assert: *true
- name: Set up Facility ethpm Link DOWN Error (idempotent)
nxos_logging: *felde
register: result
- assert: *false
- name: Remove Facility ethpm Link DOWN Error
nxos_logging:
facility: ethpm
facility_link_status: link-down-error
state: absent
register: result
- assert: *true
- debug: msg="END connection={{ ansible_connection }} nxos_logging basic test" - debug: msg="END connection={{ ansible_connection }} nxos_logging basic test"

View file

@ -0,0 +1,109 @@
---
- debug: msg="START connection={{ ansible_connection }} nxos_logging purge test"
- block:
- name: Set up console logging
nxos_logging: &clog
dest: console
dest_level: 0
provider: "{{ connection }}"
state: present
register: result
- assert:
that:
- 'result.changed == true'
- '"logging console 0" in result.commands'
- name: Set up Logging Timestamp
nxos_logging: &ltms
timestamp: microseconds
provider: "{{ connection }}"
state: present
register: result
- assert:
that:
- 'result.changed == true'
- '"logging timestamp microseconds" in result.commands'
- name: Configure monitor with level
nxos_logging: &mlog
dest: monitor
dest_level: 3
provider: "{{ connection }}"
register: result
- assert:
that:
- 'result.changed == true'
- '"logging monitor 3" in result.commands'
- name: Configure facility with level
nxos_logging: &flog
facility: daemon
facility_level: 4
provider: "{{ connection }}"
register: result
- assert:
that:
- 'result.changed == true'
- '"logging level daemon 4" in result.commands'
- name: Configure logging level virtual-service 7 using nxos_config
nxos_config:
lines: logging level virtual-service 7
provider: "{{ connection }}"
register: result
- assert:
that:
- "result.changed == true"
- name: Purge the outliers
nxos_logging:
purge: yes
provider: "{{ connection }}"
register: result
- assert:
that:
- 'result.changed == true'
- '"no logging level virtual-service 7" in result.commands'
- block:
- name: Purge the outliers (idempotent)
nxos_logging:
purge: yes
provider: "{{ connection }}"
register: result
- assert:
that:
- 'result.changed == false'
when: imagetag is not search("A8")
- name: remove logging as collection tearDown
nxos_logging: &agg
aggregate:
- { dest: console, dest_level: 0 }
- { dest: monitor, dest_level: 3 }
- { timestamp: microseconds }
- { facility: daemon, facility_level: 4 }
provider: "{{ connection }}"
state: absent
register: result
- assert:
that:
- 'result.changed == true'
- '"no logging console" in result.commands'
- '"no logging timestamp microseconds" in result.commands'
- '"no logging level daemon 4" in result.commands'
- '"no logging monitor" in result.commands'
when: ansible_connection != "local"
- debug: msg="END connection={{ ansible_connection }} nxos_logging purge test"