#!/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_vrrp short_description: Manages VRRP interfaces on HUAWEI CloudEngine devices. description: - Manages VRRP interface attributes on HUAWEI CloudEngine devices. author: - Li Yanfeng (@numone213) 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: interface: description: - Name of an interface. The value is a string of 1 to 63 characters. vrid: description: - VRRP backup group ID. The value is an integer ranging from 1 to 255. default: present virtual_ip : description: - Virtual IP address. The value is a string of 0 to 255 characters. vrrp_type: description: - Type of a VRRP backup group. type: str choices: ['normal', 'member', 'admin'] admin_ignore_if_down: description: - mVRRP ignores an interface Down event. type: bool default: 'false' admin_vrid: description: - Tracked mVRRP ID. The value is an integer ranging from 1 to 255. admin_interface: description: - Tracked mVRRP interface name. The value is a string of 1 to 63 characters. admin_flowdown: description: - Disable the flowdown function for service VRRP. type: bool default: 'false' priority: description: - Configured VRRP priority. The value ranges from 1 to 254. The default value is 100. A larger value indicates a higher priority. version: description: - VRRP version. The default version is v2. type: str choices: ['v2','v3'] advertise_interval: description: - Configured interval between sending advertisements, in milliseconds. Only the master router sends VRRP advertisements. The default value is 1000 milliseconds. preempt_timer_delay: description: - Preemption delay. The value is an integer ranging from 0 to 3600. The default value is 0. gratuitous_arp_interval: description: - Interval at which gratuitous ARP packets are sent, in seconds. The value ranges from 30 to 1200.The default value is 300. recover_delay: description: - Delay in recovering after an interface goes Up. The delay is used for interface flapping suppression. The value is an integer ranging from 0 to 3600. The default value is 0 seconds. holding_multiplier: description: - The configured holdMultiplier.The value is an integer ranging from 3 to 10. The default value is 3. auth_mode: description: - Authentication type used for VRRP packet exchanges between virtual routers. The values are noAuthentication, simpleTextPassword, md5Authentication. The default value is noAuthentication. type: str choices: ['simple','md5','none'] is_plain: description: - Select the display mode of an authentication key. By default, an authentication key is displayed in ciphertext. type: bool default: 'false' auth_key: description: - This object is set based on the authentication type. When noAuthentication is specified, the value is empty. When simpleTextPassword or md5Authentication is specified, the value is a string of 1 to 8 characters in plaintext and displayed as a blank text for security. fast_resume: description: - mVRRP's fast resume mode. type: str choices: ['enable','disable'] state: description: - Specify desired state of the resource. type: str default: present choices: ['present','absent'] ''' EXAMPLES = ''' - name: vrrp 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 vrrp version ce_vrrp: version: v3 provider: "{{ cli }}" - name: Set vrrp gratuitous-arp interval ce_vrrp: gratuitous_arp_interval: 40 mlag_id: 4 provider: "{{ cli }}" - name: Set vrrp recover-delay ce_vrrp: recover_delay: 10 provider: "{{ cli }}" - name: Set vrrp vrid virtual-ip ce_vrrp: interface: 40GE2/0/8 vrid: 1 virtual_ip: 10.14.2.7 provider: "{{ cli }}" - name: Set vrrp vrid admin ce_vrrp: interface: 40GE2/0/8 vrid: 1 vrrp_type: admin provider: "{{ cli }}" - name: Set vrrp vrid fast_resume ce_vrrp: interface: 40GE2/0/8 vrid: 1 fast_resume: enable provider: "{{ cli }}" - name: Set vrrp vrid holding-multiplier ce_vrrp: interface: 40GE2/0/8 vrid: 1 holding_multiplier: 4 provider: "{{ cli }}" - name: Set vrrp vrid preempt timer delay ce_vrrp: interface: 40GE2/0/8 vrid: 1 preempt_timer_delay: 10 provider: "{{ cli }}" - name: Set vrrp vrid admin-vrrp ce_vrrp: interface: 40GE2/0/8 vrid: 1 admin_interface: 40GE2/0/9 admin_vrid: 2 vrrp_type: member provider: "{{ cli }}" - name: Set vrrp vrid authentication-mode ce_vrrp: interface: 40GE2/0/8 vrid: 1 is_plain: true auth_mode: simple auth_key: aaa provider: "{{ cli }}" ''' RETURN = ''' changed: description: check to see if a change was made on the device returned: always type: bool sample: true proposed: description: k/v pairs of parameters passed into module returned: always type: dict sample: { "auth_key": "aaa", "auth_mode": "simple", "interface": "40GE2/0/8", "is_plain": true, "state": "present", "vrid": "1" } existing: description: k/v pairs of existing aaa server returned: always type: dict sample: { "auth_mode": "none", "interface": "40GE2/0/8", "is_plain": "false", "vrid": "1", "vrrp_type": "normal" } end_state: description: k/v pairs of aaa params after module execution returned: always type: dict sample: { "auth_mode": "simple", "interface": "40GE2/0/8", "is_plain": "true", "vrid": "1", "vrrp_type": "normal" } updates: description: command sent to the device returned: always type: list sample: { "interface 40GE2/0/8", "vrrp vrid 1 authentication-mode simple plain aaa"} ''' from xml.etree import ElementTree from ansible.module_utils.basic import AnsibleModule from ansible_collections.community.general.plugins.module_utils.network.cloudengine.ce import get_nc_config, set_nc_config, ce_argument_spec CE_NC_GET_VRRP_GROUP_INFO = """ %s %s """ CE_NC_SET_VRRP_GROUP_INFO_HEAD = """ %s %s """ CE_NC_SET_VRRP_GROUP_INFO_TAIL = """ """ CE_NC_GET_VRRP_GLOBAL_INFO = """ """ CE_NC_SET_VRRP_GLOBAL_HEAD = """ """ CE_NC_SET_VRRP_GLOBAL_TAIL = """ """ CE_NC_GET_VRRP_VIRTUAL_IP_INFO = """ %s %s """ CE_NC_CREATE_VRRP_VIRTUAL_IP_INFO = """ %s %s %s """ CE_NC_DELETE_VRRP_VIRTUAL_IP_INFO = """ %s %s %s """ def is_valid_address(address): """check ip-address is valid""" if address.find('.') != -1: addr_list = address.split('.') if len(addr_list) != 4: return False for each_num in addr_list: if not each_num.isdigit(): return False if int(each_num) > 255: return False return True return False 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' elif interface.upper().startswith('VLANIF'): iftype = 'vlanif' else: return None return iftype.lower() class Vrrp(object): """ Manages Manages vrrp information. """ def __init__(self, argument_spec): self.spec = argument_spec self.module = None self.init_module() # module input info self.interface = self.module.params['interface'] self.vrid = self.module.params['vrid'] self.virtual_ip = self.module.params['virtual_ip'] self.vrrp_type = self.module.params['vrrp_type'] self.admin_ignore_if_down = 'false' if self.module.params['admin_ignore_if_down'] is False else 'true' self.admin_vrid = self.module.params['admin_vrid'] self.admin_interface = self.module.params['admin_interface'] self.admin_flowdown = 'false' if self.module.params['admin_flowdown'] is False else 'true' self.priority = self.module.params['priority'] self.version = self.module.params['version'] self.advertise_interval = self.module.params['advertise_interval'] self.preempt_timer_delay = self.module.params['preempt_timer_delay'] self.gratuitous_arp_interval = self.module.params[ 'gratuitous_arp_interval'] self.recover_delay = self.module.params['recover_delay'] self.holding_multiplier = self.module.params['holding_multiplier'] self.auth_mode = self.module.params['auth_mode'] self.is_plain = 'false' if self.module.params['is_plain'] is False else 'true' self.auth_key = self.module.params['auth_key'] self.fast_resume = self.module.params['fast_resume'] self.state = self.module.params['state'] # vrrp info self.vrrp_global_info = None self.virtual_ip_info = None self.vrrp_group_info = None # state self.changed = False self.updates_cmd = list() self.results = dict() self.existing = dict() self.proposed = dict() self.end_state = dict() def init_module(self): """ init module """ self.module = AnsibleModule( argument_spec=self.spec, supports_check_mode=True) def get_virtual_ip_info(self): """ get vrrp virtual ip info.""" virtual_ip_info = dict() conf_str = CE_NC_GET_VRRP_VIRTUAL_IP_INFO % (self.vrid, self.interface) xml_str = get_nc_config(self.module, conf_str) if "" in xml_str: return virtual_ip_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"', "") virtual_ip_info["vrrpVirtualIpInfos"] = list() root = ElementTree.fromstring(xml_str) vrrp_virtual_ip_infos = root.findall( "vrrp/vrrpGroups/vrrpGroup/virtualIps/virtualIp") if vrrp_virtual_ip_infos: for vrrp_virtual_ip_info in vrrp_virtual_ip_infos: virtual_ip_dict = dict() for ele in vrrp_virtual_ip_info: if ele.tag in ["virtualIpAddress"]: virtual_ip_dict[ele.tag] = ele.text virtual_ip_info["vrrpVirtualIpInfos"].append( virtual_ip_dict) return virtual_ip_info def get_vrrp_global_info(self): """ get vrrp global info.""" vrrp_global_info = dict() conf_str = CE_NC_GET_VRRP_GLOBAL_INFO xml_str = get_nc_config(self.module, conf_str) if "" in xml_str: return vrrp_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( "vrrp/vrrpGlobalCfg") if global_info: for tmp in global_info: for site in tmp: if site.tag in ["gratuitousArpTimeOut", "gratuitousArpFlag", "recoverDelay", "version"]: vrrp_global_info[site.tag] = site.text return vrrp_global_info def get_vrrp_group_info(self): """ get vrrp group info.""" vrrp_group_info = dict() conf_str = CE_NC_GET_VRRP_GROUP_INFO % (self.interface, self.vrid) xml_str = get_nc_config(self.module, conf_str) if "" in xml_str: return vrrp_group_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( "vrrp/vrrpGroups/vrrpGroup") if global_info: for tmp in global_info: for site in tmp: if site.tag in ["ifName", "vrrpId", "priority", "advertiseInterval", "preemptMode", "delayTime", "authenticationMode", "authenticationKey", "vrrpType", "adminVrrpId", "adminIfName", "adminIgnoreIfDown", "isPlain", "unflowdown", "fastResume", "holdMultiplier"]: vrrp_group_info[site.tag] = site.text return vrrp_group_info def check_params(self): """Check all input params""" # 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) # vrid check if self.vrid: if not self.vrid.isdigit(): self.module.fail_json( msg='Error: The value of vrid is an integer.') if int(self.vrid) < 1 or int(self.vrid) > 255: self.module.fail_json( msg='Error: The value of vrid ranges from 1 to 255.') # virtual_ip check if self.virtual_ip: if not is_valid_address(self.virtual_ip): self.module.fail_json( msg='Error: The %s is not a valid ip address.' % self.virtual_ip) # admin_vrid check if self.admin_vrid: if not self.admin_vrid.isdigit(): self.module.fail_json( msg='Error: The value of admin_vrid is an integer.') if int(self.admin_vrid) < 1 or int(self.admin_vrid) > 255: self.module.fail_json( msg='Error: The value of admin_vrid ranges from 1 to 255.') # admin_interface check if self.admin_interface: intf_type = get_interface_type(self.admin_interface) if not intf_type: self.module.fail_json( msg='Error: Admin interface name of %s ' 'is error.' % self.admin_interface) # priority check if self.priority: if not self.priority.isdigit(): self.module.fail_json( msg='Error: The value of priority is an integer.') if int(self.priority) < 1 or int(self.priority) > 254: self.module.fail_json( msg='Error: The value of priority ranges from 1 to 254. The default value is 100.') # advertise_interval check if self.advertise_interval: if not self.advertise_interval.isdigit(): self.module.fail_json( msg='Error: The value of advertise_interval is an integer.') if int(self.advertise_interval) < 1000 or int(self.advertise_interval) > 255000: self.module.fail_json( msg='Error: The value of advertise_interval ranges from 1000 to 255000 milliseconds. The default value is 1000 milliseconds.') if int(self.advertise_interval) % 1000 != 0: self.module.fail_json( msg='Error: The advertisement interval value of VRRP must be a multiple of 1000 milliseconds.') # preempt_timer_delay check if self.preempt_timer_delay: if not self.preempt_timer_delay.isdigit(): self.module.fail_json( msg='Error: The value of preempt_timer_delay is an integer.') if int(self.preempt_timer_delay) < 1 or int(self.preempt_timer_delay) > 3600: self.module.fail_json( msg='Error: The value of preempt_timer_delay ranges from 1 to 3600. The default value is 0.') # holding_multiplier check if self.holding_multiplier: if not self.holding_multiplier.isdigit(): self.module.fail_json( msg='Error: The value of holding_multiplier is an integer.') if int(self.holding_multiplier) < 3 or int(self.holding_multiplier) > 10: self.module.fail_json( msg='Error: The value of holding_multiplier ranges from 3 to 10. The default value is 3.') # auth_key check if self.auth_key: if len(self.auth_key) > 16 \ or len(self.auth_key.replace(' ', '')) < 1: self.module.fail_json( msg='Error: The length of auth_key is not in the range from 1 to 16.') def is_virtual_ip_change(self): """whether virtual ip change""" if not self.virtual_ip_info: return True for info in self.virtual_ip_info["vrrpVirtualIpInfos"]: if info["virtualIpAddress"] == self.virtual_ip: return False return True def is_virtual_ip_exist(self): """whether virtual ip info exist""" if not self.virtual_ip_info: return False for info in self.virtual_ip_info["vrrpVirtualIpInfos"]: if info["virtualIpAddress"] == self.virtual_ip: return True return False def is_vrrp_global_info_change(self): """whether vrrp global attribute info change""" if not self.vrrp_global_info: return True if self.gratuitous_arp_interval: if self.vrrp_global_info["gratuitousArpFlag"] == "false": self.module.fail_json(msg="Error: gratuitousArpFlag is false.") if self.vrrp_global_info["gratuitousArpTimeOut"] != self.gratuitous_arp_interval: return True if self.recover_delay: if self.vrrp_global_info["recoverDelay"] != self.recover_delay: return True if self.version: if self.vrrp_global_info["version"] != self.version: return True return False def is_vrrp_global_info_exist(self): """whether vrrp global attribute info exist""" if self.gratuitous_arp_interval or self.recover_delay or self.version: if self.gratuitous_arp_interval: if self.vrrp_global_info["gratuitousArpFlag"] == "false": self.module.fail_json( msg="Error: gratuitousArpFlag is false.") if self.vrrp_global_info["gratuitousArpTimeOut"] != self.gratuitous_arp_interval: return False if self.recover_delay: if self.vrrp_global_info["recoverDelay"] != self.recover_delay: return False if self.version: if self.vrrp_global_info["version"] != self.version: return False return True return False def is_vrrp_group_info_change(self): """whether vrrp group attribute info change""" if self.vrrp_type: if self.vrrp_group_info["vrrpType"] != self.vrrp_type: return True if self.admin_ignore_if_down: if self.vrrp_group_info["adminIgnoreIfDown"] != self.admin_ignore_if_down: return True if self.admin_vrid: if self.vrrp_group_info["adminVrrpId"] != self.admin_vrid: return True if self.admin_interface: if self.vrrp_group_info["adminIfName"] != self.admin_interface: return True if self.admin_flowdown: if self.vrrp_group_info["unflowdown"] != self.admin_flowdown: return True if self.priority: if self.vrrp_group_info["priority"] != self.priority: return True if self.fast_resume: fast_resume = "false" if self.fast_resume == "enable": fast_resume = "true" if self.vrrp_group_info["fastResume"] != fast_resume: return True if self.advertise_interval: if self.vrrp_group_info["advertiseInterval"] != self.advertise_interval: return True if self.preempt_timer_delay: if self.vrrp_group_info["delayTime"] != self.preempt_timer_delay: return True if self.holding_multiplier: if self.vrrp_group_info["holdMultiplier"] != self.holding_multiplier: return True if self.auth_mode: if self.vrrp_group_info["authenticationMode"] != self.auth_mode: return True if self.auth_key: return True if self.is_plain: if self.vrrp_group_info["isPlain"] != self.is_plain: return True return False def is_vrrp_group_info_exist(self): """whether vrrp group attribute info exist""" if self.vrrp_type: if self.vrrp_group_info["vrrpType"] != self.vrrp_type: return False if self.admin_ignore_if_down: if self.vrrp_group_info["adminIgnoreIfDown"] != self.admin_ignore_if_down: return False if self.admin_vrid: if self.vrrp_group_info["adminVrrpId"] != self.admin_vrid: return False if self.admin_interface: if self.vrrp_group_info["adminIfName"] != self.admin_interface: return False if self.admin_flowdown: if self.vrrp_group_info["unflowdown"] != self.admin_flowdown: return False if self.priority: if self.vrrp_group_info["priority"] != self.priority: return False if self.fast_resume: fast_resume = "false" if self.fast_resume == "enable": fast_resume = "true" if self.vrrp_group_info["fastResume"] != fast_resume: return False if self.advertise_interval: if self.vrrp_group_info["advertiseInterval"] != self.advertise_interval: return False if self.preempt_timer_delay: if self.vrrp_group_info["delayTime"] != self.preempt_timer_delay: return False if self.holding_multiplier: if self.vrrp_group_info["holdMultiplier"] != self.holding_multiplier: return False if self.auth_mode: if self.vrrp_group_info["authenticationMode"] != self.auth_mode: return False if self.is_plain: if self.vrrp_group_info["isPlain"] != self.is_plain: return False return True def create_virtual_ip(self): """create virtual ip info""" if self.is_virtual_ip_change(): conf_str = CE_NC_CREATE_VRRP_VIRTUAL_IP_INFO % ( self.vrid, self.interface, self.virtual_ip) recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json( msg='Error: create virtual ip info failed.') self.updates_cmd.append("interface %s" % self.interface) self.updates_cmd.append( "vrrp vrid %s virtual-ip %s" % (self.vrid, self.virtual_ip)) self.changed = True def delete_virtual_ip(self): """delete virtual ip info""" if self.is_virtual_ip_exist(): conf_str = CE_NC_DELETE_VRRP_VIRTUAL_IP_INFO % ( self.vrid, self.interface, self.virtual_ip) recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json( msg='Error: delete virtual ip info failed.') self.updates_cmd.append("interface %s" % self.interface) self.updates_cmd.append( "undo vrrp vrid %s virtual-ip %s " % (self.vrid, self.virtual_ip)) self.changed = True def set_vrrp_global(self): """set vrrp global attribute info""" if self.is_vrrp_global_info_change(): conf_str = CE_NC_SET_VRRP_GLOBAL_HEAD if self.gratuitous_arp_interval: conf_str += "%s" % self.gratuitous_arp_interval if self.recover_delay: conf_str += "%s" % self.recover_delay if self.version: conf_str += "%s" % self.version conf_str += CE_NC_SET_VRRP_GLOBAL_TAIL recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json( msg='Error: set vrrp global attribute info failed.') if self.gratuitous_arp_interval: self.updates_cmd.append( "vrrp gratuitous-arp interval %s" % self.gratuitous_arp_interval) if self.recover_delay: self.updates_cmd.append( "vrrp recover-delay %s" % self.recover_delay) if self.version: version = "3" if self.version == "v2": version = "2" self.updates_cmd.append("vrrp version %s" % version) self.changed = True def delete_vrrp_global(self): """delete vrrp global attribute info""" if self.is_vrrp_global_info_exist(): conf_str = CE_NC_SET_VRRP_GLOBAL_HEAD if self.gratuitous_arp_interval: if self.gratuitous_arp_interval == "120": self.module.fail_json( msg='Error: The default value of gratuitous_arp_interval is 120.') gratuitous_arp_interval = "120" conf_str += "%s" % gratuitous_arp_interval if self.recover_delay: if self.recover_delay == "0": self.module.fail_json( msg='Error: The default value of recover_delay is 0.') recover_delay = "0" conf_str += "%s" % recover_delay if self.version: if self.version == "v2": self.module.fail_json( msg='Error: The default value of version is v2.') version = "v2" conf_str += "%s" % version conf_str += CE_NC_SET_VRRP_GLOBAL_TAIL recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json( msg='Error: set vrrp global attribute info failed.') if self.gratuitous_arp_interval: self.updates_cmd.append("undo vrrp gratuitous-arp interval") if self.recover_delay: self.updates_cmd.append("undo vrrp recover-delay") if self.version == "v3": self.updates_cmd.append("undo vrrp version") self.changed = True def set_vrrp_group(self): """set vrrp group attribute info""" if self.is_vrrp_group_info_change(): conf_str = CE_NC_SET_VRRP_GROUP_INFO_HEAD % ( self.interface, self.vrid) if self.vrrp_type: conf_str += "%s" % self.vrrp_type if self.admin_vrid: conf_str += "%s" % self.admin_vrid if self.admin_interface: conf_str += "%s" % self.admin_interface if self.admin_flowdown: conf_str += "%s" % self.admin_flowdown if self.priority: conf_str += "%s" % self.priority if self.vrrp_type == "admin": if self.admin_ignore_if_down: conf_str += "%s" % self.admin_ignore_if_down if self.fast_resume: fast_resume = "false" if self.fast_resume == "enable": fast_resume = "true" conf_str += "%s" % fast_resume if self.advertise_interval: conf_str += "%s" % self.advertise_interval if self.preempt_timer_delay: conf_str += "%s" % self.preempt_timer_delay if self.holding_multiplier: conf_str += "%s" % self.holding_multiplier if self.auth_mode: conf_str += "%s" % self.auth_mode if self.auth_key: conf_str += "%s" % self.auth_key if self.auth_mode == "simple": conf_str += "%s" % self.is_plain conf_str += CE_NC_SET_VRRP_GROUP_INFO_TAIL recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json( msg='Error: set vrrp group attribute info failed.') if self.interface and self.vrid: self.updates_cmd.append("interface %s" % self.interface) if self.vrrp_type == "admin": if self.admin_ignore_if_down == "true": self.updates_cmd.append( "vrrp vrid %s admin ignore-if-down" % self.vrid) else: self.updates_cmd.append( "vrrp vrid %s admin" % self.vrid) if self.priority: self.updates_cmd.append( "vrrp vrid %s priority %s" % (self.vrid, self.priority)) if self.fast_resume == "enable": self.updates_cmd.append( "vrrp vrid %s fast-resume" % self.vrid) if self.fast_resume == "disable": self.updates_cmd.append( "undo vrrp vrid %s fast-resume" % self.vrid) if self.advertise_interval: advertise_interval = int(self.advertise_interval) / 1000 self.updates_cmd.append("vrrp vrid %s timer advertise %s" % ( self.vrid, int(advertise_interval))) if self.preempt_timer_delay: self.updates_cmd.append("vrrp vrid %s preempt timer delay %s" % (self.vrid, self.preempt_timer_delay)) if self.holding_multiplier: self.updates_cmd.append( "vrrp vrid %s holding-multiplier %s" % (self.vrid, self.holding_multiplier)) if self.admin_vrid and self.admin_interface: if self.admin_flowdown == "true": self.updates_cmd.append("vrrp vrid %s track admin-vrrp interface %s vrid %s unflowdown" % (self.vrid, self.admin_interface, self.admin_vrid)) else: self.updates_cmd.append("vrrp vrid %s track admin-vrrp interface %s vrid %s" % (self.vrid, self.admin_interface, self.admin_vrid)) if self.auth_mode and self.auth_key: if self.auth_mode == "simple": if self.is_plain == "true": self.updates_cmd.append("vrrp vrid %s authentication-mode simple plain %s" % (self.vrid, self.auth_key)) else: self.updates_cmd.append("vrrp vrid %s authentication-mode simple cipher %s" % (self.vrid, self.auth_key)) if self.auth_mode == "md5": self.updates_cmd.append( "vrrp vrid %s authentication-mode md5 %s" % (self.vrid, self.auth_key)) self.changed = True def delete_vrrp_group(self): """delete vrrp group attribute info""" if self.is_vrrp_group_info_exist(): conf_str = CE_NC_SET_VRRP_GROUP_INFO_HEAD % ( self.interface, self.vrid) if self.vrrp_type: vrrp_type = self.vrrp_type if self.vrrp_type == "admin": vrrp_type = "normal" if self.vrrp_type == "member" and self.admin_vrid and self.admin_interface: vrrp_type = "normal" conf_str += "%s" % vrrp_type if self.priority: if self.priority == "100": self.module.fail_json( msg='Error: The default value of priority is 100.') priority = "100" conf_str += "%s" % priority if self.fast_resume: fast_resume = "false" if self.fast_resume == "enable": fast_resume = "true" conf_str += "%s" % fast_resume if self.advertise_interval: if self.advertise_interval == "1000": self.module.fail_json( msg='Error: The default value of advertise_interval is 1000.') advertise_interval = "1000" conf_str += "%s" % advertise_interval if self.preempt_timer_delay: if self.preempt_timer_delay == "0": self.module.fail_json( msg='Error: The default value of preempt_timer_delay is 0.') preempt_timer_delay = "0" conf_str += "%s" % preempt_timer_delay if self.holding_multiplier: if self.holding_multiplier == "0": self.module.fail_json( msg='Error: The default value of holding_multiplier is 3.') holding_multiplier = "3" conf_str += "%s" % holding_multiplier if self.auth_mode: auth_mode = self.auth_mode if self.auth_mode == "md5" or self.auth_mode == "simple": auth_mode = "none" conf_str += "%s" % auth_mode conf_str += CE_NC_SET_VRRP_GROUP_INFO_TAIL recv_xml = set_nc_config(self.module, conf_str) if "" not in recv_xml: self.module.fail_json( msg='Error: set vrrp global attribute info failed.') if self.interface and self.vrid: self.updates_cmd.append("interface %s" % self.interface) if self.vrrp_type == "admin": self.updates_cmd.append( "undo vrrp vrid %s admin" % self.vrid) if self.priority: self.updates_cmd.append( "undo vrrp vrid %s priority" % self.vrid) if self.fast_resume: self.updates_cmd.append( "undo vrrp vrid %s fast-resume" % self.vrid) if self.advertise_interval: self.updates_cmd.append( "undo vrrp vrid %s timer advertise" % self.vrid) if self.preempt_timer_delay: self.updates_cmd.append( "undo vrrp vrid %s preempt timer delay" % self.vrid) if self.holding_multiplier: self.updates_cmd.append( "undo vrrp vrid %s holding-multiplier" % self.vrid) if self.admin_vrid and self.admin_interface: self.updates_cmd.append( "undo vrrp vrid %s track admin-vrrp" % self.vrid) if self.auth_mode: self.updates_cmd.append( "undo vrrp vrid %s authentication-mode" % self.vrid) self.changed = True def get_proposed(self): """get proposed info""" if self.interface: self.proposed["interface"] = self.interface if self.vrid: self.proposed["vrid"] = self.vrid if self.virtual_ip: self.proposed["virtual_ip"] = self.virtual_ip if self.vrrp_type: self.proposed["vrrp_type"] = self.vrrp_type if self.admin_vrid: self.proposed["admin_vrid"] = self.admin_vrid if self.admin_interface: self.proposed["admin_interface"] = self.admin_interface if self.admin_flowdown: self.proposed["unflowdown"] = self.admin_flowdown if self.admin_ignore_if_down: self.proposed["admin_ignore_if_down"] = self.admin_ignore_if_down if self.priority: self.proposed["priority"] = self.priority if self.version: self.proposed["version"] = self.version if self.advertise_interval: self.proposed["advertise_interval"] = self.advertise_interval if self.preempt_timer_delay: self.proposed["preempt_timer_delay"] = self.preempt_timer_delay if self.gratuitous_arp_interval: self.proposed[ "gratuitous_arp_interval"] = self.gratuitous_arp_interval if self.recover_delay: self.proposed["recover_delay"] = self.recover_delay if self.holding_multiplier: self.proposed["holding_multiplier"] = self.holding_multiplier if self.auth_mode: self.proposed["auth_mode"] = self.auth_mode if self.is_plain: self.proposed["is_plain"] = self.is_plain if self.auth_key: self.proposed["auth_key"] = self.auth_key if self.fast_resume: self.proposed["fast_resume"] = self.fast_resume if self.state: self.proposed["state"] = self.state def get_existing(self): """get existing info""" if self.gratuitous_arp_interval: self.existing["gratuitous_arp_interval"] = self.vrrp_global_info[ "gratuitousArpTimeOut"] if self.version: self.existing["version"] = self.vrrp_global_info["version"] if self.recover_delay: self.existing["recover_delay"] = self.vrrp_global_info[ "recoverDelay"] if self.virtual_ip: if self.virtual_ip_info: self.existing["interface"] = self.interface self.existing["vrid"] = self.vrid self.existing["virtual_ip_info"] = self.virtual_ip_info[ "vrrpVirtualIpInfos"] if self.vrrp_group_info: self.existing["interface"] = self.vrrp_group_info["ifName"] self.existing["vrid"] = self.vrrp_group_info["vrrpId"] self.existing["vrrp_type"] = self.vrrp_group_info["vrrpType"] if self.vrrp_type == "admin": self.existing["admin_ignore_if_down"] = self.vrrp_group_info[ "adminIgnoreIfDown"] if self.admin_vrid and self.admin_interface: self.existing["admin_vrid"] = self.vrrp_group_info[ "adminVrrpId"] self.existing["admin_interface"] = self.vrrp_group_info[ "adminIfName"] self.existing["admin_flowdown"] = self.vrrp_group_info[ "unflowdown"] if self.priority: self.existing["priority"] = self.vrrp_group_info["priority"] if self.advertise_interval: self.existing["advertise_interval"] = self.vrrp_group_info[ "advertiseInterval"] if self.preempt_timer_delay: self.existing["preempt_timer_delay"] = self.vrrp_group_info[ "delayTime"] if self.holding_multiplier: self.existing["holding_multiplier"] = self.vrrp_group_info[ "holdMultiplier"] if self.fast_resume: fast_resume_exist = "disable" fast_resume = self.vrrp_group_info["fastResume"] if fast_resume == "true": fast_resume_exist = "enable" self.existing["fast_resume"] = fast_resume_exist if self.auth_mode: self.existing["auth_mode"] = self.vrrp_group_info[ "authenticationMode"] self.existing["is_plain"] = self.vrrp_group_info["isPlain"] def get_end_state(self): """get end state info""" if self.gratuitous_arp_interval or self.version or self.recover_delay: self.vrrp_global_info = self.get_vrrp_global_info() if self.interface and self.vrid: if self.virtual_ip: self.virtual_ip_info = self.get_virtual_ip_info() if self.virtual_ip_info: self.vrrp_group_info = self.get_vrrp_group_info() if self.gratuitous_arp_interval: self.end_state["gratuitous_arp_interval"] = self.vrrp_global_info[ "gratuitousArpTimeOut"] if self.version: self.end_state["version"] = self.vrrp_global_info["version"] if self.recover_delay: self.end_state["recover_delay"] = self.vrrp_global_info[ "recoverDelay"] if self.virtual_ip: if self.virtual_ip_info: self.end_state["interface"] = self.interface self.end_state["vrid"] = self.vrid self.end_state["virtual_ip_info"] = self.virtual_ip_info[ "vrrpVirtualIpInfos"] if self.vrrp_group_info: self.end_state["interface"] = self.vrrp_group_info["ifName"] self.end_state["vrid"] = self.vrrp_group_info["vrrpId"] self.end_state["vrrp_type"] = self.vrrp_group_info["vrrpType"] if self.vrrp_type == "admin": self.end_state["admin_ignore_if_down"] = self.vrrp_group_info[ "adminIgnoreIfDown"] if self.admin_vrid and self.admin_interface: self.end_state["admin_vrid"] = self.vrrp_group_info[ "adminVrrpId"] self.end_state["admin_interface"] = self.vrrp_group_info[ "adminIfName"] self.end_state["admin_flowdown"] = self.vrrp_group_info[ "unflowdown"] if self.priority: self.end_state["priority"] = self.vrrp_group_info["priority"] if self.advertise_interval: self.end_state["advertise_interval"] = self.vrrp_group_info[ "advertiseInterval"] if self.preempt_timer_delay: self.end_state["preempt_timer_delay"] = self.vrrp_group_info[ "delayTime"] if self.holding_multiplier: self.end_state["holding_multiplier"] = self.vrrp_group_info[ "holdMultiplier"] if self.fast_resume: fast_resume_end = "disable" fast_resume = self.vrrp_group_info["fastResume"] if fast_resume == "true": fast_resume_end = "enable" self.end_state["fast_resume"] = fast_resume_end if self.auth_mode: self.end_state["auth_mode"] = self.vrrp_group_info[ "authenticationMode"] self.end_state["is_plain"] = self.vrrp_group_info["isPlain"] if self.existing == self.end_state: self.changed = False def work(self): """worker""" self.check_params() if self.gratuitous_arp_interval or self.version or self.recover_delay: self.vrrp_global_info = self.get_vrrp_global_info() if self.interface and self.vrid: self.virtual_ip_info = self.get_virtual_ip_info() if self.virtual_ip_info: self.vrrp_group_info = self.get_vrrp_group_info() self.get_proposed() self.get_existing() if self.gratuitous_arp_interval or self.version or self.recover_delay: if self.state == "present": self.set_vrrp_global() else: self.delete_vrrp_global() else: if not self.interface or not self.vrid: self.module.fail_json( msg='Error: interface, vrid must be config at the same time.') if self.interface and self.vrid: if self.virtual_ip: if self.state == "present": self.create_virtual_ip() else: self.delete_virtual_ip() else: if not self.vrrp_group_info: self.module.fail_json( msg='Error: The VRRP group does not exist.') if self.admin_ignore_if_down == "true": if self.vrrp_type != "admin": self.module.fail_json( msg='Error: vrrpType must be admin when admin_ignore_if_down is true.') if self.admin_interface or self.admin_vrid: if self.vrrp_type != "member": self.module.fail_json( msg='Error: it binds a VRRP group to an mVRRP group, vrrp_type must be "member".') if not self.vrrp_type or not self.interface or not self.vrid: self.module.fail_json( msg='Error: admin_interface admin_vrid vrrp_type interface vrid must ' 'be config at the same time.') if self.auth_mode == "md5" and self.is_plain == "true": self.module.fail_json( msg='Error: is_plain can not be True when auth_mode is md5.') if self.state == "present": self.set_vrrp_group() else: self.delete_vrrp_group() 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( interface=dict(type='str'), vrid=dict(type='str'), virtual_ip=dict(type='str'), vrrp_type=dict(type='str', choices=['normal', 'member', 'admin']), admin_ignore_if_down=dict(type='bool', default=False), admin_vrid=dict(type='str'), admin_interface=dict(type='str'), admin_flowdown=dict(type='bool', default=False), priority=dict(type='str'), version=dict(type='str', choices=['v2', 'v3']), advertise_interval=dict(type='str'), preempt_timer_delay=dict(type='str'), gratuitous_arp_interval=dict(type='str'), recover_delay=dict(type='str'), holding_multiplier=dict(type='str'), auth_mode=dict(type='str', choices=['simple', 'md5', 'none']), is_plain=dict(type='bool', default=False), auth_key=dict(type='str'), fast_resume=dict(type='str', choices=['enable', 'disable']), state=dict(type='str', default='present', choices=['present', 'absent']) ) argument_spec.update(ce_argument_spec) module = Vrrp(argument_spec=argument_spec) module.work() if __name__ == '__main__': main()