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

252 lines
9.6 KiB
Python
Raw Normal View History

2020-03-09 10:11:07 +01:00
#!/usr/bin/python
#
# Copyright: Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
module: onyx_syslog_files
author: "Anas Shami (@anass)"
short_description: Configure file management syslog module
description:
- This module provides declarative management of syslog
on Mellanox ONYX network devices.
notes:
options:
debug:
description:
- Configure settings for debug log files
type: bool
default: False
delete_group:
description:
- Delete certain log files
choices: ['current', 'oldest']
type: str
rotation:
description:
- rotation related attributes
type: dict
suboptions:
frequency:
description:
- Rotate log files on a fixed time-based schedule
choices: ['daily', 'weekly', 'monthly']
type: str
force:
description:
- force an immediate rotation of log files
type: bool
max_num:
description:
- Sepcify max_num of old log files to keep
type: int
size:
description:
- Rotate files when they pass max size
type: float
size_pct:
description:
- Rotatoe files when they pass percent of HD
type: float
upload_url:
description:
- upload local log files to remote host (ftp, scp, sftp, tftp) with format protocol://username[:password]@server/path
type: str
upload_file:
description:
- Upload compressed log file (current or filename)
type: str
'''
EXAMPLES = """
- name: syslog delete old files
- onyx_syslog_files:
delete_group: oldest
- name: syslog upload file
- onyx_syslog_files:
upload_url: scp://username:password@hostnamepath/filename
upload_file: current
- name: syslog rotation force, frequency and max number
- onyx_syslog_files:
rotation:
force: true
max_num: 30
frequency: daily
size: 128
"""
RETURN = """
commands:
description: The list of configuration mode commands to send to the device.
returned: always
type: list
sample:
- logging files delete current
- logging files rotate criteria
- logging files upload current url
"""
import re
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.network.onyx.onyx import show_cmd
from ansible_collections.community.general.plugins.module_utils.network.onyx.onyx import BaseOnyxModule
class OnyxSyslogFilesModule(BaseOnyxModule):
MAX_FILES = 999999
URL_REGEX = re.compile(
r'^(ftp|scp|ftps):\/\/[a-z0-9\.]*:(.*)@(.*):([a-zA-Z\/\/])*$')
FREQUANCIES = ['daily', 'weekly', 'monthly']
ROTATION_KEYS = ['frequency', 'max_num', 'size', 'size_pct', 'force']
ROTATION_CMDS = {'size': 'logging {0} rotation criteria size {1}',
'frequency': 'logging {0} rotation criteria frequency {1}',
'max_num': 'logging {0} rotation max-num {1}',
'size_pct': 'logging {0} rotation criteria size-pct {1}',
'force': 'logging {0} rotation force'}
def init_module(self):
"""" Ansible module initialization
"""
rotation_spec = dict(frequency=dict(choices=self.FREQUANCIES),
max_num=dict(type="int"),
force=dict(type="bool"),
size=dict(type="float"),
size_pct=dict(type="float"))
element_spec = dict(delete_group=dict(choices=['oldest', 'current']),
rotation=dict(type="dict", options=rotation_spec),
upload_file=dict(type="str"),
upload_url=dict(type="str"),
debug=dict(type="bool", default=False))
argument_spec = dict()
argument_spec.update(element_spec)
self._module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
required_together=[['upload_file', 'upload_url']])
def validate_rotation(self, rotation):
size_pct = rotation.get('size_pct', None)
max_num = rotation.get('max_num', None)
if size_pct is not None and (float(size_pct) < 0 or float(size_pct) > 100):
self._module.fail_json(
msg='logging size_pct must be in range 0-100')
elif max_num is not None and (int(max_num) < 0 or int(max_num) > self.MAX_FILES):
self._module.fail_json(
msg='logging max_num must be positive number less than {0}'.format(self.MAX_FILES))
def validate_upload_url(self, upload_url):
check = self.URL_REGEX.match(upload_url)
if upload_url and not check:
self._module.fail_json(
msg='Invalid url, make sure that you use "[ftp, scp, tftp, sftp]://username:password@hostname:/location" format')
def show_logging(self):
show_logging = show_cmd(self._module, "show logging", json_fmt=True, fail_on_error=False)
running_config = show_cmd(self._module, "show running-config | include .*logging.*debug-files.*", json_fmt=True, fail_on_error=False)
if len(show_logging) > 0:
show_logging[0]['debug'] = running_config['Lines'] if 'Lines' in running_config else []
else:
show_logging = [{
'debug': running_config['Lines'] if 'Lines' in running_config else []
}]
return show_logging
def load_current_config(self):
self._current_config = dict()
current_config = self.show_logging()[0]
freq = current_config.get('Log rotation frequency') # daily (Once per day at midnight)
size = current_config.get('Log rotation size threshold') # 19.07 megabytes or 10.000% of partition (987.84 megabytes)
max_num = current_config.get('Number of archived log files to keep')
if freq is not None:
freq_str = freq.split()[0]
self._current_config['frequency'] = freq_str
if size is not None:
size_arr = size.split(' ')
if '%' in size:
size_pct_value = size_arr[0].replace('%', '')
self._current_config['size_pct'] = float(size_pct_value)
size_value = re.sub(r'(\(|\)|megabytes)', '', size_arr[-2]).strip()
self._current_config['size'] = float(size_value)
else:
size_value = size_arr[0]
self._current_config['size'] = float(size_value)
if max_num is not None:
self._current_config['max_num'] = int(max_num)
'''debug params'''
for line in current_config['debug']:
if 'size' in line:
self._current_config['debug_size'] = float(line.split(' ')[-1])
elif 'frequency' in line:
self._current_config['debug_frequency'] = line.split(' ')[-1]
elif 'size-pct' in line:
self._current_config['debug_size_pct'] = float(line.split(' ')[-1])
elif 'max-num' in line:
self._current_config['debug_max_num'] = int(line.split(' ')[-1])
def get_required_config(self):
self._required_config = dict()
required_config = dict()
module_params = self._module.params
delete_group = module_params.get('delete_group')
upload_file = module_params.get('upload_file')
rotation = module_params.get('rotation')
if delete_group:
required_config['delete_group'] = delete_group
if upload_file:
required_config.update({'upload_file': upload_file,
'upload_url': module_params.get('upload_url')})
if rotation:
required_config['rotation'] = rotation
required_config['debug'] = module_params['debug']
self.validate_param_values(required_config)
self._required_config = required_config
def generate_commands(self):
required_config = self._required_config
current_config = self._current_config
logging_files_type = 'debug-files' if required_config['debug'] else 'files'
debug_prefix = 'debug_' if required_config['debug'] else ''
rotation = required_config.get('rotation')
if rotation:
for key in rotation:
if rotation.get(key) and current_config.get(debug_prefix + key) != rotation.get(key):
cmd = self.ROTATION_CMDS[key].format(logging_files_type, rotation[key]) if key != 'force' else\
self.ROTATION_CMDS[key].format(logging_files_type)
self._commands.append(cmd)
delete_group = required_config.get('delete_group')
if delete_group:
self._commands.append('logging {0} delete {1}'.format(logging_files_type,
delete_group))
upload_file = required_config.get('upload_file')
if upload_file:
self._commands.append('logging {0} upload {1} {2}'.format(logging_files_type,
upload_file, required_config.get('upload_url')))
def main():
""" main entry point for module execution
"""
OnyxSyslogFilesModule.main()
if __name__ == '__main__':
main()