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/cloudengine/ce_info_center_debug.py
Ansible Core Team aebc1b03fd Initial commit
2020-03-09 09:11:07 +00:00

617 lines
21 KiB
Python

#!/usr/bin/python
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: ce_info_center_debug
short_description: Manages information center debug configuration on HUAWEI CloudEngine switches.
description:
- Manages information center debug configurations on HUAWEI CloudEngine switches.
author:
- wangdezhuang (@QijunPan)
notes:
- This module requires the netconf system service be enabled on the remote device being managed.
- Recommended connection is C(netconf).
- This module also works with C(local) connections for legacy playbooks.
options:
state:
description:
- Specify desired state of the resource.
default: present
choices: ['present','absent']
debug_time_stamp:
description:
- Timestamp type of debugging information.
choices: ['date_boot', 'date_second', 'date_tenthsecond', 'date_millisecond', 'shortdate_second',
'shortdate_tenthsecond', 'shortdate_millisecond', 'formatdate_second', 'formatdate_tenthsecond',
'formatdate_millisecond']
module_name:
description:
- Module name of the rule.
The value is a string of 1 to 31 case-insensitive characters. The default value is default.
Please use lower-case letter, such as [aaa, acl, arp, bfd].
channel_id:
description:
- Number of a channel.
The value is an integer ranging from 0 to 9. The default value is 0.
debug_enable:
description:
- Whether a device is enabled to output debugging information.
default: no_use
choices: ['no_use','true','false']
debug_level:
description:
- Debug level permitted to output.
choices: ['emergencies', 'alert', 'critical', 'error', 'warning', 'notification',
'informational', 'debugging']
'''
EXAMPLES = '''
- name: CloudEngine info center debug test
hosts: cloudengine
connection: local
gather_facts: no
vars:
cli:
host: "{{ inventory_hostname }}"
port: "{{ ansible_ssh_port }}"
username: "{{ username }}"
password: "{{ password }}"
transport: cli
tasks:
- name: "Config debug time stamp"
ce_info_center_debug:
state: present
debug_time_stamp: date_boot
provider: "{{ cli }}"
- name: "Undo debug time stamp"
ce_info_center_debug:
state: absent
debug_time_stamp: date_boot
provider: "{{ cli }}"
- name: "Config debug module log level"
ce_info_center_debug:
state: present
module_name: aaa
channel_id: 1
debug_enable: true
debug_level: error
provider: "{{ cli }}"
- name: "Undo debug module log level"
ce_info_center_debug:
state: absent
module_name: aaa
channel_id: 1
debug_enable: true
debug_level: error
provider: "{{ cli }}"
'''
RETURN = '''
changed:
description: check to see if a change was made on the device
returned: always
type: bool
sample: true
proposed:
description: k/v pairs of parameters passed into module
returned: always
type: dict
sample: {"state": "present", "debug_time_stamp": "date_boot"}
existing:
description: k/v pairs of existing aaa server
returned: always
type: dict
sample: {"debugTimeStamp": "DATE_MILLISECOND"}
end_state:
description: k/v pairs of aaa params after module execution
returned: always
type: dict
sample: {"debugTimeStamp": "DATE_BOOT"}
updates:
description: command sent to the device
returned: always
type: list
sample: ["info-center timestamp debugging boot"]
'''
from xml.etree import ElementTree
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.network.cloudengine.ce import get_nc_config, set_nc_config, ce_argument_spec
# get info center debug global
CE_GET_DEBUG_GLOBAL_HEADER = """
<filter type="subtree">
<syslog xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<globalParam>
"""
CE_GET_DEBUG_GLOBAL_TAIL = """
</globalParam>
</syslog>
</filter>
"""
# merge info center debug global
CE_MERGE_DEBUG_GLOBAL_HEADER = """
<config>
<syslog xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<globalParam operation="merge">
"""
CE_MERGE_DEBUG_GLOBAL_TAIL = """
</globalParam>
</syslog>
</config>
"""
# get info center debug source
CE_GET_DEBUG_SOURCE_HEADER = """
<filter type="subtree">
<syslog xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<icSources>
<icSource>
"""
CE_GET_DEBUG_SOURCE_TAIL = """
</icSource>
</icSources>
</syslog>
</filter>
"""
# merge info center debug source
CE_MERGE_DEBUG_SOURCE_HEADER = """
<config>
<syslog xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<icSources>
<icSource operation="merge">
"""
CE_MERGE_DEBUG_SOURCE_TAIL = """
</icSource>
</icSources>
</syslog>
</config>
"""
# delete info center debug source
CE_DELETE_DEBUG_SOURCE_HEADER = """
<config>
<syslog xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<icSources>
<icSource operation="delete">
"""
CE_DELETE_DEBUG_SOURCE_TAIL = """
</icSource>
</icSources>
</syslog>
</config>
"""
TIME_STAMP_DICT = {"date_boot": "boot",
"date_second": "date precision-time second",
"date_tenthsecond": "date precision-time tenth-second",
"date_millisecond": "date precision-time millisecond",
"shortdate_second": "short-date precision-time second",
"shortdate_tenthsecond": "short-date precision-time tenth-second",
"shortdate_millisecond": "short-date precision-time millisecond",
"formatdate_second": "format-date precision-time second",
"formatdate_tenthsecond": "format-date precision-time tenth-second",
"formatdate_millisecond": "format-date precision-time millisecond"}
CHANNEL_DEFAULT_DBG_STATE = {"0": "true",
"1": "true",
"2": "false",
"3": "false",
"4": "false",
"5": "false",
"6": "false",
"7": "false",
"8": "false",
"9": "false"}
CHANNEL_DEFAULT_DBG_LEVEL = {"0": "debugging",
"1": "debugging",
"2": "debugging",
"3": "debugging",
"4": "debugging",
"5": "debugging",
"6": "debugging",
"7": "debugging",
"8": "debugging",
"9": "debugging"}
class InfoCenterDebug(object):
""" Manages info center debug configuration """
def __init__(self, **kwargs):
""" Init function """
# argument spec
argument_spec = kwargs["argument_spec"]
self.spec = argument_spec
self.module = AnsibleModule(argument_spec=self.spec, supports_check_mode=True)
# module args
self.state = self.module.params['state']
self.debug_time_stamp = self.module.params['debug_time_stamp'] or None
self.module_name = self.module.params['module_name'] or None
self.channel_id = self.module.params['channel_id'] or None
self.debug_enable = self.module.params['debug_enable']
self.debug_level = self.module.params['debug_level'] or None
# cur config
self.cur_global_cfg = dict()
self.cur_source_cfg = dict()
# state
self.changed = False
self.updates_cmd = list()
self.results = dict()
self.proposed = dict()
self.existing = dict()
self.end_state = dict()
def check_global_args(self):
""" Check global args """
need_cfg = False
find_flag = False
self.cur_global_cfg["global_cfg"] = []
if self.debug_time_stamp:
conf_str = CE_GET_DEBUG_GLOBAL_HEADER
conf_str += "<debugTimeStamp></debugTimeStamp>"
conf_str += CE_GET_DEBUG_GLOBAL_TAIL
xml_str = get_nc_config(self.module, conf_str)
if "<data/>" in xml_str:
find_flag = False
else:
xml_str = xml_str.replace('\r', '').replace('\n', '').\
replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\
replace('xmlns="http://www.huawei.com/netconf/vrp"', "")
root = ElementTree.fromstring(xml_str)
global_cfg = root.findall("syslog/globalParam")
if global_cfg:
for tmp in global_cfg:
tmp_dict = dict()
for site in tmp:
if site.tag in ["debugTimeStamp"]:
tmp_dict[site.tag] = site.text
self.cur_global_cfg["global_cfg"].append(tmp_dict)
if self.cur_global_cfg["global_cfg"]:
for tmp in self.cur_global_cfg["global_cfg"]:
find_flag = True
if tmp.get("debugTimeStamp").lower() != self.debug_time_stamp:
find_flag = False
if find_flag:
break
else:
find_flag = False
if self.state == "present":
need_cfg = bool(not find_flag)
else:
need_cfg = bool(find_flag)
self.cur_global_cfg["need_cfg"] = need_cfg
def check_source_args(self):
""" Check source args """
need_cfg = False
find_flag = False
self.cur_source_cfg["source_cfg"] = []
if self.module_name:
if len(self.module_name) < 1 or len(self.module_name) > 31:
self.module.fail_json(
msg='Error: The module_name is out of [1 - 31].')
if not self.channel_id:
self.module.fail_json(
msg='Error: Please input channel_id at the same time.')
if self.channel_id:
if self.channel_id.isdigit():
if int(self.channel_id) < 0 or int(self.channel_id) > 9:
self.module.fail_json(
msg='Error: The value of channel_id is out of [0 - 9].')
else:
self.module.fail_json(
msg='Error: The channel_id is not digit.')
conf_str = CE_GET_DEBUG_SOURCE_HEADER
if self.module_name != "default":
conf_str += "<moduleName>%s</moduleName>" % self.module_name.upper()
else:
conf_str += "<moduleName>default</moduleName>"
if self.channel_id:
conf_str += "<icChannelId></icChannelId>"
if self.debug_enable != 'no_use':
conf_str += "<dbgEnFlg></dbgEnFlg>"
if self.debug_level:
conf_str += "<dbgEnLevel></dbgEnLevel>"
conf_str += CE_GET_DEBUG_SOURCE_TAIL
xml_str = get_nc_config(self.module, conf_str)
if "<data/>" in xml_str:
find_flag = False
else:
xml_str = xml_str.replace('\r', '').replace('\n', '').\
replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\
replace('xmlns="http://www.huawei.com/netconf/vrp"', "")
root = ElementTree.fromstring(xml_str)
source_cfg = root.findall("syslog/icSources/icSource")
if source_cfg:
for tmp in source_cfg:
tmp_dict = dict()
for site in tmp:
if site.tag in ["moduleName", "icChannelId", "dbgEnFlg", "dbgEnLevel"]:
tmp_dict[site.tag] = site.text
self.cur_source_cfg["source_cfg"].append(tmp_dict)
if self.cur_source_cfg["source_cfg"]:
for tmp in self.cur_source_cfg["source_cfg"]:
find_flag = True
if self.module_name and tmp.get("moduleName").lower() != self.module_name.lower():
find_flag = False
if self.channel_id and tmp.get("icChannelId") != self.channel_id:
find_flag = False
if self.debug_enable != 'no_use' and tmp.get("dbgEnFlg") != self.debug_enable:
find_flag = False
if self.debug_level and tmp.get("dbgEnLevel") != self.debug_level:
find_flag = False
if find_flag:
break
else:
find_flag = False
if self.state == "present":
need_cfg = bool(not find_flag)
else:
need_cfg = bool(find_flag)
self.cur_source_cfg["need_cfg"] = need_cfg
def get_proposed(self):
""" Get proposed """
self.proposed["state"] = self.state
if self.debug_time_stamp:
self.proposed["debug_time_stamp"] = self.debug_time_stamp
if self.module_name:
self.proposed["module_name"] = self.module_name
if self.channel_id:
self.proposed["channel_id"] = self.channel_id
if self.debug_enable != 'no_use':
self.proposed["debug_enable"] = self.debug_enable
if self.debug_level:
self.proposed["debug_level"] = self.debug_level
def get_existing(self):
""" Get existing """
if self.cur_global_cfg["global_cfg"]:
self.existing["global_cfg"] = self.cur_global_cfg["global_cfg"]
if self.cur_source_cfg["source_cfg"]:
self.existing["source_cfg"] = self.cur_source_cfg["source_cfg"]
def get_end_state(self):
""" Get end state """
self.check_global_args()
if self.cur_global_cfg["global_cfg"]:
self.end_state["global_cfg"] = self.cur_global_cfg["global_cfg"]
self.check_source_args()
if self.cur_source_cfg["source_cfg"]:
self.end_state["source_cfg"] = self.cur_source_cfg["source_cfg"]
def merge_debug_global(self):
""" Merge debug global """
conf_str = CE_MERGE_DEBUG_GLOBAL_HEADER
if self.debug_time_stamp:
conf_str += "<debugTimeStamp>%s</debugTimeStamp>" % self.debug_time_stamp.upper()
conf_str += CE_MERGE_DEBUG_GLOBAL_TAIL
recv_xml = set_nc_config(self.module, conf_str)
if "<ok/>" not in recv_xml:
self.module.fail_json(msg='Error: Merge debug global failed.')
if self.debug_time_stamp:
cmd = "info-center timestamp debugging " + TIME_STAMP_DICT.get(self.debug_time_stamp)
self.updates_cmd.append(cmd)
self.changed = True
def delete_debug_global(self):
""" Delete debug global """
conf_str = CE_MERGE_DEBUG_GLOBAL_HEADER
if self.debug_time_stamp:
conf_str += "<debugTimeStamp>DATE_MILLISECOND</debugTimeStamp>"
conf_str += CE_MERGE_DEBUG_GLOBAL_TAIL
recv_xml = set_nc_config(self.module, conf_str)
if "<ok/>" not in recv_xml:
self.module.fail_json(msg='Error: delete debug global failed.')
if self.debug_time_stamp:
cmd = "undo info-center timestamp debugging"
self.updates_cmd.append(cmd)
self.changed = True
def merge_debug_source(self):
""" Merge debug source """
conf_str = CE_MERGE_DEBUG_SOURCE_HEADER
if self.module_name:
conf_str += "<moduleName>%s</moduleName>" % self.module_name
if self.channel_id:
conf_str += "<icChannelId>%s</icChannelId>" % self.channel_id
if self.debug_enable != 'no_use':
conf_str += "<dbgEnFlg>%s</dbgEnFlg>" % self.debug_enable
if self.debug_level:
conf_str += "<dbgEnLevel>%s</dbgEnLevel>" % self.debug_level
conf_str += CE_MERGE_DEBUG_SOURCE_TAIL
recv_xml = set_nc_config(self.module, conf_str)
if "<ok/>" not in recv_xml:
self.module.fail_json(msg='Error: Merge debug source failed.')
cmd = "info-center source"
if self.module_name:
cmd += " %s" % self.module_name
if self.channel_id:
cmd += " channel %s" % self.channel_id
if self.debug_enable != 'no_use':
if self.debug_enable == "true":
cmd += " debug state on"
else:
cmd += " debug state off"
if self.debug_level:
cmd += " level %s" % self.debug_level
self.updates_cmd.append(cmd)
self.changed = True
def delete_debug_source(self):
""" Delete debug source """
if self.debug_enable == 'no_use' and not self.debug_level:
conf_str = CE_DELETE_DEBUG_SOURCE_HEADER
if self.module_name:
conf_str += "<moduleName>%s</moduleName>" % self.module_name
if self.channel_id:
conf_str += "<icChannelId>%s</icChannelId>" % self.channel_id
conf_str += CE_DELETE_DEBUG_SOURCE_TAIL
else:
conf_str = CE_MERGE_DEBUG_SOURCE_HEADER
if self.module_name:
conf_str += "<moduleName>%s</moduleName>" % self.module_name
if self.channel_id:
conf_str += "<icChannelId>%s</icChannelId>" % self.channel_id
if self.debug_enable != 'no_use':
conf_str += "<dbgEnFlg>%s</dbgEnFlg>" % CHANNEL_DEFAULT_DBG_STATE.get(self.channel_id)
if self.debug_level:
conf_str += "<dbgEnLevel>%s</dbgEnLevel>" % CHANNEL_DEFAULT_DBG_LEVEL.get(self.channel_id)
conf_str += CE_MERGE_DEBUG_SOURCE_TAIL
recv_xml = set_nc_config(self.module, conf_str)
if "<ok/>" not in recv_xml:
self.module.fail_json(msg='Error: Delete debug source failed.')
cmd = "undo info-center source"
if self.module_name:
cmd += " %s" % self.module_name
if self.channel_id:
cmd += " channel %s" % self.channel_id
if self.debug_enable != 'no_use':
cmd += " debug state"
if self.debug_level:
cmd += " level"
self.updates_cmd.append(cmd)
self.changed = True
def work(self):
""" work function """
self.check_global_args()
self.check_source_args()
self.get_proposed()
self.get_existing()
if self.state == "present":
if self.cur_global_cfg["need_cfg"]:
self.merge_debug_global()
if self.cur_source_cfg["need_cfg"]:
self.merge_debug_source()
else:
if self.cur_global_cfg["need_cfg"]:
self.delete_debug_global()
if self.cur_source_cfg["need_cfg"]:
self.delete_debug_source()
self.get_end_state()
self.results['changed'] = self.changed
self.results['proposed'] = self.proposed
self.results['existing'] = self.existing
self.results['end_state'] = self.end_state
self.results['updates'] = self.updates_cmd
self.module.exit_json(**self.results)
def main():
""" Module main """
argument_spec = dict(
state=dict(choices=['present', 'absent'], default='present'),
debug_time_stamp=dict(choices=['date_boot', 'date_second', 'date_tenthsecond',
'date_millisecond', 'shortdate_second', 'shortdate_tenthsecond',
'shortdate_millisecond', 'formatdate_second', 'formatdate_tenthsecond',
'formatdate_millisecond']),
module_name=dict(type='str'),
channel_id=dict(type='str'),
debug_enable=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
debug_level=dict(choices=['emergencies', 'alert', 'critical', 'error', 'warning', 'notification',
'informational', 'debugging'])
)
argument_spec.update(ce_argument_spec)
module = InfoCenterDebug(argument_spec=argument_spec)
module.work()
if __name__ == '__main__':
main()