From 45f05ca8aaffd66e37e5ca5f72a6df07db1714bb Mon Sep 17 00:00:00 2001 From: QijunPan Date: Wed, 17 May 2017 05:44:49 +0800 Subject: [PATCH] Contributing lib/ansible/modules/network/cloudengine/ce_mlag_interface.py module to manage HUAWEI data center CloudEngine (#22055) * add ce_mlag_interface add ce_mlag_interface * upgrade ce mlag interface * fix CI issues --- .../network/cloudengine/ce_mlag_interface.py | 1029 +++++++++++++++++ 1 file changed, 1029 insertions(+) create mode 100644 lib/ansible/modules/network/cloudengine/ce_mlag_interface.py diff --git a/lib/ansible/modules/network/cloudengine/ce_mlag_interface.py b/lib/ansible/modules/network/cloudengine/ce_mlag_interface.py new file mode 100644 index 0000000000..2389ea8dc7 --- /dev/null +++ b/lib/ansible/modules/network/cloudengine/ce_mlag_interface.py @@ -0,0 +1,1029 @@ +#!/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 . +# + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'metadata_version': '1.0'} + +DOCUMENTATION = ''' +--- +module: ce_mlag_interface +version_added: "2.4" +short_description: Manages MLAG interfaces on HUAWEI CloudEngine switches. +description: + - Manages MLAG interface attributes on HUAWEI CloudEngine switches. +author: + - Li Yanfeng (@CloudEngine-Ansible) +options: + eth_trunk_id: + description: + - Name of the local M-LAG interface. The value is ranging from 0 to 511. + required: false + default: null + dfs_group_id: + description: + - ID of a DFS group.The value is 1. + required: false + default: present + mlag_id: + description: + - ID of the M-LAG. The value is an integer that ranges from 1 to 2048. + required: false + default: null + mlag_system_id: + description: + - M-LAG global LACP system MAC address. The value is a string of 0 to 255 characters. The default value + is the MAC address of the Ethernet port of MPU. + required: false + default: null + mlag_priority_id: + description: + - M-LAG global LACP system priority. The value is an integer ranging from 0 to 65535. + The default value is 32768. + required: false + default: null + interface: + description: + - Name of the interface that enters the Error-Down state when the peer-link fails. + The value is a string of 1 to 63 characters. + required: false + default: null + mlag_error_down: + description: + - Configure the interface on the slave device to enter the Error-Down state. + required: false + default: null + choices: ['enable','disable'] + state: + description: + - Specify desired state of the resource. + required: false + default: present + choices: ['present','absent'] + +''' + +EXAMPLES = ''' +- name: mlag interface 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: Set interface mlag error down + ce_mlag_interface: + interface: 10GE2/0/1 + mlag_error_down: enable + provider: "{{ cli }}" + - name: Create mlag + ce_mlag_interface: + eth_trunk_id: 1 + dfs_group_id: 1 + mlag_id: 4 + provider: "{{ cli }}" + - name: Set mlag global attribute + ce_mlag_interface: + mlag_system_id: 0020-1409-0407 + mlag_priority_id: 5 + provider: "{{ cli }}" + - name: Set mlag interface attribute + ce_mlag_interface: + eth_trunk_id: 1 + mlag_system_id: 0020-1409-0400 + mlag_priority_id: 3 + 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: { "interface": "eth-trunk1", + "mlag_error_down": "disable", + "state": "present" + } +existing: + description: k/v pairs of existing aaa server + returned: always + type: dict + sample: { "mlagErrorDownInfos": [ + { + "dfsgroupId": "1", + "portName": "Eth-Trunk1" + } + ] + } +end_state: + description: k/v pairs of aaa params after module execution + returned: always + type: dict + sample: {} +updates: + description: command sent to the device + returned: always + type: list + sample: { "interface eth-trunk1", + "undo m-lag unpaired-port suspend"} +''' + +import re +from xml.etree import ElementTree +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ce import load_config +from ansible.module_utils.ce import get_nc_config, set_nc_config, ce_argument_spec + +CE_NC_GET_MLAG_INFO = """ + + + + + + + + +""" + +CE_NC_CREATE_MLAG_INFO = """ + + + + + %s + %s + %s + + + + +""" + +CE_NC_DELETE_MLAG_INFO = """ + + + + + %s + %s + %s + + + + +""" + +CE_NC_GET_LACP_MLAG_INFO = """ + + + + + %s + + + + + + + + +""" + +CE_NC_SET_LACP_MLAG_INFO_HEAD = """ + + + + + %s + +""" + +CE_NC_SET_LACP_MLAG_INFO_TAIL = """ + + + + + +""" + +CE_NC_GET_GLOBAL_LACP_MLAG_INFO = """ + + + + + + + + + + +""" + +CE_NC_SET_GLOBAL_LACP_MLAG_INFO_HEAD = """ + + + + +""" + +CE_NC_SET_GLOBAL_LACP_MLAG_INFO_TAIL = """ + + + + +""" + +CE_NC_GET_MLAG_ERROR_DOWN_INFO = """ + + + + + + + + + + + + +""" + +CE_NC_CREATE_MLAG_ERROR_DOWN_INFO = """ + + + + + 1 + %s + + + + +""" + +CE_NC_DELETE_MLAG_ERROR_DOWN_INFO = """ + + + + + 1 + %s + + + + + +""" + + +def get_interface_type(interface): + """Gets the type of interface, such as 10GE, ETH-TRUNK, VLANIF...""" + + if interface is None: + return None + + iftype = None + + if interface.upper().startswith('GE'): + iftype = 'ge' + elif interface.upper().startswith('10GE'): + iftype = '10ge' + elif interface.upper().startswith('25GE'): + iftype = '25ge' + elif interface.upper().startswith('40GE'): + iftype = '40ge' + elif interface.upper().startswith('100GE'): + iftype = '100ge' + elif interface.upper().startswith('ETH-TRUNK'): + iftype = 'eth-trunk' + elif interface.upper().startswith('NULL'): + iftype = 'null' + else: + return None + + return iftype.lower() + + +class MlagInterface(object): + """ + Manages Manages MLAG interface information. + """ + + def __init__(self, argument_spec): + self.spec = argument_spec + self.module = None + self.init_module() + + # module input info + self.eth_trunk_id = self.module.params['eth_trunk_id'] + self.dfs_group_id = self.module.params['dfs_group_id'] + self.mlag_id = self.module.params['mlag_id'] + self.mlag_system_id = self.module.params['mlag_system_id'] + self.mlag_priority_id = self.module.params['mlag_priority_id'] + self.interface = self.module.params['interface'] + self.mlag_error_down = self.module.params['mlag_error_down'] + self.state = self.module.params['state'] + + # state + self.changed = False + self.updates_cmd = list() + self.results = dict() + self.existing = dict() + self.proposed = dict() + self.end_state = dict() + + # mlag info + self.commands = list() + self.mlag_info = None + self.mlag_global_info = None + self.mlag_error_down_info = None + self.mlag_trunk_attribute_info = None + + def init_module(self): + """ init module """ + + self.module = AnsibleModule( + argument_spec=self.spec, supports_check_mode=True) + + def check_response(self, xml_str, xml_name): + """Check if response message is already succeed.""" + + if "" not in xml_str: + self.module.fail_json(msg='Error: %s failed.' % xml_name) + + def cli_add_command(self, command, undo=False): + """add command to self.update_cmd and self.commands""" + + if undo and command.lower() not in ["quit", "return"]: + cmd = "undo " + command + else: + cmd = command + + self.commands.append(cmd) # set to device + if command.lower() not in ["quit", "return"]: + self.updates_cmd.append(cmd) # show updates result + + def cli_load_config(self, commands): + """load config by cli""" + + if not self.module.check_mode: + load_config(self.module, commands) + + def get_mlag_info(self): + """ get mlag info.""" + + mlag_info = dict() + conf_str = CE_NC_GET_MLAG_INFO + xml_str = get_nc_config(self.module, conf_str) + if "" in xml_str: + return mlag_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"', "") + + mlag_info["mlagInfos"] = list() + root = ElementTree.fromstring(xml_str) + dfs_mlag_infos = root.findall( + "data/mlag/mlagInstances/mlagInstance") + + if dfs_mlag_infos: + for dfs_mlag_info in dfs_mlag_infos: + mlag_dict = dict() + for ele in dfs_mlag_info: + if ele.tag in ["dfsgroupId", "mlagId", "localMlagPort"]: + mlag_dict[ele.tag] = ele.text + mlag_info["mlagInfos"].append(mlag_dict) + return mlag_info + + def get_mlag_global_info(self): + """ get mlag global info.""" + + mlag_global_info = dict() + conf_str = CE_NC_GET_GLOBAL_LACP_MLAG_INFO + xml_str = get_nc_config(self.module, conf_str) + if "" in xml_str: + return mlag_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( + "data/ifmtrunk/lacpSysInfo/lacpMlagGlobal") + + if global_info: + for tmp in global_info: + for site in tmp: + if site.tag in ["lacpMlagSysId", "lacpMlagPriority"]: + mlag_global_info[site.tag] = site.text + return mlag_global_info + + def get_mlag_trunk_attribute_info(self): + """ get mlag global info.""" + + mlag_trunk_attribute_info = dict() + eth_trunk = "Eth-Trunk" + eth_trunk += self.eth_trunk_id + conf_str = CE_NC_GET_LACP_MLAG_INFO % eth_trunk + xml_str = get_nc_config(self.module, conf_str) + if "" in xml_str: + return mlag_trunk_attribute_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( + "data/ifmtrunk/TrunkIfs/TrunkIf/lacpMlagIf") + + if global_info: + for tmp in global_info: + for site in tmp: + if site.tag in ["lacpMlagSysId", "lacpMlagPriority"]: + mlag_trunk_attribute_info[site.tag] = site.text + return mlag_trunk_attribute_info + + def get_mlag_error_down_info(self): + """ get error down info.""" + + mlag_error_down_info = dict() + conf_str = CE_NC_GET_MLAG_ERROR_DOWN_INFO + xml_str = get_nc_config(self.module, conf_str) + if "" in xml_str: + return mlag_error_down_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"', "") + + mlag_error_down_info["mlagErrorDownInfos"] = list() + root = ElementTree.fromstring(xml_str) + mlag_error_infos = root.findall( + "data/mlag/errordowns/errordown") + + if mlag_error_infos: + for mlag_error_info in mlag_error_infos: + mlag_error_dict = dict() + for ele in mlag_error_info: + if ele.tag in ["dfsgroupId", "portName"]: + mlag_error_dict[ele.tag] = ele.text + mlag_error_down_info[ + "mlagErrorDownInfos"].append(mlag_error_dict) + return mlag_error_down_info + + def check_macaddr(self): + """check mac-address whether valid""" + + valid_char = '0123456789abcdef-' + mac = self.mlag_system_id + + if len(mac) > 16: + return False + + mac_list = re.findall(r'([0-9a-fA-F]+)', mac) + if len(mac_list) != 3: + return False + + if mac.count('-') != 2: + return False + + for _, value in enumerate(mac, start=0): + if value.lower() not in valid_char: + return False + + return True + + def check_params(self): + """Check all input params""" + + # eth_trunk_id check + if self.eth_trunk_id: + if not self.eth_trunk_id.isdigit(): + self.module.fail_json( + msg='Error: The value of eth_trunk_id is an integer.') + if int(self.eth_trunk_id) < 0 or int(self.eth_trunk_id) > 511: + self.module.fail_json( + msg='Error: The value of eth_trunk_id is not in the range from 0 to 511.') + + # dfs_group_id check + if self.dfs_group_id: + if self.dfs_group_id != "1": + self.module.fail_json( + msg='Error: The value of dfs_group_id must be 1.') + + # mlag_id check + if self.mlag_id: + if not self.mlag_id.isdigit(): + self.module.fail_json( + msg='Error: The value of mlag_id is an integer.') + if int(self.mlag_id) < 1 or int(self.mlag_id) > 2048: + self.module.fail_json( + msg='Error: The value of mlag_id is not in the range from 1 to 2048.') + + # mlag_system_id check + if self.mlag_system_id: + if not self.check_macaddr(): + self.module.fail_json( + msg="Error: mlag_system_id has invalid value %s." % self.mlag_system_id) + + # mlag_priority_id check + if self.mlag_priority_id: + if not self.mlag_priority_id.isdigit(): + self.module.fail_json( + msg='Error: The value of mlag_priority_id is an integer.') + if int(self.mlag_priority_id) < 0 or int(self.mlag_priority_id) > 254: + self.module.fail_json( + msg='Error: The value of mlag_priority_id is not in the range from 0 to 254.') + + # interface check + if self.interface: + intf_type = get_interface_type(self.interface) + if not intf_type: + self.module.fail_json( + msg='Error: Interface name of %s ' + 'is error.' % self.interface) + + def is_mlag_info_change(self): + """whether mlag info change""" + + if not self.mlag_info: + return True + + eth_trunk = "Eth-Trunk" + eth_trunk += self.eth_trunk_id + for info in self.mlag_info["mlagInfos"]: + if info["mlagId"] == self.mlag_id and info["localMlagPort"] == eth_trunk: + return False + return True + + def is_mlag_info_exist(self): + """whether mlag info exist""" + + if not self.mlag_info: + return False + + eth_trunk = "Eth-Trunk" + eth_trunk += self.eth_trunk_id + + for info in self.mlag_info["mlagInfos"]: + if info["mlagId"] == self.mlag_id and info["localMlagPort"] == eth_trunk: + return True + return False + + def is_mlag_error_down_info_change(self): + """whether mlag error down info change""" + + if not self.mlag_error_down_info: + return True + + for info in self.mlag_error_down_info["mlagErrorDownInfos"]: + if info["portName"].upper() == self.interface.upper(): + return False + return True + + def is_mlag_error_down_info_exist(self): + """whether mlag error down info exist""" + + if not self.mlag_error_down_info: + return False + + for info in self.mlag_error_down_info["mlagErrorDownInfos"]: + if info["portName"].upper() == self.interface.upper(): + return True + return False + + def is_mlag_interface_info_change(self): + """whether mlag interface attribute info change""" + + if not self.mlag_trunk_attribute_info: + return True + + if self.mlag_system_id: + if self.mlag_trunk_attribute_info["lacpMlagSysId"] != self.mlag_system_id: + return True + if self.mlag_priority_id: + if self.mlag_trunk_attribute_info["lacpMlagPriority"] != self.mlag_priority_id: + return True + return False + + def is_mlag_interface_info_exist(self): + """whether mlag interface attribute info exist""" + + if not self.mlag_trunk_attribute_info: + return False + + if self.mlag_system_id: + if self.mlag_priority_id: + if self.mlag_trunk_attribute_info["lacpMlagSysId"] == self.mlag_system_id \ + and self.mlag_trunk_attribute_info["lacpMlagPriority"] == self.mlag_priority_id: + return True + else: + if self.mlag_trunk_attribute_info["lacpMlagSysId"] == self.mlag_system_id: + return True + + if self.mlag_priority_id: + if self.mlag_system_id: + if self.mlag_trunk_attribute_info["lacpMlagSysId"] == self.mlag_system_id \ + and self.mlag_trunk_attribute_info["lacpMlagPriority"] == self.mlag_priority_id: + return True + else: + if self.mlag_trunk_attribute_info["lacpMlagPriority"] == self.mlag_priority_id: + return True + + return False + + def is_mlag_global_info_change(self): + """whether mlag global attribute info change""" + + if not self.mlag_global_info: + return True + + if self.mlag_system_id: + if self.mlag_global_info["lacpMlagSysId"] != self.mlag_system_id: + return True + if self.mlag_priority_id: + if self.mlag_global_info["lacpMlagPriority"] != self.mlag_priority_id: + return True + return False + + def is_mlag_global_info_exist(self): + """whether mlag global attribute info exist""" + + if not self.mlag_global_info: + return False + + if self.mlag_system_id: + if self.mlag_priority_id: + if self.mlag_global_info["lacpMlagSysId"] == self.mlag_system_id \ + and self.mlag_global_info["lacpMlagPriority"] == self.mlag_priority_id: + return True + else: + if self.mlag_global_info["lacpMlagSysId"] == self.mlag_system_id: + return True + + if self.mlag_priority_id: + if self.mlag_system_id: + if self.mlag_global_info["lacpMlagSysId"] == self.mlag_system_id \ + and self.mlag_global_info["lacpMlagPriority"] == self.mlag_priority_id: + return True + else: + if self.mlag_global_info["lacpMlagPriority"] == self.mlag_priority_id: + return True + + return False + + def create_mlag(self): + """create mlag info""" + + if self.is_mlag_info_change(): + mlag_port = "Eth-Trunk" + mlag_port += self.eth_trunk_id + conf_str = CE_NC_CREATE_MLAG_INFO % ( + self.dfs_group_id, self.mlag_id, mlag_port) + recv_xml = set_nc_config(self.module, conf_str) + if "" not in recv_xml: + self.module.fail_json( + msg='Error: create mlag info failed.') + + self.updates_cmd.append("interface %s" % mlag_port) + self.updates_cmd.append("dfs-group %s m-lag %s" % + (self.dfs_group_id, self.mlag_id)) + self.changed = True + + def delete_mlag(self): + """delete mlag info""" + + if self.is_mlag_info_exist(): + mlag_port = "Eth-Trunk" + mlag_port += self.eth_trunk_id + conf_str = CE_NC_DELETE_MLAG_INFO % ( + self.dfs_group_id, self.mlag_id, mlag_port) + recv_xml = set_nc_config(self.module, conf_str) + if "" not in recv_xml: + self.module.fail_json( + msg='Error: delete mlag info failed.') + + self.updates_cmd.append("interface %s" % mlag_port) + self.updates_cmd.append( + "undo dfs-group %s m-lag %s" % (self.dfs_group_id, self.mlag_id)) + self.changed = True + + def create_mlag_error_down(self): + """create mlag error down info""" + + if self.is_mlag_error_down_info_change(): + conf_str = CE_NC_CREATE_MLAG_ERROR_DOWN_INFO % self.interface + recv_xml = set_nc_config(self.module, conf_str) + if "" not in recv_xml: + self.module.fail_json( + msg='Error: create mlag error down info failed.') + + self.updates_cmd.append("interface %s" % self.interface) + self.updates_cmd.append("m-lag unpaired-port suspend") + self.changed = True + + def delete_mlag_error_down(self): + """delete mlag error down info""" + + if self.is_mlag_error_down_info_exist(): + + conf_str = CE_NC_DELETE_MLAG_ERROR_DOWN_INFO % self.interface + recv_xml = set_nc_config(self.module, conf_str) + if "" not in recv_xml: + self.module.fail_json( + msg='Error: delete mlag error down info failed.') + + self.updates_cmd.append("interface %s" % self.interface) + self.updates_cmd.append("undo m-lag unpaired-port suspend") + self.changed = True + + def set_mlag_interface(self): + """set mlag interface atrribute info""" + + if self.is_mlag_interface_info_change(): + mlag_port = "Eth-Trunk" + mlag_port += self.eth_trunk_id + conf_str = CE_NC_SET_LACP_MLAG_INFO_HEAD % mlag_port + if self.mlag_priority_id: + conf_str += "%s" % self.mlag_priority_id + if self.mlag_system_id: + conf_str += "%s" % self.mlag_system_id + conf_str += CE_NC_SET_LACP_MLAG_INFO_TAIL + recv_xml = set_nc_config(self.module, conf_str) + if "" not in recv_xml: + self.module.fail_json( + msg='Error: set mlag interface atrribute info failed.') + + self.updates_cmd.append("interface %s" % mlag_port) + if self.mlag_priority_id: + self.updates_cmd.append( + "lacp m-lag priority %s" % self.mlag_priority_id) + + if self.mlag_system_id: + self.updates_cmd.append( + "lacp m-lag system-id %s" % self.mlag_system_id) + self.changed = True + + def delete_mlag_interface(self): + """delete mlag interface attribute info""" + + if self.is_mlag_interface_info_exist(): + mlag_port = "Eth-Trunk" + mlag_port += self.eth_trunk_id + + cmd = "interface %s" % mlag_port + self.cli_add_command(cmd) + + if self.mlag_priority_id: + cmd = "lacp m-lag priority %s" % self.mlag_priority_id + self.cli_add_command(cmd, True) + + if self.mlag_system_id: + cmd = "lacp m-lag system-id %s" % self.mlag_system_id + self.cli_add_command(cmd, True) + + if self.commands: + self.cli_load_config(self.commands) + self.changed = True + + def set_mlag_global(self): + """set mlag global attribute info""" + + if self.is_mlag_global_info_change(): + conf_str = CE_NC_SET_GLOBAL_LACP_MLAG_INFO_HEAD + if self.mlag_priority_id: + conf_str += "%s" % self.mlag_priority_id + if self.mlag_system_id: + conf_str += "%s" % self.mlag_system_id + conf_str += CE_NC_SET_GLOBAL_LACP_MLAG_INFO_TAIL + recv_xml = set_nc_config(self.module, conf_str) + if "" not in recv_xml: + self.module.fail_json( + msg='Error: set mlag interface atrribute info failed.') + + if self.mlag_priority_id: + self.updates_cmd.append( + "lacp m-lag priority %s" % self.mlag_priority_id) + + if self.mlag_system_id: + self.updates_cmd.append( + "lacp m-lag system-id %s" % self.mlag_system_id) + self.changed = True + + def delete_mlag_global(self): + """delete mlag global attribute info""" + + if self.is_mlag_global_info_exist(): + if self.mlag_priority_id: + cmd = "lacp m-lag priority %s" % self.mlag_priority_id + self.cli_add_command(cmd, True) + + if self.mlag_system_id: + cmd = "lacp m-lag system-id %s" % self.mlag_system_id + self.cli_add_command(cmd, True) + + if self.commands: + self.cli_load_config(self.commands) + self.changed = True + + def get_proposed(self): + """get proposed info""" + + if self.eth_trunk_id: + self.proposed["eth_trunk_id"] = self.eth_trunk_id + if self.dfs_group_id: + self.proposed["dfs_group_id"] = self.dfs_group_id + if self.mlag_id: + self.proposed["mlag_id"] = self.mlag_id + if self.mlag_system_id: + self.proposed["mlag_system_id"] = self.mlag_system_id + if self.mlag_priority_id: + self.proposed["mlag_priority_id"] = self.mlag_priority_id + if self.interface: + self.proposed["interface"] = self.interface + if self.mlag_error_down: + self.proposed["mlag_error_down"] = self.mlag_error_down + if self.state: + self.proposed["state"] = self.state + + def get_existing(self): + """get existing info""" + + self.mlag_info = self.get_mlag_info() + self.mlag_global_info = self.get_mlag_global_info() + self.mlag_error_down_info = self.get_mlag_error_down_info() + + if self.eth_trunk_id or self.dfs_group_id or self.mlag_id: + if not self.mlag_system_id and not self.mlag_priority_id: + if self.mlag_info: + self.existing["mlagInfos"] = self.mlag_info["mlagInfos"] + + if self.mlag_system_id or self.mlag_priority_id: + if self.eth_trunk_id: + if self.mlag_trunk_attribute_info: + if self.mlag_system_id: + self.end_state["lacpMlagSysId"] = self.mlag_trunk_attribute_info[ + "lacpMlagSysId"] + if self.mlag_priority_id: + self.end_state["lacpMlagPriority"] = self.mlag_trunk_attribute_info[ + "lacpMlagPriority"] + else: + if self.mlag_global_info: + if self.mlag_system_id: + self.end_state["lacpMlagSysId"] = self.mlag_global_info[ + "lacpMlagSysId"] + if self.mlag_priority_id: + self.end_state["lacpMlagPriority"] = self.mlag_global_info[ + "lacpMlagPriority"] + + if self.interface or self.mlag_error_down: + if self.mlag_error_down_info: + self.existing["mlagErrorDownInfos"] = self.mlag_error_down_info[ + "mlagErrorDownInfos"] + + def get_end_state(self): + """get end state info""" + + if self.eth_trunk_id or self.dfs_group_id or self.mlag_id: + self.mlag_info = self.get_mlag_info() + if not self.mlag_system_id and not self.mlag_priority_id: + if self.mlag_info: + self.end_state["mlagInfos"] = self.mlag_info["mlagInfos"] + + if self.mlag_system_id or self.mlag_priority_id: + if self.eth_trunk_id: + self.mlag_trunk_attribute_info = self.get_mlag_trunk_attribute_info() + if self.mlag_trunk_attribute_info: + if self.mlag_system_id: + self.end_state["lacpMlagSysId"] = self.mlag_trunk_attribute_info[ + "lacpMlagSysId"] + if self.mlag_priority_id: + self.end_state["lacpMlagPriority"] = self.mlag_trunk_attribute_info[ + "lacpMlagPriority"] + else: + self.mlag_global_info = self.get_mlag_global_info() + if self.mlag_global_info: + if self.mlag_system_id: + self.end_state["lacpMlagSysId"] = self.mlag_global_info[ + "lacpMlagSysId"] + if self.mlag_priority_id: + self.end_state["lacpMlagPriority"] = self.mlag_global_info[ + "lacpMlagPriority"] + + if self.interface or self.mlag_error_down: + self.mlag_error_down_info = self.get_mlag_error_down_info() + if self.mlag_error_down_info: + self.end_state["mlagErrorDownInfos"] = self.mlag_error_down_info[ + "mlagErrorDownInfos"] + + def work(self): + """worker""" + + self.check_params() + self.get_proposed() + self.get_existing() + + if self.eth_trunk_id or self.dfs_group_id or self.mlag_id: + self.mlag_info = self.get_mlag_info() + if self.eth_trunk_id and self.dfs_group_id and self.mlag_id: + if self.state == "present": + self.create_mlag() + else: + self.delete_mlag() + else: + if not self.mlag_system_id and not self.mlag_priority_id: + self.module.fail_json( + msg='Error: eth_trunk_id, dfs_group_id, mlag_id must be config at the same time.') + + if self.mlag_system_id or self.mlag_priority_id: + + if self.eth_trunk_id: + self.mlag_trunk_attribute_info = self.get_mlag_trunk_attribute_info() + if self.mlag_system_id or self.mlag_priority_id: + if self.state == "present": + self.set_mlag_interface() + else: + self.delete_mlag_interface() + else: + self.mlag_global_info = self.get_mlag_global_info() + if self.mlag_system_id or self.mlag_priority_id: + if self.state == "present": + self.set_mlag_global() + else: + self.delete_mlag_global() + + if self.interface or self.mlag_error_down: + self.mlag_error_down_info = self.get_mlag_error_down_info() + if self.interface and self.mlag_error_down: + if self.mlag_error_down == "enable": + self.create_mlag_error_down() + else: + self.delete_mlag_error_down() + else: + self.module.fail_json( + msg='Error: interface, mlag_error_down must be config at the same time.') + + 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( + eth_trunk_id=dict(type='str'), + dfs_group_id=dict(type='str'), + mlag_id=dict(type='str'), + mlag_system_id=dict(type='str'), + mlag_priority_id=dict(type='str'), + interface=dict(type='str'), + mlag_error_down=dict(type='str', choices=['enable', 'disable']), + state=dict(type='str', default='present', + choices=['present', 'absent']) + ) + argument_spec.update(ce_argument_spec) + module = MlagInterface(argument_spec=argument_spec) + module.work() + + +if __name__ == '__main__': + main()