From dda49ca7c9f2daef84da461b231411d55e447e3a Mon Sep 17 00:00:00 2001
From: QijunPan <panqijun@huawei.com>
Date: Fri, 19 May 2017 15:22:19 +0800
Subject: [PATCH] Contributing
 lib/ansible/modules/network/cloudengine/ce_snmp_traps.py module to manage
 HUAWEI data center CloudEngine (#22067)

* add ce-snmp_traps

* fix review issues

* fix pep8 error
---
 .../network/cloudengine/ce_snmp_traps.py      | 548 ++++++++++++++++++
 1 file changed, 548 insertions(+)
 create mode 100644 lib/ansible/modules/network/cloudengine/ce_snmp_traps.py

diff --git a/lib/ansible/modules/network/cloudengine/ce_snmp_traps.py b/lib/ansible/modules/network/cloudengine/ce_snmp_traps.py
new file mode 100644
index 00000000000..101787d79ae
--- /dev/null
+++ b/lib/ansible/modules/network/cloudengine/ce_snmp_traps.py
@@ -0,0 +1,548 @@
+#!/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/>.
+#
+
+ANSIBLE_METADATA = {'status': ['preview'],
+                    'supported_by': 'community',
+                    'metadata_version': '1.0'}
+
+DOCUMENTATION = '''
+---
+module: ce_snmp_traps
+version_added: "2.4"
+short_description: Manages SNMP traps configuration on HUAWEI CloudEngine switches.
+description:
+    - Manages SNMP traps configurations on HUAWEI CloudEngine switches.
+author:
+    - wangdezhuang (@CloudEngine-Ansible)
+options:
+    feature_name:
+        description:
+            - Alarm feature name.
+        required: false
+        default: null
+        choices: ['aaa', 'arp', 'bfd', 'bgp', 'cfg', 'configuration', 'dad', 'devm',
+                 'dhcpsnp', 'dldp', 'driver', 'efm', 'erps', 'error-down', 'fcoe',
+                 'fei', 'fei_comm', 'fm', 'ifnet', 'info', 'ipsg', 'ipv6', 'isis',
+                'l3vpn', 'lacp', 'lcs', 'ldm', 'ldp', 'ldt', 'lldp', 'mpls_lspm',
+                'msdp', 'mstp', 'nd', 'netconf', 'nqa', 'nvo3', 'openflow', 'ospf',
+                'ospfv3', 'pim', 'pim-std', 'qos', 'radius', 'rm', 'rmon', 'securitytrap',
+                'smlktrap', 'snmp', 'ssh', 'stackmng', 'sysclock', 'sysom', 'system',
+                'tcp', 'telnet', 'trill', 'trunk', 'tty', 'vbst', 'vfs', 'virtual-perception',
+                'vrrp', 'vstm', 'all']
+    trap_name:
+        description:
+            - Alarm trap name.
+        required: false
+        default: null
+    interface_type:
+        description:
+            - Interface type.
+        required: false
+        default: null
+        choices: ['Ethernet', 'Eth-Trunk', 'Tunnel', 'NULL', 'LoopBack', 'Vlanif', '100GE',
+                 '40GE', 'MTunnel', '10GE', 'GE', 'MEth', 'Vbdif', 'Nve']
+    interface_number:
+        description:
+            - Interface number.
+        required: false
+        default: null
+    port_number:
+        description:
+            - Source port number.
+        required: false
+        default: null
+'''
+
+EXAMPLES = '''
+
+- name: CloudEngine snmp traps 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 SNMP trap all enable"
+    ce_snmp_traps:
+      state:  present
+      feature_name:  all
+      provider: "{{ cli }}"
+
+  - name: "Config SNMP trap interface"
+    ce_snmp_traps:
+      state:  present
+      interface_type:  40GE
+      interface_number:  2/0/1
+      provider: "{{ cli }}"
+
+  - name: "Config SNMP trap port"
+    ce_snmp_traps:
+      state:  present
+      port_number:  2222
+      provider: "{{ cli }}"
+'''
+
+RETURN = '''
+changed:
+    description: check to see if a change was made on the device
+    returned: always
+    type: boolean
+    sample: true
+proposed:
+    description: k/v pairs of parameters passed into module
+    returned: always
+    type: dict
+    sample: {"feature_name": "all",
+             "state": "present"}
+existing:
+    description: k/v pairs of existing aaa server
+    returned: always
+    type: dict
+    sample: {"snmp-agent trap": [],
+             "undo snmp-agent trap": []}
+end_state:
+    description: k/v pairs of aaa params after module execution
+    returned: always
+    type: dict
+    sample: {"snmp-agent trap": ["enable"],
+             "undo snmp-agent trap": []}
+updates:
+    description: command sent to the device
+    returned: always
+    type: list
+    sample: ["snmp-agent trap enable"]
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.ce import get_config, load_config, ce_argument_spec, run_commands
+
+
+class SnmpTraps(object):
+    """ Manages SNMP trap configuration """
+
+    def __init__(self, **kwargs):
+        """ Class init """
+
+        # module
+        argument_spec = kwargs["argument_spec"]
+        self.spec = argument_spec
+        self.module = AnsibleModule(
+            argument_spec=self.spec,
+            required_together=[("interface_type", "interface_number")],
+            supports_check_mode=True
+        )
+
+        # config
+        self.cur_cfg = dict()
+        self.cur_cfg["snmp-agent trap"] = []
+        self.cur_cfg["undo snmp-agent trap"] = []
+
+        # module args
+        self.state = self.module.params['state']
+        self.feature_name = self.module.params['feature_name']
+        self.trap_name = self.module.params['trap_name']
+        self.interface_type = self.module.params['interface_type']
+        self.interface_number = self.module.params['interface_number']
+        self.port_number = self.module.params['port_number']
+
+        # state
+        self.changed = False
+        self.updates_cmd = list()
+        self.results = dict()
+        self.proposed = dict()
+        self.existing = dict()
+        self.existing["snmp-agent trap"] = []
+        self.existing["undo snmp-agent trap"] = []
+        self.end_state = dict()
+        self.end_state["snmp-agent trap"] = []
+        self.end_state["undo snmp-agent trap"] = []
+
+        commands = list()
+        cmd1 = 'display interface brief'
+        commands.append(cmd1)
+        self.interface = run_commands(self.module, commands)
+
+    def check_args(self):
+        """ Check invalid args """
+
+        if self.port_number:
+            if self.port_number.isdigit():
+                if int(self.port_number) < 1025 or int(self.port_number) > 65535:
+                    self.module.fail_json(
+                        msg='Error: The value of port_number is out of [1025 - 65535].')
+            else:
+                self.module.fail_json(
+                    msg='Error: The port_number is not digit.')
+
+        if self.interface_type and self.interface_number:
+            tmp_interface = self.interface_type + self.interface_number
+            if tmp_interface not in self.interface[0]:
+                self.module.fail_json(
+                    msg='Error: The interface %s is not in the device.' % tmp_interface)
+
+    def get_proposed(self):
+        """ Get proposed state """
+
+        self.proposed["state"] = self.state
+
+        if self.feature_name:
+            self.proposed["feature_name"] = self.feature_name
+
+        if self.trap_name:
+            self.proposed["trap_name"] = self.trap_name
+
+        if self.interface_type:
+            self.proposed["interface_type"] = self.interface_type
+
+        if self.interface_number:
+            self.proposed["interface_number"] = self.interface_number
+
+        if self.port_number:
+            self.proposed["port_number"] = self.port_number
+
+    def get_existing(self):
+        """ Get existing state """
+
+        tmp_cfg = self.cli_get_config()
+        if tmp_cfg:
+            temp_cfg_lower = tmp_cfg.lower()
+            temp_data = tmp_cfg.split("\n")
+            temp_data_lower = temp_cfg_lower.split("\n")
+
+            for item in temp_data:
+                if "snmp-agent trap source-port " in item:
+                    if self.port_number:
+                        item_tmp = item.split("snmp-agent trap source-port ")
+                        self.cur_cfg["trap source-port"] = item_tmp[1]
+                        self.existing["trap source-port"] = item_tmp[1]
+                elif "snmp-agent trap source " in item:
+                    if self.interface_type:
+                        item_tmp = item.split("snmp-agent trap source ")
+                        self.cur_cfg["trap source interface"] = item_tmp[1]
+                        self.existing["trap source interface"] = item_tmp[1]
+
+            if self.feature_name:
+                for item in temp_data_lower:
+                    if item == "snmp-agent trap enable":
+                        self.cur_cfg["snmp-agent trap"].append("enable")
+                        self.existing["snmp-agent trap"].append("enable")
+                    elif item == "snmp-agent trap disable":
+                        self.cur_cfg["snmp-agent trap"].append("disable")
+                        self.existing["snmp-agent trap"].append("disable")
+                    elif "undo snmp-agent trap enable " in item:
+                        item_tmp = item.split("undo snmp-agent trap enable ")
+                        self.cur_cfg[
+                            "undo snmp-agent trap"].append(item_tmp[1])
+                        self.existing[
+                            "undo snmp-agent trap"].append(item_tmp[1])
+                    elif "snmp-agent trap enable " in item:
+                        item_tmp = item.split("snmp-agent trap enable ")
+                        self.cur_cfg["snmp-agent trap"].append(item_tmp[1])
+                        self.existing["snmp-agent trap"].append(item_tmp[1])
+            else:
+                del self.existing["snmp-agent trap"]
+                del self.existing["undo snmp-agent trap"]
+
+    def get_end_state(self):
+        """ Get end_state state """
+
+        tmp_cfg = self.cli_get_config()
+        if tmp_cfg:
+            temp_cfg_lower = tmp_cfg.lower()
+            temp_data = tmp_cfg.split("\n")
+            temp_data_lower = temp_cfg_lower.split("\n")
+
+            for item in temp_data:
+                if "snmp-agent trap source-port " in item:
+                    if self.port_number:
+                        item_tmp = item.split("snmp-agent trap source-port ")
+                        self.end_state["trap source-port"] = item_tmp[1]
+                elif "snmp-agent trap source " in item:
+                    if self.interface_type:
+                        item_tmp = item.split("snmp-agent trap source ")
+                        self.end_state["trap source interface"] = item_tmp[1]
+
+            if self.feature_name:
+                for item in temp_data_lower:
+                    if item == "snmp-agent trap enable":
+                        self.end_state["snmp-agent trap"].append("enable")
+                    elif item == "snmp-agent trap disable":
+                        self.end_state["snmp-agent trap"].append("disable")
+                    elif "undo snmp-agent trap enable " in item:
+                        item_tmp = item.split("undo snmp-agent trap enable ")
+                        self.end_state[
+                            "undo snmp-agent trap"].append(item_tmp[1])
+                    elif "snmp-agent trap enable " in item:
+                        item_tmp = item.split("snmp-agent trap enable ")
+                        self.end_state["snmp-agent trap"].append(item_tmp[1])
+            else:
+                del self.end_state["snmp-agent trap"]
+                del self.end_state["undo snmp-agent trap"]
+
+    def cli_load_config(self, commands):
+        """ Load configure through cli """
+
+        if not self.module.check_mode:
+            load_config(self.module, commands)
+
+    def cli_get_config(self):
+        """ Get configure through cli """
+
+        regular = "| include snmp | include trap"
+        flags = list()
+        flags.append(regular)
+        tmp_cfg = get_config(self.module, flags)
+
+        return tmp_cfg
+
+    def set_trap_feature_name(self):
+        """ Set feature name for trap """
+
+        if self.feature_name == "all":
+            cmd = "snmp-agent trap enable"
+        else:
+            cmd = "snmp-agent trap enable feature-name %s" % self.feature_name
+            if self.trap_name:
+                cmd += " trap-name %s" % self.trap_name
+
+        self.updates_cmd.append(cmd)
+
+        cmds = list()
+        cmds.append(cmd)
+
+        self.cli_load_config(cmds)
+        self.changed = True
+
+    def undo_trap_feature_name(self):
+        """ Undo feature name for trap """
+
+        if self.feature_name == "all":
+            cmd = "undo snmp-agent trap enable"
+        else:
+            cmd = "undo snmp-agent trap enable feature-name %s" % self.feature_name
+            if self.trap_name:
+                cmd += " trap-name %s" % self.trap_name
+
+        self.updates_cmd.append(cmd)
+
+        cmds = list()
+        cmds.append(cmd)
+
+        self.cli_load_config(cmds)
+        self.changed = True
+
+    def set_trap_source_interface(self):
+        """ Set source interface for trap """
+
+        cmd = "snmp-agent trap source %s %s" % (
+            self.interface_type, self.interface_number)
+        self.updates_cmd.append(cmd)
+
+        cmds = list()
+        cmds.append(cmd)
+
+        self.cli_load_config(cmds)
+        self.changed = True
+
+    def undo_trap_source_interface(self):
+        """ Undo source interface for trap """
+
+        cmd = "undo snmp-agent trap source"
+        self.updates_cmd.append(cmd)
+
+        cmds = list()
+        cmds.append(cmd)
+
+        self.cli_load_config(cmds)
+        self.changed = True
+
+    def set_trap_source_port(self):
+        """ Set source port for trap """
+
+        cmd = "snmp-agent trap source-port %s" % self.port_number
+        self.updates_cmd.append(cmd)
+
+        cmds = list()
+        cmds.append(cmd)
+
+        self.cli_load_config(cmds)
+        self.changed = True
+
+    def undo_trap_source_port(self):
+        """ Undo source port for trap """
+
+        cmd = "undo snmp-agent trap source-port"
+        self.updates_cmd.append(cmd)
+
+        cmds = list()
+        cmds.append(cmd)
+
+        self.cli_load_config(cmds)
+        self.changed = True
+
+    def work(self):
+        """ The work function """
+
+        self.check_args()
+        self.get_proposed()
+        self.get_existing()
+
+        find_flag = False
+        find_undo_flag = False
+        tmp_interface = None
+
+        if self.state == "present":
+            if self.feature_name:
+                if self.trap_name:
+                    tmp_cfg = "feature-name %s trap-name %s" % (
+                        self.feature_name, self.trap_name.lower())
+                else:
+                    tmp_cfg = "feature-name %s" % self.feature_name
+
+                find_undo_flag = False
+                if self.cur_cfg["undo snmp-agent trap"]:
+                    for item in self.cur_cfg["undo snmp-agent trap"]:
+                        if item == tmp_cfg:
+                            find_undo_flag = True
+                        elif tmp_cfg in item:
+                            find_undo_flag = True
+                        elif self.feature_name == "all":
+                            find_undo_flag = True
+                if find_undo_flag:
+                    self.set_trap_feature_name()
+
+                if not find_undo_flag:
+                    find_flag = False
+                    if self.cur_cfg["snmp-agent trap"]:
+                        for item in self.cur_cfg["snmp-agent trap"]:
+                            if item == "enable":
+                                find_flag = True
+                            elif item == tmp_cfg:
+                                find_flag = True
+                    if not find_flag:
+                        self.set_trap_feature_name()
+
+            if self.interface_type:
+                find_flag = False
+                tmp_interface = self.interface_type + self.interface_number
+
+                if "trap source interface" in self.cur_cfg.keys():
+                    if self.cur_cfg["trap source interface"] == tmp_interface:
+                        find_flag = True
+
+                if not find_flag:
+                    self.set_trap_source_interface()
+
+            if self.port_number:
+                find_flag = False
+
+                if "trap source-port" in self.cur_cfg.keys():
+                    if self.cur_cfg["trap source-port"] == self.port_number:
+                        find_flag = True
+
+                if not find_flag:
+                    self.set_trap_source_port()
+
+        else:
+            if self.feature_name:
+                if self.trap_name:
+                    tmp_cfg = "feature-name %s trap-name %s" % (
+                        self.feature_name, self.trap_name.lower())
+                else:
+                    tmp_cfg = "feature-name %s" % self.feature_name
+
+                find_flag = False
+                if self.cur_cfg["snmp-agent trap"]:
+                    for item in self.cur_cfg["snmp-agent trap"]:
+                        if item == tmp_cfg:
+                            find_flag = True
+                        elif item == "enable":
+                            find_flag = True
+                        elif tmp_cfg in item:
+                            find_flag = True
+                else:
+                    find_flag = True
+
+                find_undo_flag = False
+                if self.cur_cfg["undo snmp-agent trap"]:
+                    for item in self.cur_cfg["undo snmp-agent trap"]:
+                        if item == tmp_cfg:
+                            find_undo_flag = True
+                        elif tmp_cfg in item:
+                            find_undo_flag = True
+
+                if find_undo_flag:
+                    pass
+                elif find_flag:
+                    self.undo_trap_feature_name()
+
+            if self.interface_type:
+                if "trap source interface" in self.cur_cfg.keys():
+                    self.undo_trap_source_interface()
+
+            if self.port_number:
+                if "trap source-port" in self.cur_cfg.keys():
+                    self.undo_trap_source_port()
+
+        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'),
+        feature_name=dict(choices=['aaa', 'arp', 'bfd', 'bgp', 'cfg', 'configuration', 'dad',
+                                   'devm', 'dhcpsnp', 'dldp', 'driver', 'efm', 'erps', 'error-down',
+                                   'fcoe', 'fei', 'fei_comm', 'fm', 'ifnet', 'info', 'ipsg', 'ipv6',
+                                   'isis', 'l3vpn', 'lacp', 'lcs', 'ldm', 'ldp', 'ldt', 'lldp',
+                                   'mpls_lspm', 'msdp', 'mstp', 'nd', 'netconf', 'nqa', 'nvo3',
+                                   'openflow', 'ospf', 'ospfv3', 'pim', 'pim-std', 'qos', 'radius',
+                                   'rm', 'rmon', 'securitytrap', 'smlktrap', 'snmp', 'ssh', 'stackmng',
+                                   'sysclock', 'sysom', 'system', 'tcp', 'telnet', 'trill', 'trunk',
+                                   'tty', 'vbst', 'vfs', 'virtual-perception', 'vrrp', 'vstm', 'all']),
+        trap_name=dict(type='str'),
+        interface_type=dict(choices=['Ethernet', 'Eth-Trunk', 'Tunnel', 'NULL', 'LoopBack', 'Vlanif',
+                                     '100GE', '40GE', 'MTunnel', '10GE', 'GE', 'MEth', 'Vbdif', 'Nve']),
+        interface_number=dict(type='str'),
+        port_number=dict(type='str')
+    )
+
+    argument_spec.update(ce_argument_spec)
+    module = SnmpTraps(argument_spec=argument_spec)
+    module.work()
+
+
+if __name__ == '__main__':
+    main()