#!/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 . # 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_global short_description: Manages outputting logs on HUAWEI CloudEngine switches. description: - This module offers the ability to be output to the log buffer, log file, console, terminal, or log host on HUAWEI CloudEngine switches. author: - Li Yanfeng (@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: info_center_enable: description: - Whether the info-center function is enabled. The value is of the Boolean type. choices: ['true','false'] packet_priority: description: - Set the priority of the syslog packet.The value is an integer ranging from 0 to 7. The default value is 0. suppress_enable: description: - Whether a device is enabled to suppress duplicate statistics. The value is of the Boolean type. choices: [ 'false', 'true' ] logfile_max_num: description: - Maximum number of log files of the same type. The default value is 200. - The value range for log files is[3, 500], for security files is [1, 3],and for operation files is [1, 7]. logfile_max_size: description: - Maximum size (in MB) of a log file. The default value is 32. - The value range for log files is [4, 8, 16, 32], for security files is [1, 4], - and for operation files is [1, 4]. default: 32 choices: ['4', '8', '16', '32'] channel_id: description: - Number for channel. The value is an integer ranging from 0 to 9. The default value is 0. channel_cfg_name: description: - Channel name.The value is a string of 1 to 30 case-sensitive characters. The default value is console. default: console channel_out_direct: description: - Direction of information output. choices: ['console','monitor','trapbuffer','logbuffer','snmp','logfile'] filter_feature_name: description: - Feature name of the filtered log. The value is a string of 1 to 31 case-insensitive characters. filter_log_name: description: - Name of the filtered log. The value is a string of 1 to 63 case-sensitive characters. ip_type: description: - Log server address type, IPv4 or IPv6. choices: ['ipv4','ipv6'] server_ip: description: - Log server address, IPv4 or IPv6 type. The value is a string of 0 to 255 characters. The value can be an valid IPv4 or IPv6 address. server_domain: description: - Server name. The value is a string of 1 to 255 case-sensitive characters. is_default_vpn: description: - Use the default VPN or not. type: bool default: 'no' vrf_name: description: - VPN name on a log server. The value is a string of 1 to 31 case-sensitive characters. The default value is _public_. level: description: - Level of logs saved on a log server. choices: ['emergencies','alert','critical','error','warning','notification','informational','debugging'] server_port: description: - Number of a port sending logs.The value is an integer ranging from 1 to 65535. For UDP, the default value is 514. For TCP, the default value is 601. For TSL, the default value is 6514. facility: description: - Log record tool. choices: ['local0','local1','local2','local3','local4','local5','local6','local7'] channel_name: description: - Channel name. The value is a string of 1 to 30 case-sensitive characters. timestamp: description: - Log server timestamp. The value is of the enumerated type and case-sensitive. choices: ['UTC', 'localtime'] transport_mode: description: - Transport mode. The value is of the enumerated type and case-sensitive. choices: ['tcp','udp'] ssl_policy_name: description: - SSL policy name. The value is a string of 1 to 23 case-sensitive characters. source_ip: description: - Log source ip address, IPv4 or IPv6 type. The value is a string of 0 to 255. The value can be an valid IPv4 or IPv6 address. state: description: - Specify desired state of the resource. default: present choices: ['present','absent'] ''' EXAMPLES = ''' - name: info center global module 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 info-center enable ce_info_center_global: info_center_enable: true state: present provider: "{{ cli }}" - name: Config statistic-suppress enable ce_info_center_global: suppress_enable: true state: present provider: "{{ cli }}" - name: Config info-center syslog packet-priority 1 ce_info_center_global: packet_priority: 2 state: present provider: "{{ cli }}" - name: Config info-center channel 1 name aaa ce_info_center_global: channel_id: 1 channel_cfg_name: aaa state: present provider: "{{ cli }}" - name: Config info-center logfile size 10 ce_info_center_global: logfile_max_num: 10 state: present provider: "{{ cli }}" - name: Config info-center console channel 1 ce_info_center_global: channel_out_direct: console channel_id: 1 state: present provider: "{{ cli }}" - name: Config info-center filter-id bymodule-alias snmp snmp_ipunlock ce_info_center_global: filter_feature_name: SNMP filter_log_name: SNMP_IPLOCK state: present provider: "{{ cli }}" - name: Config info-center max-logfile-number 16 ce_info_center_global: logfile_max_size: 16 state: present provider: "{{ cli }}" - name: Config syslog loghost domain. ce_info_center_global: server_domain: aaa vrf_name: aaa channel_id: 1 transport_mode: tcp facility: local4 server_port: 100 level: alert timestamp: UTC state: present provider: "{{ cli }}" ''' RETURN = ''' proposed: description: k/v pairs of parameters passed into module returned: always type: dict sample: {"channel_id": "1", "facility": "local4", "is_default_vpn": True, "level": "alert", "server_domain": "aaa", "server_port": "100", "state": "present", "timestamp": "localtime", "transport_mode": "tcp"} existing: description: k/v pairs of existing rollback returned: always type: dict sample: "server_domain_info": [ { "chnlId": "1", "chnlName": "monitor", "facility": "local4", "isBriefFmt": "false", "isDefaultVpn": "false", "level": "alert", "serverDomain": "aaa", "serverPort": "100", "sourceIP": "0.0.0.0", "sslPolicyName": "gmc", "timestamp": "UTC", "transportMode": "tcp", "vrfName": "aaa" } ] end_state: description: k/v pairs of aaa params after module execution returned: always type: dict sample: "server_domain_info": [ { "chnlId": "1", "chnlName": "monitor", "facility": "local4", "isBriefFmt": "false", "isDefaultVpn": "true", "level": "alert", "serverDomain": "aaa", "serverPort": "100", "sourceIP": "0.0.0.0", "sslPolicyName": null, "timestamp": "localtime", "transportMode": "tcp", "vrfName": "_public_" }, { "chnlId": "1", "chnlName": "monitor", "facility": "local4", "isBriefFmt": "false", "isDefaultVpn": "false", "level": "alert", "serverDomain": "aaa", "serverPort": "100", "sourceIP": "0.0.0.0", "sslPolicyName": "gmc", "timestamp": "UTC", "transportMode": "tcp", "vrfName": "aaa" } ] updates: description: command sent to the device returned: always type: list sample: ["info-center loghost domain aaa level alert port 100 facility local4 channel 1 localtime transport tcp"] changed: description: check to see if a change was made on the device returned: always type: bool sample: true ''' from xml.etree import ElementTree from ansible.module_utils.basic import AnsibleModule from ansible_collections.community.general.plugins.module_utils.network.cloudengine.ce import ce_argument_spec, get_nc_config, set_nc_config, check_ip_addr CE_NC_GET_CENTER_GLOBAL_INFO_HEADER = """ """ CE_NC_GET_CENTER_GLOBAL_INFO_TAIL = """ """ CE_NC_MERGE_CENTER_GLOBAL_INFO_HEADER = """ """ CE_NC_MERGE_CENTER_GLOBAL_INFO_TAIL = """ """ CE_NC_GET_LOG_FILE_INFO_HEADER = """ """ CE_NC_GET_LOG_FILE_INFO_TAIL = """ """ CE_NC_MERGE_LOG_FILE_INFO_HEADER = """ """ CE_NC_MERGE_LOG_FILE_INFO_TAIL = """ """ CE_NC_GET_CHANNEL_INFO = """ %s """ CE_NC_MERGE_CHANNEL_INFO_HEADER = """ """ CE_NC_MERGE_CHANNEL_INFO_TAIL = """ """ CE_NC_GET_CHANNEL_DIRECT_INFO = """ %s """ CE_NC_MERGE_CHANNEL_DIRECT_HEADER = """ """ CE_NC_MERGE_CHANNEL_DIRECT_TAIL = """ """ CE_NC_GET_FILTER_INFO = """ """ CE_NC_CREATE_CHANNEL_FILTER_HEADER = """ """ CE_NC_CREATE_CHANNEL_FILTER_TAIL = """ """ CE_NC_DELETE_CHANNEL_FILTER_HEADER = """ """ CE_NC_DELETE_CHANNEL_FILTER_TAIL = """ """ CE_NC_GET_SERVER_IP_INFO_HEADER = """ %s %s %s %s """ CE_NC_GET_SERVER_IP_INFO_TAIL = """ """ CE_NC_MERGE_SERVER_IP_INFO_HEADER = """ %s %s %s %s """ CE_NC_MERGE_SERVER_IP_INFO_TAIL = """ """ CE_NC_DELETE_SERVER_IP_INFO_HEADER = """ %s %s %s %s """ CE_NC_DELETE_SERVER_IP_INFO_TAIL = """ """ CE_NC_GET_SERVER_DNS_INFO_HEADER = """ """ CE_NC_GET_SERVER_DNS_INFO_TAIL = """ """ CE_NC_MERGE_SERVER_DNS_INFO_HEADER = """ %s %s %s """ CE_NC_MERGE_SERVER_DNS_INFO_TAIL = """ """ CE_NC_DELETE_SERVER_DNS_INFO_HEADER = """ %s %s %s """ CE_NC_DELETE_SERVER_DNS_INFO_TAIL = """ """ def get_out_direct_default(out_direct): """get default out direct""" outdict = {"console": "1", "monitor": "2", "trapbuffer": "3", "logbuffer": "4", "snmp": "5", "logfile": "6"} channel_id_default = outdict.get(out_direct) return channel_id_default def get_channel_name_default(channel_id): """get default out direct""" channel_dict = {"0": "console", "1": "monitor", "2": "loghost", "3": "trapbuffer", "4": "logbuffer", "5": "snmpagent", "6": "channel6", "7": "channel7", "8": "channel8", "9": "channel9"} channel_name_default = channel_dict.get(channel_id) return channel_name_default class InfoCenterGlobal(object): """ Manages info center global configuration. """ def __init__(self, argument_spec): self.spec = argument_spec self.module = None self.init_module() # module input info self.info_center_enable = self.module.params['info_center_enable'] or None self.packet_priority = self.module.params['packet_priority'] or None self.suppress_enable = self.module.params['suppress_enable'] or None self.logfile_max_num = self.module.params['logfile_max_num'] or None self.logfile_max_size = self.module.params['logfile_max_size'] or None self.channel_id = self.module.params['channel_id'] or None self.channel_cfg_name = self.module.params['channel_cfg_name'] or None self.channel_out_direct = self.module.params['channel_out_direct'] or None self.filter_feature_name = self.module.params['filter_feature_name'] or None self.filter_log_name = self.module.params['filter_log_name'] or None self.ip_type = self.module.params['ip_type'] or None self.server_ip = self.module.params['server_ip'] or None self.server_domain = self.module.params['server_domain'] or None self.is_default_vpn = self.module.params['is_default_vpn'] or None self.vrf_name = self.module.params['vrf_name'] or None self.level = self.module.params['level'] or None self.server_port = self.module.params['server_port'] or None self.facility = self.module.params['facility'] or None self.channel_name = self.module.params['channel_name'] or None self.timestamp = self.module.params['timestamp'] or None self.transport_mode = self.module.params['transport_mode'] or None self.ssl_policy_name = self.module.params['ssl_policy_name'] or None self.source_ip = self.module.params['source_ip'] or None self.state = self.module.params['state'] or None # state self.changed = False self.updates_cmd = list() self.results = dict() self.existing = dict() self.proposed = dict() self.end_state = dict() # syslog info self.cur_global_info = None self.cur_logfile_info = None self.channel_info = None self.channel_direct_info = None self.filter_info = None self.server_ip_info = None self.server_domain_info = None def init_module(self): """ init module """ self.module = AnsibleModule( argument_spec=self.spec, supports_check_mode=True) def check_response(self, con_obj, xml_name): """Check if response message is already succeed.""" xml_str = con_obj.xml if "" not in xml_str: self.module.fail_json(msg='Error: %s failed.' % xml_name) def get_channel_dict(self): """ get channel attributes dict.""" channel_info = dict() # get channel info conf_str = CE_NC_GET_CHANNEL_INFO % self.channel_id xml_str = get_nc_config(self.module, conf_str) if "" in xml_str: return channel_info 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) channel_info["channelInfos"] = list() channels = root.findall("syslog/icChannels/icChannel") if channels: for channel in channels: channel_dict = dict() for ele in channel: if ele.tag in ["icChnlId", "icChnlCfgName"]: channel_dict[ele.tag] = ele.text channel_info["channelInfos"].append(channel_dict) return channel_info def is_exist_channel_id_name(self, channel_id, channel_name): """if channel id exist""" if not self.channel_info: return False for id2name in self.channel_info["channelInfos"]: if id2name["icChnlId"] == channel_id and id2name["icChnlCfgName"] == channel_name: return True return False def config_merge_syslog_channel(self, channel_id, channel_name): """config channel id""" if not self.is_exist_channel_id_name(channel_id, channel_name): conf_str = CE_NC_MERGE_CHANNEL_INFO_HEADER if channel_id: conf_str += "%s" % channel_id if channel_name: conf_str += "%s" % channel_name conf_str += CE_NC_MERGE_CHANNEL_INFO_TAIL recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json( msg='Error: Merge syslog channel id failed.') self.updates_cmd.append( "info-center channel %s name %s" % (channel_id, channel_name)) self.changed = True def delete_merge_syslog_channel(self, channel_id, channel_name): """delete channel id""" change_flag = False if channel_name: for id2name in self.channel_info["channelInfos"]: channel_default_name = get_channel_name_default( id2name["icChnlId"]) if id2name["icChnlId"] == channel_id and id2name["icChnlCfgName"] == channel_name: channel_name = channel_default_name change_flag = True if not channel_name: for id2name in self.channel_info["channelInfos"]: channel_default_name = get_channel_name_default( id2name["icChnlId"]) if id2name["icChnlId"] == channel_id and id2name["icChnlCfgName"] != channel_default_name: channel_name = channel_default_name change_flag = True if change_flag: conf_str = CE_NC_MERGE_CHANNEL_INFO_HEADER if channel_id: conf_str += "%s" % channel_id if channel_name: conf_str += "%s" % channel_name conf_str += CE_NC_MERGE_CHANNEL_INFO_TAIL recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json( msg='Error: Merge syslog channel id failed.') self.updates_cmd.append("undo info-center channel %s" % channel_id) self.changed = True def get_channel_direct_dict(self): """ get channel direct attributes dict.""" channel_direct_info = dict() # get channel direct info conf_str = CE_NC_GET_CHANNEL_DIRECT_INFO % self.channel_out_direct xml_str = get_nc_config(self.module, conf_str) if "" in xml_str: return channel_direct_info 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) channel_direct_info["channelDirectInfos"] = list() dir_channels = root.findall("syslog/icDirChannels/icDirChannel") if dir_channels: for ic_dir_channel in dir_channels: channel_direct_dict = dict() for ele in ic_dir_channel: if ele.tag in ["icOutDirect", "icCfgChnlId"]: channel_direct_dict[ele.tag] = ele.text channel_direct_info["channelDirectInfos"].append( channel_direct_dict) return channel_direct_info def is_exist_out_direct(self, out_direct, channel_id): """if channel out direct exist""" if not self.channel_direct_info: return False for id2name in self.channel_direct_info["channelDirectInfos"]: if id2name["icOutDirect"] == out_direct and id2name["icCfgChnlId"] == channel_id: return True return False def config_merge_out_direct(self, out_direct, channel_id): """config out direct""" if not self.is_exist_out_direct(out_direct, channel_id): conf_str = CE_NC_MERGE_CHANNEL_DIRECT_HEADER if out_direct: conf_str += "%s" % out_direct if channel_id: conf_str += "%s" % channel_id conf_str += CE_NC_MERGE_CHANNEL_DIRECT_TAIL recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json( msg='Error: Merge syslog channel out direct failed.') self.updates_cmd.append( "info-center %s channel %s" % (out_direct, channel_id)) self.changed = True def delete_merge_out_direct(self, out_direct, channel_id): """delete out direct""" change_flag = False channel_id_default = get_out_direct_default(out_direct) if channel_id: for id2name in self.channel_direct_info["channelDirectInfos"]: if id2name["icOutDirect"] == out_direct and id2name["icCfgChnlId"] == channel_id: if channel_id != channel_id_default: channel_id = channel_id_default change_flag = True if not channel_id: for id2name in self.channel_direct_info["channelDirectInfos"]: if id2name["icOutDirect"] == out_direct and id2name["icCfgChnlId"] != channel_id_default: channel_id = channel_id_default change_flag = True if change_flag: conf_str = CE_NC_MERGE_CHANNEL_DIRECT_HEADER if out_direct: conf_str += "%s" % out_direct if channel_id: conf_str += "%s" % channel_id conf_str += CE_NC_MERGE_CHANNEL_DIRECT_TAIL recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json( msg='Error: Merge syslog channel out direct failed.') self.updates_cmd.append("undo info-center logfile channel") self.changed = True def get_filter_dict(self): """ get syslog filter attributes dict.""" filter_info = dict() # get filter info conf_str = CE_NC_GET_FILTER_INFO xml_str = get_nc_config(self.module, conf_str) if "" in xml_str: return filter_info 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) filter_info["filterInfos"] = list() ic_filters = root.findall("syslog/icFilters/icFilter") if ic_filters: for ic_filter in ic_filters: filter_dict = dict() for ele in ic_filter: if ele.tag in ["icFeatureName", "icFilterLogName"]: filter_dict[ele.tag] = ele.text filter_info["filterInfos"].append(filter_dict) return filter_info def is_exist_filter(self, filter_feature_name, filter_log_name): """if filter info exist""" if not self.filter_info: return False for id2name in self.filter_info["filterInfos"]: if id2name["icFeatureName"] == filter_feature_name and id2name["icFilterLogName"] == filter_log_name: return True return False def config_merge_filter(self, filter_feature_name, filter_log_name): """config filter""" if not self.is_exist_filter(filter_feature_name, filter_log_name): conf_str = CE_NC_CREATE_CHANNEL_FILTER_HEADER conf_str += "true" if filter_feature_name: conf_str += "%s" % filter_feature_name if filter_log_name: conf_str += "%s" % filter_log_name conf_str += CE_NC_CREATE_CHANNEL_FILTER_TAIL recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json(msg='Error: Merge syslog filter failed.') self.updates_cmd.append("info-center filter-id bymodule-alias %s %s" % (filter_feature_name, filter_log_name)) self.changed = True def delete_merge_filter(self, filter_feature_name, filter_log_name): """delete filter""" change_flag = False if self.is_exist_filter(filter_feature_name, filter_log_name): for id2name in self.filter_info["filterInfos"]: if id2name["icFeatureName"] == filter_feature_name and id2name["icFilterLogName"] == filter_log_name: change_flag = True if change_flag: conf_str = CE_NC_DELETE_CHANNEL_FILTER_HEADER conf_str += "true" if filter_feature_name: conf_str += "%s" % filter_feature_name if filter_log_name: conf_str += "%s" % filter_log_name conf_str += CE_NC_DELETE_CHANNEL_FILTER_TAIL recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json( msg='Error: Merge syslog channel out direct failed.') self.updates_cmd.append("undo info-center filter-id bymodule-alias %s %s" % (filter_feature_name, filter_log_name)) self.changed = True def get_server_ip_dict(self): """ get server ip attributes dict.""" server_ip_info = dict() # get server ip info is_default_vpn = "false" if not self.is_default_vpn: self.is_default_vpn = False if self.is_default_vpn is True: is_default_vpn = "true" if not self.vrf_name: self.vrf_name = "_public_" conf_str = CE_NC_GET_SERVER_IP_INFO_HEADER % ( self.ip_type, self.server_ip, self.vrf_name, is_default_vpn) conf_str += CE_NC_GET_SERVER_IP_INFO_TAIL xml_str = get_nc_config(self.module, conf_str) if "" in xml_str: return server_ip_info 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) server_ip_info["serverIpInfos"] = list() syslog_servers = root.findall("syslog/syslogServers/syslogServer") if syslog_servers: for syslog_server in syslog_servers: server_dict = dict() for ele in syslog_server: if ele.tag in ["ipType", "serverIp", "vrfName", "level", "serverPort", "facility", "chnlId", "chnlName", "timestamp", "transportMode", "sslPolicyName", "isDefaultVpn", "sourceIP", "isBriefFmt"]: server_dict[ele.tag] = ele.text server_ip_info["serverIpInfos"].append(server_dict) return server_ip_info def config_merge_loghost(self): """config loghost ip or dns""" conf_str = "" is_default_vpn = "false" if self.is_default_vpn is True: is_default_vpn = "true" if self.ip_type: conf_str = CE_NC_MERGE_SERVER_IP_INFO_HEADER % (self.ip_type, self.server_ip, self.vrf_name, is_default_vpn) elif self.server_domain: conf_str = CE_NC_MERGE_SERVER_DNS_INFO_HEADER % ( self.server_domain, self.vrf_name, is_default_vpn) if self.level: conf_str += "%s" % self.level if self.server_port: conf_str += "%s" % self.server_port if self.facility: conf_str += "%s" % self.facility if self.channel_id: conf_str += "%s" % self.channel_id if self.channel_name: conf_str += "%s" % self.channel_name if self.timestamp: conf_str += "%s" % self.timestamp if self.transport_mode: conf_str += "%s" % self.transport_mode if self.ssl_policy_name: conf_str += "%s" % self.ssl_policy_name if self.source_ip: conf_str += "%s" % self.source_ip if self.ip_type: conf_str += CE_NC_MERGE_SERVER_IP_INFO_TAIL elif self.server_domain: conf_str += CE_NC_MERGE_SERVER_DNS_INFO_TAIL recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json(msg='Error: Merge server loghost failed.') cmd = "info-center loghost" if self.ip_type == "ipv4" and self.server_ip: cmd += " %s" % self.server_ip if self.ip_type == "ipv6" and self.server_ip: cmd += " ipv6 %s" % self.server_ip if self.server_domain: cmd += " domain %s" % self.server_domain if self.channel_id: cmd += " channel %s" % self.channel_id if self.channel_name: cmd += " channel %s" % self.channel_name if self.vrf_name: if self.vrf_name != "_public_": cmd += " vpn-instance %s" % self.vrf_name if self.source_ip: cmd += " source-ip %s" % self.source_ip if self.facility: cmd += " facility %s" % self.facility if self.server_port: cmd += " port %s" % self.server_port if self.level: cmd += " level %s" % self.level if self.timestamp: if self.timestamp == "localtime": cmd += " local-time" else: cmd += " utc" if self.transport_mode: cmd += " transport %s" % self.transport_mode if self.ssl_policy_name: cmd += " ssl-policy %s" % self.ssl_policy_name self.updates_cmd.append(cmd) self.changed = True def delete_merge_loghost(self): """delete loghost ip or dns""" conf_str = "" is_default_vpn = "false" if self.is_default_vpn is True: is_default_vpn = "true" if self.ip_type: conf_str = CE_NC_DELETE_SERVER_IP_INFO_HEADER % (self.ip_type, self.server_ip, self.vrf_name, is_default_vpn) elif self.server_domain: conf_str = CE_NC_DELETE_SERVER_DNS_INFO_HEADER % ( self.server_domain, self.vrf_name, is_default_vpn) if self.level: conf_str += "%s" % self.level if self.server_port: conf_str += "%s" % self.server_port if self.facility: conf_str += "%s" % self.facility if self.channel_id: conf_str += "%s" % self.channel_id if self.channel_name: conf_str += "%s" % self.channel_name if self.timestamp: conf_str += "%s" % self.timestamp if self.transport_mode: conf_str += "%s" % self.transport_mode if self.ssl_policy_name: conf_str += "%s" % self.ssl_policy_name if self.source_ip: conf_str += "%s" % self.source_ip if self.ip_type: conf_str += CE_NC_DELETE_SERVER_IP_INFO_TAIL elif self.server_domain: conf_str += CE_NC_DELETE_SERVER_DNS_INFO_TAIL recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json(msg='Error: Merge server loghost failed.') cmd = "undo info-center loghost" if self.ip_type == "ipv4" and self.server_ip: cmd += " %s" % self.server_ip if self.ip_type == "ipv6" and self.server_ip: cmd += " ipv6 %s" % self.server_ip if self.server_domain: cmd += " domain %s" % self.server_domain if self.vrf_name: if self.vrf_name != "_public_": cmd += " vpn-instance %s" % self.vrf_name self.updates_cmd.append(cmd) self.changed = True def get_server_domain_dict(self): """ get server domain attributes dict""" server_domain_info = dict() # get server domain info if not self.is_default_vpn: self.is_default_vpn = False if not self.vrf_name: self.vrf_name = "_public_" conf_str = CE_NC_GET_SERVER_DNS_INFO_HEADER conf_str += CE_NC_GET_SERVER_DNS_INFO_TAIL xml_str = get_nc_config(self.module, conf_str) if "" in xml_str: return server_domain_info 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) server_domain_info["serverAddressInfos"] = list() syslog_dnss = root.findall("syslog/syslogDNSs/syslogDNS") if syslog_dnss: for syslog_dns in syslog_dnss: dns_dict = dict() for ele in syslog_dns: if ele.tag in ["serverDomain", "vrfName", "level", "serverPort", "facility", "chnlId", "chnlName", "timestamp", "transportMode", "sslPolicyName", "isDefaultVpn", "sourceIP", "isBriefFmt"]: dns_dict[ele.tag] = ele.text server_domain_info["serverAddressInfos"].append(dns_dict) return server_domain_info def check_need_loghost_cfg(self): """ check need cfg""" need_cfg = False find_flag = False if self.ip_type and self.server_ip: if self.server_ip_info: for tmp in self.server_ip_info["serverIpInfos"]: find_flag = True if self.ip_type and tmp.get("ipType") != self.ip_type: find_flag = False if self.server_ip and tmp.get("serverIp") != self.server_ip: find_flag = False if self.vrf_name and tmp.get("vrfName") != self.vrf_name: find_flag = False if self.level and tmp.get("level") != self.level: find_flag = False if self.server_port and tmp.get("serverPort") != self.server_port: find_flag = False if self.facility and tmp.get("facility") != self.facility: find_flag = False if self.channel_id and tmp.get("chnlId") != self.channel_id: find_flag = False if self.channel_name and tmp.get("chnlName") != self.channel_name: find_flag = False if self.timestamp and tmp.get("timestamp") != self.timestamp: find_flag = False if self.transport_mode and tmp.get("transportMode") != self.transport_mode: find_flag = False if self.ssl_policy_name and tmp.get("sslPolicyName") != self.ssl_policy_name: find_flag = False if self.source_ip and tmp.get("sourceIP") != self.source_ip: find_flag = False if find_flag: break elif self.server_domain: if self.server_domain_info: for tmp in self.server_domain_info["serverAddressInfos"]: find_flag = True if self.server_domain and tmp.get("serverDomain") != self.server_domain: find_flag = False if self.vrf_name and tmp.get("vrfName") != self.vrf_name: find_flag = False if self.level and tmp.get("level") != self.level: find_flag = False if self.server_port and tmp.get("serverPort") != self.server_port: find_flag = False if self.facility and tmp.get("facility") != self.facility: find_flag = False if self.channel_id and tmp.get("chnlId") != self.channel_id: find_flag = False if self.channel_name and tmp.get("chnlName") != self.channel_name: find_flag = False if self.timestamp and tmp.get("timestamp") != self.timestamp: find_flag = False if self.transport_mode and tmp.get("transportMode") != self.transport_mode: find_flag = False if self.ssl_policy_name and tmp.get("sslPolicyName") != self.ssl_policy_name: find_flag = False if self.source_ip and tmp.get("sourceIP") != self.source_ip: find_flag = False if find_flag: break else: find_flag = False if self.state == "present": need_cfg = bool(not find_flag) elif self.state == "absent": need_cfg = bool(find_flag) return need_cfg def get_syslog_global(self): """get syslog global attributes""" cur_global_info = dict() conf_str = CE_NC_GET_CENTER_GLOBAL_INFO_HEADER if self.info_center_enable: conf_str += "" if self.packet_priority: conf_str += "" if self.suppress_enable: conf_str += "" conf_str += CE_NC_GET_CENTER_GLOBAL_INFO_TAIL xml_str = get_nc_config(self.module, conf_str) if "" in xml_str: return cur_global_info 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_info = root.findall( "syslog/globalParam") if global_info: for tmp in global_info: for site in tmp: if site.tag in ["icEnable", "packetPriority", "suppressEnable"]: cur_global_info[site.tag] = site.text return cur_global_info def merge_syslog_global(self): """config global""" conf_str = CE_NC_MERGE_CENTER_GLOBAL_INFO_HEADER if self.info_center_enable: conf_str += "%s" % self.info_center_enable if self.packet_priority: if self.state == "present": packet_priority = self.packet_priority else: packet_priority = 0 conf_str += "%s" % packet_priority if self.suppress_enable: conf_str += "%s" % self.suppress_enable conf_str += CE_NC_MERGE_CENTER_GLOBAL_INFO_TAIL if self.info_center_enable == "true" and self.cur_global_info["icEnable"] != self.info_center_enable: cmd = "info-center enable" self.updates_cmd.append(cmd) self.changed = True if self.suppress_enable == "true" and self.cur_global_info["suppressEnable"] != self.suppress_enable: cmd = "info-center statistic-suppress enable" self.updates_cmd.append(cmd) self.changed = True if self.info_center_enable == "false" and self.cur_global_info["icEnable"] != self.info_center_enable: cmd = "undo info-center enable" self.updates_cmd.append(cmd) self.changed = True if self.suppress_enable == "false" and self.cur_global_info["suppressEnable"] != self.suppress_enable: cmd = "undo info-center statistic-suppress enable" self.updates_cmd.append(cmd) self.changed = True if self.state == "present": if self.packet_priority: if self.cur_global_info["packetPriority"] != self.packet_priority: cmd = "info-center syslog packet-priority %s" % self.packet_priority self.updates_cmd.append(cmd) self.changed = True if self.state == "absent": if self.packet_priority: if self.cur_global_info["packetPriority"] == self.packet_priority: cmd = "undo info-center syslog packet-priority %s" % self.packet_priority self.updates_cmd.append(cmd) self.changed = True if self.changed: recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json(msg='Error: Merge syslog global failed.') def get_syslog_logfile(self): """get syslog logfile""" cur_logfile_info = dict() conf_str = CE_NC_GET_LOG_FILE_INFO_HEADER conf_str += "log" if self.logfile_max_num: conf_str += "" if self.logfile_max_size: conf_str += "" conf_str += CE_NC_GET_LOG_FILE_INFO_TAIL xml_str = get_nc_config(self.module, conf_str) if "" in xml_str: return cur_logfile_info 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) logfile_info = root.findall( "syslog/icLogFileInfos/icLogFileInfo") if logfile_info: for tmp in logfile_info: for site in tmp: if site.tag in ["maxFileNum", "maxFileSize"]: cur_logfile_info[site.tag] = site.text return cur_logfile_info def merge_syslog_logfile(self): """config logfile""" logfile_max_num = "200" conf_str = CE_NC_MERGE_LOG_FILE_INFO_HEADER if self.logfile_max_num: if self.state == "present": logfile_max_num = self.logfile_max_num else: if self.logfile_max_num != "200" and self.cur_logfile_info["maxFileNum"] == self.logfile_max_num: logfile_max_num = "200" conf_str += "%s" % logfile_max_num if self.logfile_max_size: logfile_max_size = "32" if self.state == "present": logfile_max_size = self.logfile_max_size else: if self.logfile_max_size != "32" and self.cur_logfile_info["maxFileSize"] == self.logfile_max_size: logfile_max_size = "32" conf_str += "%s" % logfile_max_size conf_str += "log" conf_str += CE_NC_MERGE_LOG_FILE_INFO_TAIL if self.state == "present": if self.logfile_max_num: if self.cur_logfile_info["maxFileNum"] != self.logfile_max_num: cmd = "info-center max-logfile-number %s" % self.logfile_max_num self.updates_cmd.append(cmd) self.changed = True if self.logfile_max_size: if self.cur_logfile_info["maxFileSize"] != self.logfile_max_size: cmd = "info-center logfile size %s" % self.logfile_max_size self.updates_cmd.append(cmd) self.changed = True if self.state == "absent": if self.logfile_max_num and self.logfile_max_num != "200": if self.cur_logfile_info["maxFileNum"] == self.logfile_max_num: cmd = "undo info-center max-logfile-number" self.updates_cmd.append(cmd) self.changed = True if self.logfile_max_size and self.logfile_max_size != "32": if self.cur_logfile_info["maxFileSize"] == self.logfile_max_size: cmd = "undo info-center logfile size" self.updates_cmd.append(cmd) self.changed = True if self.changed: recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json( msg='Error: Merge syslog logfile failed.') def check_params(self): """Check all input params""" # packet_priority check if self.packet_priority: if not self.packet_priority.isdigit(): self.module.fail_json( msg='Error: The parameter of packet priority is invalid.') if int(self.packet_priority) > 7 or int(self.packet_priority) < 0: self.module.fail_json( msg='Error: The packet priority must be an integer between 0 and 7.') # logfile_max_num check if self.logfile_max_num: if not self.logfile_max_num.isdigit(): self.module.fail_json( msg='Error: The parameter of logfile_max_num is invalid.') if int(self.logfile_max_num) > 500 or int(self.logfile_max_num) < 3: self.module.fail_json( msg='Error: The logfile_max_num must be an integer between 3 and 500.') # channel_id check if self.channel_id: if not self.channel_id.isdigit(): self.module.fail_json( msg='Error: The parameter of channel_id is invalid.') if int(self.channel_id) > 9 or int(self.channel_id) < 0: self.module.fail_json( msg='Error: The channel_id must be an integer between 0 and 9.') # channel_cfg_name check if self.channel_cfg_name: if len(self.channel_cfg_name) > 30 \ or len(self.channel_cfg_name.replace(' ', '')) < 1: self.module.fail_json( msg='Error: channel_cfg_name is not in the range from 1 to 30.') # filter_feature_name check if self.filter_feature_name: if len(self.filter_feature_name) > 31 \ or len(self.filter_feature_name.replace(' ', '')) < 1: self.module.fail_json( msg='Error: filter_feature_name is not in the range from 1 to 31.') # filter_log_name check if self.filter_log_name: if len(self.filter_log_name) > 63 \ or len(self.filter_log_name.replace(' ', '')) < 1: self.module.fail_json( msg='Error: filter_log_name is not in the range from 1 to 63.') # server_ip check if self.server_ip: if not check_ip_addr(self.server_ip): self.module.fail_json( msg='Error: The %s is not a valid ip address' % self.server_ip) # source_ip check if self.source_ip: if not check_ip_addr(self.source_ip): self.module.fail_json( msg='Error: The %s is not a valid ip address' % self.source_ip) # server_domain check if self.server_domain: if len(self.server_domain) > 255 \ or len(self.server_domain.replace(' ', '')) < 1: self.module.fail_json( msg='Error: server_domain is not in the range from 1 to 255.') # vrf_name check if self.vrf_name: if len(self.vrf_name) > 31 \ or len(self.vrf_name.replace(' ', '')) < 1: self.module.fail_json( msg='Error: vrf_name is not in the range from 1 to 31.') # server_port check if self.server_port: if not self.server_port.isdigit(): self.module.fail_json( msg='Error: The parameter of server_port is invalid.') if int(self.server_port) > 65535 or int(self.server_port) < 1: self.module.fail_json( msg='Error: The server_port must be an integer between 1 and 65535.') # channel_name check if self.channel_name: if len(self.channel_name) > 31 \ or len(self.channel_name.replace(' ', '')) < 1: self.module.fail_json( msg='Error: channel_name is not in the range from 1 to 30.') # ssl_policy_name check if self.ssl_policy_name: if len(self.ssl_policy_name) > 23 \ or len(self.ssl_policy_name.replace(' ', '')) < 1: self.module.fail_json( msg='Error: ssl_policy_name is not in the range from 1 to 23.') def get_proposed(self): """get proposed info""" if self.info_center_enable: self.proposed["info_center_enable"] = self.info_center_enable if self.packet_priority: self.proposed["packet_priority"] = self.packet_priority if self.suppress_enable: self.proposed["suppress_enable"] = self.suppress_enable if self.logfile_max_num: self.proposed["logfile_max_num"] = self.logfile_max_num if self.logfile_max_size: self.proposed["logfile_max_size"] = self.logfile_max_size if self.channel_id: self.proposed["channel_id"] = self.channel_id if self.channel_cfg_name: self.proposed["channel_cfg_name"] = self.channel_cfg_name if self.channel_out_direct: self.proposed["channel_out_direct"] = self.channel_out_direct if self.filter_feature_name: self.proposed["filter_feature_name"] = self.filter_feature_name if self.filter_log_name: self.proposed["filter_log_name"] = self.filter_log_name if self.ip_type: self.proposed["ip_type"] = self.ip_type if self.server_ip: self.proposed["server_ip"] = self.server_ip if self.server_domain: self.proposed["server_domain"] = self.server_domain if self.vrf_name: self.proposed["vrf_name"] = self.vrf_name if self.level: self.proposed["level"] = self.level if self.server_port: self.proposed["server_port"] = self.server_port if self.facility: self.proposed["facility"] = self.facility if self.channel_name: self.proposed["channel_name"] = self.channel_name if self.timestamp: self.proposed["timestamp"] = self.timestamp if self.ssl_policy_name: self.proposed["ssl_policy_name"] = self.ssl_policy_name if self.transport_mode: self.proposed["transport_mode"] = self.transport_mode if self.is_default_vpn: self.proposed["is_default_vpn"] = self.is_default_vpn if self.source_ip: self.proposed["source_ip"] = self.source_ip if self.state: self.proposed["state"] = self.state def get_existing(self): """get existing info""" if self.info_center_enable: self.existing["info_center_enable"] = self.cur_global_info[ "icEnable"] if self.packet_priority: self.existing["packet_priority"] = self.cur_global_info[ "packetPriority"] if self.suppress_enable: self.existing["suppress_enable"] = self.cur_global_info[ "suppressEnable"] if self.logfile_max_num: self.existing["logfile_max_num"] = self.cur_logfile_info[ "maxFileNum"] if self.logfile_max_size: self.existing["logfile_max_size"] = self.cur_logfile_info[ "maxFileSize"] if self.channel_id and self.channel_cfg_name: if self.channel_info: self.existing["channel_id_info"] = self.channel_info[ "channelInfos"] if self.channel_out_direct and self.channel_id: if self.channel_direct_info: self.existing["channel_out_direct_info"] = self.channel_direct_info[ "channelDirectInfos"] if self.filter_feature_name and self.filter_log_name: if self.filter_info: self.existing["filter_id_info"] = self.filter_info[ "filterInfos"] if self.ip_type: if self.server_ip_info: self.existing["server_ip_info"] = self.server_ip_info[ "serverIpInfos"] if self.server_domain: if self.server_domain_info: self.existing["server_domain_info"] = self.server_domain_info[ "serverAddressInfos"] def get_end_state(self): """get end state info""" if self.info_center_enable or self.packet_priority or self.suppress_enable: self.cur_global_info = self.get_syslog_global() if self.logfile_max_num or self.logfile_max_size: self.cur_logfile_info = self.get_syslog_logfile() if self.channel_id and self.channel_cfg_name: self.channel_info = self.get_channel_dict() if self.channel_out_direct and self.channel_id: self.channel_direct_info = self.get_channel_direct_dict() if self.filter_feature_name and self.filter_log_name: self.filter_info = self.get_filter_dict() if self.ip_type: self.server_ip_info = self.get_server_ip_dict() if self.server_domain: self.server_domain_info = self.get_server_domain_dict() if self.info_center_enable: self.end_state[ "info_center_enable"] = self.cur_global_info["icEnable"] if self.packet_priority: self.end_state["packet_priority"] = self.cur_global_info[ "packetPriority"] if self.suppress_enable: self.end_state["suppress_enable"] = self.cur_global_info[ "suppressEnable"] if self.logfile_max_num: self.end_state["logfile_max_num"] = self.cur_logfile_info[ "maxFileNum"] if self.logfile_max_size: self.end_state["logfile_max_size"] = self.cur_logfile_info[ "maxFileSize"] if self.channel_id and self.channel_cfg_name: if self.channel_info: self.end_state["channel_id_info"] = self.channel_info[ "channelInfos"] if self.channel_out_direct and self.channel_id: if self.channel_direct_info: self.end_state["channel_out_direct_info"] = self.channel_direct_info[ "channelDirectInfos"] if self.filter_feature_name and self.filter_log_name: if self.filter_info: self.end_state["filter_id_info"] = self.filter_info[ "filterInfos"] if self.ip_type: if self.server_ip_info: self.end_state["server_ip_info"] = self.server_ip_info[ "serverIpInfos"] if self.server_domain: if self.server_domain_info: self.end_state["server_domain_info"] = self.server_domain_info[ "serverAddressInfos"] if self.end_state == self.existing: self.changed = False def work(self): """worker""" self.check_params() if self.info_center_enable or self.packet_priority or self.suppress_enable: self.cur_global_info = self.get_syslog_global() if self.logfile_max_num or self.logfile_max_size: self.cur_logfile_info = self.get_syslog_logfile() if self.channel_id: self.channel_info = self.get_channel_dict() if self.channel_out_direct: self.channel_direct_info = self.get_channel_direct_dict() if self.filter_feature_name and self.filter_log_name: self.filter_info = self.get_filter_dict() if self.ip_type: self.server_ip_info = self.get_server_ip_dict() if self.server_domain: self.server_domain_info = self.get_server_domain_dict() self.get_existing() self.get_proposed() if self.info_center_enable or self.packet_priority or self.suppress_enable: self.merge_syslog_global() if self.logfile_max_num or self.logfile_max_size: self.merge_syslog_logfile() if self.server_ip: if not self.ip_type: self.module.fail_json( msg='Error: ip_type and server_ip must be exist at the same time.') if self.ip_type: if not self.server_ip: self.module.fail_json( msg='Error: ip_type and server_ip must be exist at the same time.') if self.ip_type or self.server_domain or self.channel_id or self.filter_feature_name: if self.ip_type and self.server_domain: self.module.fail_json( msg='Error: ip_type and server_domain can not be exist at the same time.') if self.channel_id and self.channel_name: self.module.fail_json( msg='Error: channel_id and channel_name can not be exist at the same time.') if self.ssl_policy_name: if self.transport_mode == "udp": self.module.fail_json( msg='Error: transport_mode: udp does not support ssl_policy.') if not self.transport_mode: self.module.fail_json( msg='Error: transport_mode, ssl_policy_name must be exist at the same time.') if self.ip_type == "ipv6": if self.vrf_name and self.vrf_name != "_public_": self.module.fail_json( msg='Error: ipType:ipv6 only support default vpn:_public_.') if self.is_default_vpn is True: if self.vrf_name: if self.vrf_name != "_public_": self.module.fail_json( msg='Error: vrf_name should be _public_ when is_default_vpn is True.') else: self.vrf_name = "_public_" else: if self.vrf_name == "_public_": self.module.fail_json( msg='Error: The default vpn value is _public_, but is_default_vpn is False.') if self.state == "present": # info-center channel channel-number name channel-name if self.channel_id and self.channel_cfg_name: self.config_merge_syslog_channel( self.channel_id, self.channel_cfg_name) # info-center { console | logfile | monitor | snmp | logbuffer # | trapbuffer } channel channel-number if self.channel_out_direct and self.channel_id: self.config_merge_out_direct( self.channel_out_direct, self.channel_id) # info-center filter-id bymodule-alias modname alias if self.filter_feature_name and self.filter_log_name: self.config_merge_filter( self.filter_feature_name, self.filter_log_name) if self.ip_type and self.server_ip: if not self.vrf_name: self.vrf_name = "_public_" if self.check_need_loghost_cfg(): self.config_merge_loghost() if self.server_domain: if not self.vrf_name: self.vrf_name = "_public_" if self.check_need_loghost_cfg(): self.config_merge_loghost() elif self.state == "absent": if self.channel_id: self.delete_merge_syslog_channel( self.channel_id, self.channel_cfg_name) if self.channel_out_direct: self.delete_merge_out_direct( self.channel_out_direct, self.channel_id) if self.filter_feature_name and self.filter_log_name: self.delete_merge_filter( self.filter_feature_name, self.filter_log_name) if self.ip_type and self.server_ip: if not self.vrf_name: self.vrf_name = "_public_" if self.check_need_loghost_cfg(): self.delete_merge_loghost() if self.server_domain: if not self.vrf_name: self.vrf_name = "_public_" if self.check_need_loghost_cfg(): self.delete_merge_loghost() 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 if self.changed: self.results['updates'] = self.updates_cmd else: self.results['updates'] = list() self.module.exit_json(**self.results) def main(): """Module main""" argument_spec = dict( info_center_enable=dict(choices=['true', 'false']), packet_priority=dict(type='str'), suppress_enable=dict(choices=['true', 'false']), logfile_max_num=dict(type='str'), logfile_max_size=dict(choices=['4', '8', '16', '32']), channel_id=dict(type='str'), channel_cfg_name=dict(type='str'), channel_out_direct=dict(choices=['console', 'monitor', 'trapbuffer', 'logbuffer', 'snmp', 'logfile']), filter_feature_name=dict(type='str'), filter_log_name=dict(type='str'), ip_type=dict(choices=['ipv4', 'ipv6']), server_ip=dict(type='str'), server_domain=dict(type='str'), is_default_vpn=dict(default=False, type='bool'), vrf_name=dict(type='str'), level=dict(choices=['emergencies', 'alert', 'critical', 'error', 'warning', 'notification', 'informational', 'debugging']), server_port=dict(type='str'), facility=dict(choices=['local0', 'local1', 'local2', 'local3', 'local4', 'local5', 'local6', 'local7']), channel_name=dict(type='str'), timestamp=dict(choices=['UTC', 'localtime']), transport_mode=dict(choices=['tcp', 'udp']), ssl_policy_name=dict(type='str'), source_ip=dict(type='str'), state=dict(choices=['present', 'absent'], default='present') ) argument_spec.update(ce_argument_spec) module = InfoCenterGlobal(argument_spec) module.work() if __name__ == '__main__': main()