diff --git a/lib/ansible/modules/network/cloudengine/ce_bgp_neighbor.py b/lib/ansible/modules/network/cloudengine/ce_bgp_neighbor.py
new file mode 100644
index 0000000000..92caa9d6c0
--- /dev/null
+++ b/lib/ansible/modules/network/cloudengine/ce_bgp_neighbor.py
@@ -0,0 +1,2101 @@
+#!/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_bgp_neighbor
+version_added: "2.4"
+short_description: Manages BGP peer configuration on HUAWEI CloudEngine switches.
+description:
+ - Manages BGP peer configurations on HUAWEI CloudEngine switches.
+author:
+ - wangdezhuang (@CloudEngine-Ansible)
+options:
+ state:
+ description:
+ - Specify desired state of the resource.
+ required: false
+ default: present
+ choices: ['present','absent']
+ vrf_name:
+ description:
+ - Name of a BGP instance. The name is a case-sensitive string of characters.
+ The BGP instance can be used only after the corresponding VPN instance is created.
+ required: true
+ peer_addr:
+ description:
+ - Connection address of a peer, which can be an IPv4 or IPv6 address.
+ required: true
+ remote_as:
+ description:
+ - AS number of a peer.
+ The value is a string of 1 to 11 characters.
+ required: true
+ description:
+ description:
+ - Description of a peer, which can be letters or digits.
+ The value is a string of 1 to 80 characters.
+ required: false
+ default: null
+ fake_as:
+ description:
+ - Fake AS number that is specified for a local peer.
+ The value is a string of 1 to 11 characters.
+ required: false
+ default: null
+ dual_as:
+ description:
+ - If the value is true, the EBGP peer can use either a fake AS number or the actual AS number.
+ If the value is false, the EBGP peer can only use a fake AS number.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ conventional:
+ description:
+ - If the value is true, the router has all extended capabilities.
+ If the value is false, the router does not have all extended capabilities.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ route_refresh:
+ description:
+ - If the value is true, BGP is enabled to advertise REFRESH packets.
+ If the value is false, the route refresh function is enabled.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ is_ignore:
+ description:
+ - If the value is true, the session with a specified peer is torn down and all related
+ routing entries are cleared.
+ If the value is false, the session with a specified peer is retained.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ local_if_name:
+ description:
+ - Name of a source interface that sends BGP packets.
+ The value is a string of 1 to 63 characters.
+ required: false
+ default: null
+ ebgp_max_hop:
+ description:
+ - Maximum number of hops in an indirect EBGP connection.
+ The value is an ranging from 1 to 255.
+ required: false
+ default: null
+ valid_ttl_hops:
+ description:
+ - Enable GTSM on a peer or peer group.
+ The valid-TTL-Value parameter is used to specify the number of TTL hops to be detected.
+ The value is an integer ranging from 1 to 255.
+ required: false
+ default: null
+ connect_mode:
+ description:
+ - The value can be Connect-only, Listen-only, or Both.
+ required: false
+ default: null
+ is_log_change:
+ description:
+ - If the value is true, BGP is enabled to record peer session status and event information.
+ If the value is false, BGP is disabled from recording peer session status and event information.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ pswd_type:
+ description:
+ - Enable BGP peers to establish a TCP connection and perform the Message Digest 5 (MD5)
+ authentication for BGP messages.
+ required: false
+ choices: ['null','cipher','simple']
+ default: null
+ pswd_cipher_text:
+ description:
+ - The character string in a password identifies the contents of the password, spaces not supported.
+ The value is a string of 1 to 255 characters.
+ required: false
+ default: null
+ keep_alive_time:
+ description:
+ - Specify the Keepalive time of a peer or peer group.
+ The value is an integer ranging from 0 to 21845. The default value is 60.
+ required: false
+ default: null
+ hold_time:
+ description:
+ - Specify the Hold time of a peer or peer group.
+ The value is 0 or an integer ranging from 3 to 65535.
+ required: false
+ default: null
+ min_hold_time:
+ description:
+ - Specify the Min hold time of a peer or peer group.
+ required: false
+ default: null
+ key_chain_name:
+ description:
+ - Specify the Keychain authentication name used when BGP peers establish a TCP connection.
+ The value is a string of 1 to 47 case-insensitive characters.
+ required: false
+ default: null
+ conn_retry_time:
+ description:
+ - ConnectRetry interval.
+ The value is an integer ranging from 1 to 65535.
+ required: false
+ default: null
+ tcp_MSS:
+ description:
+ - Maximum TCP MSS value used for TCP connection establishment for a peer.
+ The value is an integer ranging from 176 to 4096.
+ required: false
+ default: null
+ mpls_local_ifnet_disable:
+ description:
+ - If the value is true, peer create MPLS Local IFNET disable.
+ If the value is false, peer create MPLS Local IFNET enable.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ prepend_global_as:
+ description:
+ - Add the global AS number to the Update packets to be advertised.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ prepend_fake_as:
+ description:
+ - Add the Fake AS number to received Update packets.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ is_bfd_block:
+ description:
+ - If the value is true, peers are enabled to inherit the BFD function from the peer group.
+ If the value is false, peers are disabled to inherit the BFD function from the peer group.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ multiplier:
+ description:
+ - Specify the detection multiplier. The default value is 3.
+ The value is an integer ranging from 3 to 50.
+ required: false
+ default: null
+ is_bfd_enable:
+ description:
+ - If the value is true, BFD is enabled.
+ If the value is false, BFD is disabled.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ rx_interval:
+ description:
+ - Specify the minimum interval at which BFD packets are received.
+ The value is an integer ranging from 50 to 1000, in milliseconds.
+ required: false
+ default: null
+ tx_interval:
+ description:
+ - Specify the minimum interval at which BFD packets are sent.
+ The value is an integer ranging from 50 to 1000, in milliseconds.
+ required: false
+ default: null
+ is_single_hop:
+ description:
+ - If the value is true, the system is enabled to preferentially use the single-hop mode for
+ BFD session setup between IBGP peers.
+ If the value is false, the system is disabled from preferentially using the single-hop
+ mode for BFD session setup between IBGP peers.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+'''
+
+EXAMPLES = '''
+
+- name: CloudEngine BGP neighbor 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 bgp peer"
+ ce_bgp_neighbor:
+ state: present
+ vrf_name: js
+ peer_addr: 192.168.10.10
+ remote_as: 500
+ provider: "{{ cli }}"
+
+ - name: "Config bgp route id"
+ ce_bgp_neighbor:
+ state: absent
+ vrf_name: js
+ peer_addr: 192.168.10.10
+ 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: {"peer_addr": "192.168.10.10", "remote_as": "500", "state": "present", "vrf_name": "js"}
+existing:
+ description: k/v pairs of existing aaa server
+ returned: always
+ type: dict
+ sample: {"bgp peer": []}
+end_state:
+ description: k/v pairs of aaa params after module execution
+ returned: always
+ type: dict
+ sample: {"bgp peer": [["192.168.10.10", "500"]]}
+updates:
+ description: command sent to the device
+ returned: always
+ type: list
+ sample: ["peer 192.168.10.10 as-number 500"]
+'''
+
+import re
+import sys
+import socket
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.ce import get_nc_config, set_nc_config, ce_argument_spec
+
+
+# get bgp peer
+CE_GET_BGP_PEER_HEADER = """
+
+
+
+
+
+ %s
+
+
+
+"""
+CE_GET_BGP_PEER_TAIL = """
+
+
+
+
+
+
+
+"""
+
+
+# merge bgp peer
+CE_MERGE_BGP_PEER_HEADER = """
+
+
+
+
+
+ %s
+
+
+ %s
+"""
+CE_MERGE_BGP_PEER_TAIL = """
+
+
+
+
+
+
+
+"""
+
+# create bgp peer
+CE_CREATE_BGP_PEER_HEADER = """
+
+
+
+
+
+ %s
+
+
+ %s
+"""
+CE_CREATE_BGP_PEER_TAIL = """
+
+
+
+
+
+
+
+"""
+
+# delete bgp peer
+CE_DELETE_BGP_PEER_HEADER = """
+
+
+
+
+
+ %s
+
+
+ %s
+"""
+CE_DELETE_BGP_PEER_TAIL = """
+
+
+
+
+
+
+
+"""
+
+# get peer bfd
+CE_GET_PEER_BFD_HEADER = """
+
+
+
+
+
+ %s
+
+
+ %s
+
+"""
+CE_GET_PEER_BFD_TAIL = """
+
+
+
+
+
+
+
+
+"""
+
+# merge peer bfd
+CE_MERGE_PEER_BFD_HEADER = """
+
+
+
+
+
+ %s
+
+
+ %s
+
+"""
+CE_MERGE_PEER_BFD_TAIL = """
+
+
+
+
+
+
+
+
+"""
+
+# delete peer bfd
+CE_DELETE_PEER_BFD_HEADER = """
+
+
+
+
+
+ %s
+
+
+ %s
+
+"""
+CE_DELETE_PEER_BFD_TAIL = """
+
+
+
+
+
+
+
+
+"""
+
+
+def check_ip_addr(**kwargs):
+ """ check_ip_addr, Supports IPv4 and IPv6 """
+
+ ipaddr = kwargs["ipaddr"]
+
+ if not ipaddr or '\x00' in ipaddr:
+ return False
+
+ try:
+ res = socket.getaddrinfo(ipaddr, 0, socket.AF_UNSPEC,
+ socket.SOCK_STREAM,
+ 0, socket.AI_NUMERICHOST)
+ return bool(res)
+ except socket.gaierror:
+ err = sys.exc_info()[1]
+ if err.args[0] == socket.EAI_NONAME:
+ return False
+ raise
+ return True
+
+
+class BgpNeighbor(object):
+ """ Manages BGP peer configuration """
+
+ def netconf_get_config(self, **kwargs):
+ """ netconf_get_config """
+
+ module = kwargs["module"]
+ conf_str = kwargs["conf_str"]
+
+ xml_str = get_nc_config(module, conf_str)
+
+ return xml_str
+
+ def netconf_set_config(self, **kwargs):
+ """ netconf_set_config """
+
+ module = kwargs["module"]
+ conf_str = kwargs["conf_str"]
+
+ xml_str = set_nc_config(module, conf_str)
+
+ return xml_str
+
+ def check_bgp_peer_args(self, **kwargs):
+ """ check_bgp_peer_args """
+
+ module = kwargs["module"]
+ result = dict()
+ need_cfg = False
+
+ vrf_name = module.params['vrf_name']
+ if vrf_name:
+ if len(vrf_name) > 31 or len(vrf_name) == 0:
+ module.fail_json(
+ msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)
+
+ peer_addr = module.params['peer_addr']
+ if peer_addr:
+ if not check_ip_addr(ipaddr=peer_addr):
+ module.fail_json(
+ msg='Error: The peer_addr %s is invalid.' % peer_addr)
+
+ need_cfg = True
+
+ remote_as = module.params['remote_as']
+ if remote_as:
+ if len(remote_as) > 11 or len(remote_as) < 1:
+ module.fail_json(
+ msg='Error: The len of remote_as %s is out of [1 - 11].' % remote_as)
+
+ need_cfg = True
+
+ result["need_cfg"] = need_cfg
+ return result
+
+ def check_bgp_peer_other_args(self, **kwargs):
+ """ check_bgp_peer_other_args """
+
+ module = kwargs["module"]
+ result = dict()
+ need_cfg = False
+
+ vrf_name = module.params['vrf_name']
+ if vrf_name:
+ if len(vrf_name) > 31 or len(vrf_name) == 0:
+ module.fail_json(
+ msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)
+
+ description = module.params['description']
+ if description:
+ if len(description) > 80 or len(description) < 1:
+ module.fail_json(
+ msg='Error: The len of description %s is out of [1 - 80].' % description)
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["description"] = re_find
+ if re_find[0] != description:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ fake_as = module.params['fake_as']
+ if fake_as:
+ if len(fake_as) > 11 or len(fake_as) < 1:
+ module.fail_json(
+ msg='Error: The len of fake_as %s is out of [1 - 11].' % fake_as)
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["fake_as"] = re_find
+ if re_find[0] != fake_as:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ dual_as = module.params['dual_as']
+ if dual_as != 'no_use':
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["dual_as"] = re_find
+ if re_find[0] != fake_as:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ conventional = module.params['conventional']
+ if conventional != 'no_use':
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["conventional"] = re_find
+ if re_find[0] != conventional:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ route_refresh = module.params['route_refresh']
+ if route_refresh != 'no_use':
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["route_refresh"] = re_find
+ if re_find[0] != route_refresh:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ four_byte_as = module.params['four_byte_as']
+ if four_byte_as != 'no_use':
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["four_byte_as"] = re_find
+ if re_find[0] != four_byte_as:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ is_ignore = module.params['is_ignore']
+ if is_ignore != 'no_use':
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["is_ignore"] = re_find
+ if re_find[0] != is_ignore:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ local_if_name = module.params['local_if_name']
+ if local_if_name:
+ if len(local_if_name) > 63 or len(local_if_name) < 1:
+ module.fail_json(
+ msg='Error: The len of local_if_name %s is out of [1 - 63].' % local_if_name)
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["local_if_name"] = re_find
+ if re_find[0] != local_if_name:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ ebgp_max_hop = module.params['ebgp_max_hop']
+ if ebgp_max_hop:
+ if int(ebgp_max_hop) > 255 or int(ebgp_max_hop) < 1:
+ module.fail_json(
+ msg='Error: The value of ebgp_max_hop %s is out of [1 - 255].' % ebgp_max_hop)
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["ebgp_max_hop"] = re_find
+ if re_find[0] != ebgp_max_hop:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ valid_ttl_hops = module.params['valid_ttl_hops']
+ if valid_ttl_hops:
+ if int(valid_ttl_hops) > 255 or int(valid_ttl_hops) < 1:
+ module.fail_json(
+ msg='Error: The value of valid_ttl_hops %s is out of [1 - 255].' % valid_ttl_hops)
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["valid_ttl_hops"] = re_find
+ if re_find[0] != valid_ttl_hops:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ connect_mode = module.params['connect_mode']
+ if connect_mode:
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["connect_mode"] = re_find
+ if re_find[0] != connect_mode:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ is_log_change = module.params['is_log_change']
+ if is_log_change != 'no_use':
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["is_log_change"] = re_find
+ if re_find[0] != is_log_change:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ pswd_type = module.params['pswd_type']
+ if pswd_type:
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["pswd_type"] = re_find
+ if re_find[0] != pswd_type:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ pswd_cipher_text = module.params['pswd_cipher_text']
+ if pswd_cipher_text:
+ if len(pswd_cipher_text) > 255 or len(pswd_cipher_text) < 1:
+ module.fail_json(
+ msg='Error: The len of pswd_cipher_text %s is out of [1 - 255].' % pswd_cipher_text)
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["pswd_cipher_text"] = re_find
+ if re_find[0] != pswd_cipher_text:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ keep_alive_time = module.params['keep_alive_time']
+ if keep_alive_time:
+ if int(keep_alive_time) > 21845 or len(keep_alive_time) < 0:
+ module.fail_json(
+ msg='Error: The len of keep_alive_time %s is out of [0 - 21845].' % keep_alive_time)
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["keep_alive_time"] = re_find
+ if re_find[0] != keep_alive_time:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ hold_time = module.params['hold_time']
+ if hold_time:
+ if int(hold_time) != 0 and (int(hold_time) > 65535 or int(hold_time) < 3):
+ module.fail_json(
+ msg='Error: The value of hold_time %s is out of [0 or 3 - 65535].' % hold_time)
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["hold_time"] = re_find
+ if re_find[0] != hold_time:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ min_hold_time = module.params['min_hold_time']
+ if min_hold_time:
+ if int(min_hold_time) != 0 and (int(min_hold_time) > 65535 or int(min_hold_time) < 20):
+ module.fail_json(
+ msg='Error: The value of min_hold_time %s is out of [0 or 20 - 65535].' % min_hold_time)
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["min_hold_time"] = re_find
+ if re_find[0] != min_hold_time:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ key_chain_name = module.params['key_chain_name']
+ if key_chain_name:
+ if len(key_chain_name) > 47 or len(key_chain_name) < 1:
+ module.fail_json(
+ msg='Error: The len of key_chain_name %s is out of [1 - 47].' % key_chain_name)
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["key_chain_name"] = re_find
+ if re_find[0] != key_chain_name:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ conn_retry_time = module.params['conn_retry_time']
+ if conn_retry_time:
+ if int(conn_retry_time) > 65535 or int(conn_retry_time) < 1:
+ module.fail_json(
+ msg='Error: The value of conn_retry_time %s is out of [1 - 65535].' % conn_retry_time)
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["conn_retry_time"] = re_find
+ if re_find[0] != conn_retry_time:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ tcp_mss = module.params['tcp_MSS']
+ if tcp_mss:
+ if int(tcp_mss) > 4096 or int(tcp_mss) < 176:
+ module.fail_json(
+ msg='Error: The value of tcp_mss %s is out of [176 - 4096].' % tcp_mss)
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["tcp_MSS"] = re_find
+ if re_find[0] != tcp_mss:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ mpls_local_ifnet_disable = module.params['mpls_local_ifnet_disable']
+ if mpls_local_ifnet_disable != 'no_use':
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["mpls_local_ifnet_disable"] = re_find
+ if re_find[0] != mpls_local_ifnet_disable:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ prepend_global_as = module.params['prepend_global_as']
+ if prepend_global_as != 'no_use':
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["prepend_global_as"] = re_find
+ if re_find[0] != prepend_global_as:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ prepend_fake_as = module.params['prepend_fake_as']
+ if prepend_fake_as != 'no_use':
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["prepend_fake_as"] = re_find
+ if re_find[0] != prepend_fake_as:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ result["need_cfg"] = need_cfg
+ return result
+
+ def check_peer_bfd_merge_args(self, **kwargs):
+ """ check_peer_bfd_merge_args """
+
+ module = kwargs["module"]
+ result = dict()
+ need_cfg = False
+
+ state = module.params['state']
+ if state == "absent":
+ result["need_cfg"] = need_cfg
+ return result
+
+ vrf_name = module.params['vrf_name']
+ if vrf_name:
+ if len(vrf_name) > 31 or len(vrf_name) == 0:
+ module.fail_json(
+ msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)
+
+ peer_addr = module.params['peer_addr']
+
+ is_bfd_block = module.params['is_bfd_block']
+ if is_bfd_block != 'no_use':
+
+ conf_str = CE_GET_PEER_BFD_HEADER % (
+ vrf_name, peer_addr) + "" + CE_GET_PEER_BFD_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["is_bfd_block"] = re_find
+ if re_find[0] != is_bfd_block:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ multiplier = module.params['multiplier']
+ if multiplier:
+ if int(multiplier) > 50 or int(multiplier) < 3:
+ module.fail_json(
+ msg='Error: The value of multiplier %s is out of [3 - 50].' % multiplier)
+
+ conf_str = CE_GET_PEER_BFD_HEADER % (
+ vrf_name, peer_addr) + "" + CE_GET_PEER_BFD_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["multiplier"] = re_find
+ if re_find[0] != multiplier:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ is_bfd_enable = module.params['is_bfd_enable']
+ if is_bfd_enable != 'no_use':
+
+ conf_str = CE_GET_PEER_BFD_HEADER % (
+ vrf_name, peer_addr) + "" + CE_GET_PEER_BFD_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["is_bfd_enable"] = re_find
+ if re_find[0] != is_bfd_enable:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ rx_interval = module.params['rx_interval']
+ if rx_interval:
+ if int(rx_interval) > 1000 or int(rx_interval) < 50:
+ module.fail_json(
+ msg='Error: The value of rx_interval %s is out of [50 - 1000].' % rx_interval)
+
+ conf_str = CE_GET_PEER_BFD_HEADER % (
+ vrf_name, peer_addr) + "" + CE_GET_PEER_BFD_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["rx_interval"] = re_find
+ if re_find[0] != rx_interval:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ tx_interval = module.params['tx_interval']
+ if tx_interval:
+ if int(tx_interval) > 1000 or int(tx_interval) < 50:
+ module.fail_json(
+ msg='Error: The value of tx_interval %s is out of [50 - 1000].' % tx_interval)
+
+ conf_str = CE_GET_PEER_BFD_HEADER % (
+ vrf_name, peer_addr) + "" + CE_GET_PEER_BFD_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["tx_interval"] = re_find
+ if re_find[0] != tx_interval:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ is_single_hop = module.params['is_single_hop']
+ if is_single_hop != 'no_use':
+
+ conf_str = CE_GET_PEER_BFD_HEADER % (
+ vrf_name, peer_addr) + "" + CE_GET_PEER_BFD_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["is_single_hop"] = re_find
+ if re_find[0] != is_single_hop:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ result["need_cfg"] = need_cfg
+ return result
+
+ def check_peer_bfd_delete_args(self, **kwargs):
+ """ check_peer_bfd_delete_args """
+
+ module = kwargs["module"]
+ result = dict()
+ need_cfg = False
+
+ state = module.params['state']
+ if state == "present":
+ result["need_cfg"] = need_cfg
+ return result
+
+ vrf_name = module.params['vrf_name']
+ if vrf_name:
+ if len(vrf_name) > 31 or len(vrf_name) == 0:
+ module.fail_json(
+ msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)
+
+ peer_addr = module.params['peer_addr']
+
+ is_bfd_block = module.params['is_bfd_block']
+ if is_bfd_block != 'no_use':
+
+ conf_str = CE_GET_PEER_BFD_HEADER % (
+ vrf_name, peer_addr) + "" + CE_GET_PEER_BFD_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ pass
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["is_bfd_block"] = re_find
+ if re_find[0] == is_bfd_block:
+ need_cfg = True
+
+ multiplier = module.params['multiplier']
+ if multiplier:
+ if int(multiplier) > 50 or int(multiplier) < 3:
+ module.fail_json(
+ msg='Error: The value of multiplier %s is out of [3 - 50].' % multiplier)
+
+ conf_str = CE_GET_PEER_BFD_HEADER % (
+ vrf_name, peer_addr) + "" + CE_GET_PEER_BFD_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ pass
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["multiplier"] = re_find
+ if re_find[0] == multiplier:
+ need_cfg = True
+
+ is_bfd_enable = module.params['is_bfd_enable']
+ if is_bfd_enable != 'no_use':
+
+ conf_str = CE_GET_PEER_BFD_HEADER % (
+ vrf_name, peer_addr) + "" + CE_GET_PEER_BFD_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ pass
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["is_bfd_enable"] = re_find
+ if re_find[0] == is_bfd_enable:
+ need_cfg = True
+
+ rx_interval = module.params['rx_interval']
+ if rx_interval:
+ if int(rx_interval) > 1000 or int(rx_interval) < 50:
+ module.fail_json(
+ msg='Error: The value of rx_interval %s is out of [50 - 1000].' % rx_interval)
+
+ conf_str = CE_GET_PEER_BFD_HEADER % (
+ vrf_name, peer_addr) + "" + CE_GET_PEER_BFD_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ pass
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["rx_interval"] = re_find
+ if re_find[0] == rx_interval:
+ need_cfg = True
+
+ tx_interval = module.params['tx_interval']
+ if tx_interval:
+ if int(tx_interval) > 1000 or int(tx_interval) < 50:
+ module.fail_json(
+ msg='Error: The value of tx_interval %s is out of [50 - 1000].' % tx_interval)
+
+ conf_str = CE_GET_PEER_BFD_HEADER % (
+ vrf_name, peer_addr) + "" + CE_GET_PEER_BFD_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ pass
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["tx_interval"] = re_find
+ if re_find[0] == tx_interval:
+ need_cfg = True
+
+ is_single_hop = module.params['is_single_hop']
+ if is_single_hop != 'no_use':
+
+ conf_str = CE_GET_PEER_BFD_HEADER % (
+ vrf_name, peer_addr) + "" + CE_GET_PEER_BFD_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "" in recv_xml:
+ pass
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', recv_xml)
+
+ if re_find:
+ result["is_single_hop"] = re_find
+ if re_find[0] == is_single_hop:
+ need_cfg = True
+
+ result["need_cfg"] = need_cfg
+ return result
+
+ def get_bgp_peer(self, **kwargs):
+ """ get_bgp_peer """
+
+ module = kwargs["module"]
+
+ vrf_name = module.params['vrf_name']
+ if vrf_name:
+ if len(vrf_name) > 31 or len(vrf_name) == 0:
+ module.fail_json(
+ msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
+ "" + CE_GET_BGP_PEER_TAIL
+
+ xml_str = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ result = list()
+
+ if "" in xml_str:
+ return result
+ else:
+ re_find = re.findall(
+ r'.*(.*).*\s.*(.*).*', xml_str)
+
+ if re_find:
+ return re_find
+ else:
+ return result
+
+ def get_bgp_del_peer(self, **kwargs):
+ """ get_bgp_del_peer """
+
+ module = kwargs["module"]
+
+ vrf_name = module.params['vrf_name']
+ if vrf_name:
+ if len(vrf_name) > 31 or len(vrf_name) == 0:
+ module.fail_json(
+ msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)
+
+ conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + CE_GET_BGP_PEER_TAIL
+
+ xml_str = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ result = list()
+
+ if "" in xml_str:
+ return result
+ else:
+ re_find = re.findall(
+ r'.*(.*).*', xml_str)
+
+ if re_find:
+ return re_find
+ else:
+ return result
+
+ def merge_bgp_peer(self, **kwargs):
+ """ merge_bgp_peer """
+
+ module = kwargs["module"]
+ vrf_name = module.params['vrf_name']
+ peer_addr = module.params['peer_addr']
+ remote_as = module.params['remote_as']
+
+ conf_str = CE_MERGE_BGP_PEER_HEADER % (
+ vrf_name, peer_addr) + "%s" % remote_as + CE_MERGE_BGP_PEER_TAIL
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "" not in recv_xml:
+ module.fail_json(msg='Error: Merge bgp peer failed.')
+
+ cmds = []
+ cmd = "peer %s as-number %s" % (peer_addr, remote_as)
+ cmds.append(cmd)
+
+ return cmds
+
+ def create_bgp_peer(self, **kwargs):
+ """ create_bgp_peer """
+
+ module = kwargs["module"]
+
+ vrf_name = module.params['vrf_name']
+
+ peer_addr = module.params['peer_addr']
+ remote_as = module.params['remote_as']
+
+ conf_str = CE_CREATE_BGP_PEER_HEADER % (
+ vrf_name, peer_addr) + "%s" % remote_as + CE_CREATE_BGP_PEER_TAIL
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "" not in recv_xml:
+ module.fail_json(msg='Error: Create bgp peer failed.')
+
+ cmds = []
+ cmd = "peer %s as-number %s" % (peer_addr, remote_as)
+ cmds.append(cmd)
+
+ return cmds
+
+ def delete_bgp_peer(self, **kwargs):
+ """ delete_bgp_peer """
+
+ module = kwargs["module"]
+ vrf_name = module.params['vrf_name']
+ peer_addr = module.params['peer_addr']
+
+ conf_str = CE_DELETE_BGP_PEER_HEADER % (
+ vrf_name, peer_addr) + CE_DELETE_BGP_PEER_TAIL
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "" not in recv_xml:
+ module.fail_json(msg='Error: Delete bgp peer failed.')
+
+ cmds = []
+ cmd = "undo peer %s" % peer_addr
+ cmds.append(cmd)
+
+ return cmds
+
+ def merge_bgp_peer_other(self, **kwargs):
+ """ merge_bgp_peer """
+
+ module = kwargs["module"]
+ vrf_name = module.params['vrf_name']
+ peer_addr = module.params['peer_addr']
+
+ conf_str = CE_MERGE_BGP_PEER_HEADER % (vrf_name, peer_addr)
+
+ cmds = []
+
+ description = module.params['description']
+ if description:
+ conf_str += "%s" % description
+
+ cmd = "peer %s description %s" % (peer_addr, description)
+ cmds.append(cmd)
+
+ fake_as = module.params['fake_as']
+ if fake_as:
+ conf_str += "%s" % fake_as
+
+ cmd = "peer %s local-as %s" % (peer_addr, fake_as)
+ cmds.append(cmd)
+
+ dual_as = module.params['dual_as']
+ if dual_as != 'no_use':
+ conf_str += "%s" % dual_as
+
+ if dual_as == "true":
+ cmd = "peer %s local-as %s dual-as" % (peer_addr, fake_as)
+ else:
+ cmd = "peer %s local-as %s" % (peer_addr, fake_as)
+ cmds.append(cmd)
+
+ conventional = module.params['conventional']
+ if conventional != 'no_use':
+ conf_str += "%s" % conventional
+
+ if conventional == "true":
+ cmd = "peer %s capability-advertise conventional" % peer_addr
+ else:
+ cmd = "undo peer %s capability-advertise conventional" % peer_addr
+ cmds.append(cmd)
+
+ route_refresh = module.params['route_refresh']
+ if route_refresh != 'no_use':
+ conf_str += "%s" % route_refresh
+
+ if route_refresh == "true":
+ cmd = "peer %s capability-advertise route-refresh" % peer_addr
+ else:
+ cmd = "undo peer %s capability-advertise route-refresh" % peer_addr
+ cmds.append(cmd)
+
+ four_byte_as = module.params['four_byte_as']
+ if four_byte_as != 'no_use':
+ conf_str += "%s" % four_byte_as
+
+ if four_byte_as == "true":
+ cmd = "peer %s capability-advertise 4-byte-as" % peer_addr
+ else:
+ cmd = "undo peer %s capability-advertise 4-byte-as" % peer_addr
+ cmds.append(cmd)
+
+ is_ignore = module.params['is_ignore']
+ if is_ignore != 'no_use':
+ conf_str += "%s" % is_ignore
+
+ if is_ignore == "true":
+ cmd = "peer %s ignore" % peer_addr
+ else:
+ cmd = "undo peer %s ignore" % peer_addr
+ cmds.append(cmd)
+
+ local_if_name = module.params['local_if_name']
+ if local_if_name:
+ conf_str += "%s" % local_if_name
+
+ cmd = "peer %s connect-interface local_if_name" % peer_addr
+ cmds.append(cmd)
+
+ ebgp_max_hop = module.params['ebgp_max_hop']
+ if ebgp_max_hop:
+ conf_str += "%s" % ebgp_max_hop
+
+ cmd = "peer %s ebgp-max-hop %s" % (peer_addr, ebgp_max_hop)
+ cmds.append(cmd)
+
+ valid_ttl_hops = module.params['valid_ttl_hops']
+ if valid_ttl_hops:
+ conf_str += "%s" % valid_ttl_hops
+
+ cmd = "peer %s valid-ttl-hops %s" % (peer_addr, valid_ttl_hops)
+ cmds.append(cmd)
+
+ connect_mode = module.params['connect_mode']
+ if connect_mode:
+ conf_str += "%s" % connect_mode
+
+ if connect_mode == "listenOnly":
+ cmd = "peer %s listen-only" % peer_addr
+ cmds.append(cmd)
+ elif connect_mode == "connectOnly":
+ cmd = "peer %s connect-only" % peer_addr
+ cmds.append(cmd)
+ elif connect_mode == "null":
+ cmd = "peer %s listen-only" % peer_addr
+ cmds.append(cmd)
+ cmd = "peer %s connect-only" % peer_addr
+ cmds.append(cmd)
+
+ is_log_change = module.params['is_log_change']
+ if is_log_change != 'no_use':
+ conf_str += "%s" % is_log_change
+
+ if is_log_change == "true":
+ cmd = "peer %s log-change" % peer_addr
+ else:
+ cmd = "undo peer %s log-change" % peer_addr
+ cmds.append(cmd)
+
+ pswd_type = module.params['pswd_type']
+ if pswd_type:
+ conf_str += "%s" % pswd_type
+
+ pswd_cipher_text = module.params['pswd_cipher_text']
+ if pswd_cipher_text:
+ conf_str += "%s" % pswd_cipher_text
+
+ if pswd_type == "cipher":
+ cmd = "peer %s password cipher %s" % (
+ peer_addr, pswd_cipher_text)
+ elif pswd_type == "simple":
+ cmd = "peer %s password simple %s" % (
+ peer_addr, pswd_cipher_text)
+ cmds.append(cmd)
+
+ keep_alive_time = module.params['keep_alive_time']
+ if keep_alive_time:
+ conf_str += "%s" % keep_alive_time
+
+ cmd = "peer %s timer keepalive %s" % (peer_addr, keep_alive_time)
+ cmds.append(cmd)
+
+ hold_time = module.params['hold_time']
+ if hold_time:
+ conf_str += "%s" % hold_time
+
+ cmd = "peer %s timer hold %s" % (peer_addr, hold_time)
+ cmds.append(cmd)
+
+ min_hold_time = module.params['min_hold_time']
+ if min_hold_time:
+ conf_str += "%s" % min_hold_time
+
+ cmd = "peer %s timer min-holdtime %s" % (peer_addr, min_hold_time)
+ cmds.append(cmd)
+
+ key_chain_name = module.params['key_chain_name']
+ if key_chain_name:
+ conf_str += "%s" % key_chain_name
+
+ cmd = "peer %s keychain %s" % (peer_addr, key_chain_name)
+ cmds.append(cmd)
+
+ conn_retry_time = module.params['conn_retry_time']
+ if conn_retry_time:
+ conf_str += "%s" % conn_retry_time
+
+ cmd = "peer %s timer connect-retry %s" % (
+ peer_addr, conn_retry_time)
+ cmds.append(cmd)
+
+ tcp_mss = module.params['tcp_MSS']
+ if tcp_mss:
+ conf_str += "%s" % tcp_mss
+
+ cmd = "peer %s tcp-mss %s" % (peer_addr, tcp_mss)
+ cmds.append(cmd)
+
+ mpls_local_ifnet_disable = module.params['mpls_local_ifnet_disable']
+ if mpls_local_ifnet_disable != 'no_use':
+ conf_str += "%s" % mpls_local_ifnet_disable
+
+ prepend_global_as = module.params['prepend_global_as']
+ if prepend_global_as != 'no_use':
+ conf_str += "%s" % prepend_global_as
+
+ if prepend_global_as == "true":
+ cmd = "peer %s public-as-only" % peer_addr
+ else:
+ cmd = "undo peer %s public-as-only" % peer_addr
+ cmds.append(cmd)
+
+ prepend_fake_as = module.params['prepend_fake_as']
+ if prepend_fake_as != 'no_use':
+ conf_str += "%s" % prepend_fake_as
+
+ conf_str += CE_MERGE_BGP_PEER_TAIL
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "" not in recv_xml:
+ module.fail_json(msg='Error: Merge bgp peer other failed.')
+
+ return cmds
+
+ def merge_peer_bfd(self, **kwargs):
+ """ merge_peer_bfd """
+
+ module = kwargs["module"]
+ vrf_name = module.params['vrf_name']
+ peer_addr = module.params['peer_addr']
+
+ conf_str = CE_MERGE_PEER_BFD_HEADER % (vrf_name, peer_addr)
+
+ cmds = []
+
+ is_bfd_block = module.params['is_bfd_block']
+ if is_bfd_block != 'no_use':
+ conf_str += "%s" % is_bfd_block
+
+ if is_bfd_block == "true":
+ cmd = "peer %s bfd block" % peer_addr
+ else:
+ cmd = "undo peer %s bfd block" % peer_addr
+ cmds.append(cmd)
+
+ multiplier = module.params['multiplier']
+ if multiplier:
+ conf_str += "%s" % multiplier
+
+ cmd = "peer %s bfd detect-multiplier %s" % (peer_addr, multiplier)
+ cmds.append(cmd)
+
+ is_bfd_enable = module.params['is_bfd_enable']
+ if is_bfd_enable != 'no_use':
+ conf_str += "%s" % is_bfd_enable
+
+ if is_bfd_enable == "true":
+ cmd = "peer %s bfd enable" % peer_addr
+ else:
+ cmd = "undo peer %s bfd enable" % peer_addr
+ cmds.append(cmd)
+
+ rx_interval = module.params['rx_interval']
+ if rx_interval:
+ conf_str += "%s" % rx_interval
+
+ cmd = "peer %s bfd min-rx-interval %s" % (peer_addr, rx_interval)
+ cmds.append(cmd)
+
+ tx_interval = module.params['tx_interval']
+ if tx_interval:
+ conf_str += "%s" % tx_interval
+
+ cmd = "peer %s bfd min-tx-interval %s" % (peer_addr, tx_interval)
+ cmds.append(cmd)
+
+ is_single_hop = module.params['is_single_hop']
+ if is_single_hop != 'no_use':
+ conf_str += "%s" % is_single_hop
+
+ if is_single_hop == "true":
+ cmd = "peer %s bfd enable single-hop-prefer" % peer_addr
+ else:
+ cmd = "undo peer %s bfd enable single-hop-prefer" % peer_addr
+ cmds.append(cmd)
+
+ conf_str += CE_MERGE_PEER_BFD_TAIL
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "" not in recv_xml:
+ module.fail_json(msg='Error: Merge peer bfd failed.')
+
+ return cmds
+
+ def delete_peer_bfd(self, **kwargs):
+ """ delete_peer_bfd """
+
+ module = kwargs["module"]
+ vrf_name = module.params['vrf_name']
+ peer_addr = module.params['peer_addr']
+
+ conf_str = CE_DELETE_PEER_BFD_HEADER % (vrf_name, peer_addr)
+
+ cmds = []
+
+ is_bfd_block = module.params['is_bfd_block']
+ if is_bfd_block != 'no_use':
+ conf_str += "%s" % is_bfd_block
+
+ cmd = "undo peer %s bfd block" % peer_addr
+ cmds.append(cmd)
+
+ multiplier = module.params['multiplier']
+ if multiplier:
+ conf_str += "%s" % multiplier
+
+ cmd = "undo peer %s bfd detect-multiplier %s" % (
+ peer_addr, multiplier)
+ cmds.append(cmd)
+
+ is_bfd_enable = module.params['is_bfd_enable']
+ if is_bfd_enable != 'no_use':
+ conf_str += "%s" % is_bfd_enable
+
+ cmd = "undo peer %s bfd enable" % peer_addr
+ cmds.append(cmd)
+
+ rx_interval = module.params['rx_interval']
+ if rx_interval:
+ conf_str += "%s" % rx_interval
+
+ cmd = "undo peer %s bfd min-rx-interval %s" % (
+ peer_addr, rx_interval)
+ cmds.append(cmd)
+
+ tx_interval = module.params['tx_interval']
+ if tx_interval:
+ conf_str += "%s" % tx_interval
+
+ cmd = "undo peer %s bfd min-tx-interval %s" % (
+ peer_addr, tx_interval)
+ cmds.append(cmd)
+
+ is_single_hop = module.params['is_single_hop']
+ if is_single_hop != 'no_use':
+ conf_str += "%s" % is_single_hop
+
+ cmd = "undo peer %s bfd enable single-hop-prefer" % peer_addr
+ cmds.append(cmd)
+
+ conf_str += CE_DELETE_PEER_BFD_TAIL
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "" not in recv_xml:
+ module.fail_json(msg='Error: Delete peer bfd failed.')
+
+ return cmds
+
+
+def main():
+ """ main """
+
+ argument_spec = dict(
+ state=dict(choices=['present', 'absent'], default='present'),
+ vrf_name=dict(type='str', required=True),
+ peer_addr=dict(type='str', required=True),
+ remote_as=dict(type='str', required=True),
+ description=dict(type='str'),
+ fake_as=dict(type='str'),
+ dual_as=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ conventional=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ route_refresh=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ four_byte_as=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ is_ignore=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ local_if_name=dict(type='str'),
+ ebgp_max_hop=dict(type='str'),
+ valid_ttl_hops=dict(type='str'),
+ connect_mode=dict(choices=['listenOnly', 'connectOnly', 'null']),
+ is_log_change=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ pswd_type=dict(choices=['null', 'cipher', 'simple']),
+ pswd_cipher_text=dict(type='str', no_log=True),
+ keep_alive_time=dict(type='str'),
+ hold_time=dict(type='str'),
+ min_hold_time=dict(type='str'),
+ key_chain_name=dict(type='str'),
+ conn_retry_time=dict(type='str'),
+ tcp_MSS=dict(type='str'),
+ mpls_local_ifnet_disable=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ prepend_global_as=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ prepend_fake_as=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ is_bfd_block=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ multiplier=dict(type='str'),
+ is_bfd_enable=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ rx_interval=dict(type='str'),
+ tx_interval=dict(type='str'),
+ is_single_hop=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']))
+
+ argument_spec.update(ce_argument_spec)
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
+
+ changed = False
+ proposed = dict()
+ existing = dict()
+ end_state = dict()
+ updates = []
+
+ state = module.params['state']
+ vrf_name = module.params['vrf_name']
+ peer_addr = module.params['peer_addr']
+ remote_as = module.params['remote_as']
+ description = module.params['description']
+ fake_as = module.params['fake_as']
+ dual_as = module.params['dual_as']
+ conventional = module.params['conventional']
+ route_refresh = module.params['route_refresh']
+ four_byte_as = module.params['four_byte_as']
+ is_ignore = module.params['is_ignore']
+ local_if_name = module.params['local_if_name']
+ ebgp_max_hop = module.params['ebgp_max_hop']
+ valid_ttl_hops = module.params['valid_ttl_hops']
+ connect_mode = module.params['connect_mode']
+ is_log_change = module.params['is_log_change']
+ pswd_type = module.params['pswd_type']
+ pswd_cipher_text = module.params['pswd_cipher_text']
+ keep_alive_time = module.params['keep_alive_time']
+ hold_time = module.params['hold_time']
+ min_hold_time = module.params['min_hold_time']
+ key_chain_name = module.params['key_chain_name']
+ conn_retry_time = module.params['conn_retry_time']
+ tcp_mss = module.params['tcp_MSS']
+ mpls_local_ifnet_disable = module.params['mpls_local_ifnet_disable']
+ prepend_global_as = module.params['prepend_global_as']
+ prepend_fake_as = module.params['prepend_fake_as']
+ is_bfd_block = module.params['is_bfd_block']
+ multiplier = module.params['multiplier']
+ is_bfd_enable = module.params['is_bfd_enable']
+ rx_interval = module.params['rx_interval']
+ tx_interval = module.params['tx_interval']
+ is_single_hop = module.params['is_single_hop']
+
+ ce_bgp_peer_obj = BgpNeighbor()
+
+ # get proposed
+ proposed["state"] = state
+ if vrf_name:
+ proposed["vrf_name"] = vrf_name
+ if peer_addr:
+ proposed["peer_addr"] = peer_addr
+ if remote_as:
+ proposed["remote_as"] = remote_as
+ if description:
+ proposed["description"] = description
+ if fake_as:
+ proposed["fake_as"] = fake_as
+ if dual_as != 'no_use':
+ proposed["dual_as"] = dual_as
+ if conventional != 'no_use':
+ proposed["conventional"] = conventional
+ if route_refresh != 'no_use':
+ proposed["route_refresh"] = route_refresh
+ if four_byte_as != 'no_use':
+ proposed["four_byte_as"] = four_byte_as
+ if is_ignore != 'no_use':
+ proposed["is_ignore"] = is_ignore
+ if local_if_name:
+ proposed["local_if_name"] = local_if_name
+ if ebgp_max_hop:
+ proposed["ebgp_max_hop"] = ebgp_max_hop
+ if valid_ttl_hops:
+ proposed["valid_ttl_hops"] = valid_ttl_hops
+ if connect_mode:
+ proposed["connect_mode"] = connect_mode
+ if is_log_change != 'no_use':
+ proposed["is_log_change"] = is_log_change
+ if pswd_type:
+ proposed["pswd_type"] = pswd_type
+ if pswd_cipher_text:
+ proposed["pswd_cipher_text"] = pswd_cipher_text
+ if keep_alive_time:
+ proposed["keep_alive_time"] = keep_alive_time
+ if hold_time:
+ proposed["hold_time"] = hold_time
+ if min_hold_time:
+ proposed["min_hold_time"] = min_hold_time
+ if key_chain_name:
+ proposed["key_chain_name"] = key_chain_name
+ if conn_retry_time:
+ proposed["conn_retry_time"] = conn_retry_time
+ if tcp_mss:
+ proposed["tcp_MSS"] = tcp_mss
+ if mpls_local_ifnet_disable != 'no_use':
+ proposed["mpls_local_ifnet_disable"] = mpls_local_ifnet_disable
+ if prepend_global_as != 'no_use':
+ proposed["prepend_global_as"] = prepend_global_as
+ if prepend_fake_as != 'no_use':
+ proposed["prepend_fake_as"] = prepend_fake_as
+ if is_bfd_block != 'no_use':
+ proposed["is_bfd_block"] = is_bfd_block
+ if multiplier:
+ proposed["multiplier"] = multiplier
+ if is_bfd_enable != 'no_use':
+ proposed["is_bfd_enable"] = is_bfd_enable
+ if rx_interval:
+ proposed["rx_interval"] = rx_interval
+ if tx_interval:
+ proposed["tx_interval"] = tx_interval
+ if is_single_hop != 'no_use':
+ proposed["is_single_hop"] = is_single_hop
+
+ if not ce_bgp_peer_obj:
+ module.fail_json(msg='Error: Init module failed.')
+
+ need_bgp_peer_enable = ce_bgp_peer_obj.check_bgp_peer_args(module=module)
+ need_bgp_peer_other_rst = ce_bgp_peer_obj.check_bgp_peer_other_args(
+ module=module)
+ need_peer_bfd_merge_rst = ce_bgp_peer_obj.check_peer_bfd_merge_args(
+ module=module)
+ need_peer_bfd_del_rst = ce_bgp_peer_obj.check_peer_bfd_delete_args(
+ module=module)
+
+ # bgp peer config
+ if need_bgp_peer_enable["need_cfg"]:
+
+ if state == "present":
+
+ if remote_as:
+
+ bgp_peer_exist = ce_bgp_peer_obj.get_bgp_peer(module=module)
+ existing["bgp peer"] = bgp_peer_exist
+
+ bgp_peer_new = (peer_addr, remote_as)
+
+ if len(bgp_peer_exist) == 0:
+ cmd = ce_bgp_peer_obj.create_bgp_peer(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+
+ elif bgp_peer_new in bgp_peer_exist:
+ pass
+
+ else:
+ cmd = ce_bgp_peer_obj.merge_bgp_peer(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+
+ bgp_peer_end = ce_bgp_peer_obj.get_bgp_peer(module=module)
+ end_state["bgp peer"] = bgp_peer_end
+
+ else:
+
+ bgp_peer_exist = ce_bgp_peer_obj.get_bgp_del_peer(module=module)
+ existing["bgp peer"] = bgp_peer_exist
+
+ bgp_peer_new = (peer_addr)
+
+ if len(bgp_peer_exist) == 0:
+ pass
+
+ elif bgp_peer_new in bgp_peer_exist:
+ cmd = ce_bgp_peer_obj.delete_bgp_peer(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+
+ bgp_peer_end = ce_bgp_peer_obj.get_bgp_del_peer(module=module)
+ end_state["bgp peer"] = bgp_peer_end
+
+ # bgp peer other args
+ exist_tmp = dict()
+ for item in need_bgp_peer_other_rst:
+ if item != "need_cfg":
+ exist_tmp[item] = need_bgp_peer_other_rst[item]
+ if exist_tmp:
+ existing["bgp peer other"] = exist_tmp
+
+ if need_bgp_peer_other_rst["need_cfg"]:
+
+ if state == "present":
+ cmd = ce_bgp_peer_obj.merge_bgp_peer_other(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+
+ need_bgp_peer_other_rst = ce_bgp_peer_obj.check_bgp_peer_other_args(
+ module=module)
+ end_tmp = dict()
+ for item in need_bgp_peer_other_rst:
+ if item != "need_cfg":
+ end_tmp[item] = need_bgp_peer_other_rst[item]
+ if end_tmp:
+ end_state["bgp peer other"] = end_tmp
+
+ # peer bfd args
+ if state == "present":
+ exist_tmp = dict()
+ for item in need_peer_bfd_merge_rst:
+ if item != "need_cfg":
+ exist_tmp[item] = need_peer_bfd_merge_rst[item]
+ if exist_tmp:
+ existing["peer bfd"] = exist_tmp
+
+ if need_peer_bfd_merge_rst["need_cfg"]:
+ cmd = ce_bgp_peer_obj.merge_peer_bfd(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+
+ need_peer_bfd_merge_rst = ce_bgp_peer_obj.check_peer_bfd_merge_args(
+ module=module)
+ end_tmp = dict()
+ for item in need_peer_bfd_merge_rst:
+ if item != "need_cfg":
+ end_tmp[item] = need_peer_bfd_merge_rst[item]
+ if end_tmp:
+ end_state["peer bfd"] = end_tmp
+ else:
+ exist_tmp = dict()
+ for item in need_peer_bfd_del_rst:
+ if item != "need_cfg":
+ exist_tmp[item] = need_peer_bfd_del_rst[item]
+ if exist_tmp:
+ existing["peer bfd"] = exist_tmp
+
+ # has already delete with bgp peer
+
+ need_peer_bfd_del_rst = ce_bgp_peer_obj.check_peer_bfd_delete_args(
+ module=module)
+ end_tmp = dict()
+ for item in need_peer_bfd_del_rst:
+ if item != "need_cfg":
+ end_tmp[item] = need_peer_bfd_del_rst[item]
+ if end_tmp:
+ end_state["peer bfd"] = end_tmp
+
+ results = dict()
+ results['proposed'] = proposed
+ results['existing'] = existing
+ results['changed'] = changed
+ results['end_state'] = end_state
+ results['updates'] = updates
+
+ module.exit_json(**results)
+
+
+if __name__ == '__main__':
+ main()