summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQijunPan <panqijun@huawei.com>2017-05-26 00:35:12 +0800
committerJohn R Barker <john@johnrbarker.com>2017-05-25 17:35:12 +0100
commit93ddfeb98ae97305b5b47a5cc735e6e12e198b58 (patch)
treec046ee6a083390d20a20ef53182cf1b5515c6d99
parente86279cee4a500d13ceaf577ec587232b1745f88 (diff)
downloadansible-93ddfeb98ae97305b5b47a5cc735e6e12e198b58.tar.gz
Contributing lib/ansible/modules/network/cloudengine/ce_bgp_af.py module to manage HUAWEI data center CloudEngine (#22031)
* add cd_bgp_af module add cd_bgp_af module * fix review issues
-rw-r--r--lib/ansible/modules/network/cloudengine/ce_bgp_af.py3484
1 files changed, 3484 insertions, 0 deletions
diff --git a/lib/ansible/modules/network/cloudengine/ce_bgp_af.py b/lib/ansible/modules/network/cloudengine/ce_bgp_af.py
new file mode 100644
index 0000000000..febbc8809d
--- /dev/null
+++ b/lib/ansible/modules/network/cloudengine/ce_bgp_af.py
@@ -0,0 +1,3484 @@
+#!/usr/bin/python
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+#
+
+ANSIBLE_METADATA = {'status': ['preview'],
+ 'supported_by': 'community',
+ 'metadata_version': '1.0'}
+
+DOCUMENTATION = '''
+---
+module: ce_bgp_af
+version_added: "2.4"
+short_description: Manages BGP Address-family configuration on HUAWEI CloudEngine switches.
+description:
+ - Manages BGP Address-family 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.
+ The value is a string of 1 to 31 case-sensitive characters.
+ required: true
+ af_type:
+ description:
+ - Address family type of a BGP instance.
+ required: true
+ choices: ['ipv4uni','ipv4multi', 'ipv4vpn', 'ipv6uni', 'ipv6vpn', 'evpn']
+ max_load_ibgp_num:
+ description:
+ - Specify the maximum number of equal-cost IBGP routes.
+ The value is an integer ranging from 1 to 65535.
+ required: false
+ default: null
+ ibgp_ecmp_nexthop_changed:
+ description:
+ - If the value is true, the next hop of an advertised route is changed to the advertiser itself in IBGP
+ load-balancing scenarios.
+ If the value is false, the next hop of an advertised route is not changed to the advertiser itself in
+ IBGP load-balancing scenarios.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ max_load_ebgp_num:
+ description:
+ - Specify the maximum number of equal-cost EBGP routes.
+ The value is an integer ranging from 1 to 65535.
+ required: false
+ default: null
+ ebgp_ecmp_nexthop_changed:
+ description:
+ - If the value is true, the next hop of an advertised route is changed to the advertiser itself in EBGP
+ load-balancing scenarios.
+ If the value is false, the next hop of an advertised route is not changed to the advertiser itself in
+ EBGP load-balancing scenarios.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ maximum_load_balance:
+ description:
+ - Specify the maximum number of equal-cost routes in the BGP routing table.
+ The value is an integer ranging from 1 to 65535.
+ required: false
+ default: null
+ ecmp_nexthop_changed:
+ description:
+ - If the value is true, the next hop of an advertised route is changed to the advertiser itself in BGP
+ load-balancing scenarios.
+ If the value is false, the next hop of an advertised route is not changed to the advertiser itself
+ in BGP load-balancing scenarios.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ default_local_pref:
+ description:
+ - Set the Local-Preference attribute. The value is an integer.
+ The value is an integer ranging from 0 to 4294967295.
+ required: false
+ default: null
+ default_med:
+ description:
+ - Specify the Multi-Exit-Discriminator (MED) of BGP routes.
+ The value is an integer ranging from 0 to 4294967295.
+ required: false
+ default: null
+ default_rt_import_enable:
+ description:
+ - If the value is true, importing default routes to the BGP routing table is allowed.
+ If the value is false, importing default routes to the BGP routing table is not allowed.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ router_id:
+ description:
+ - ID of a router that is in IPv4 address format.
+ The value is a string of 0 to 255 characters.
+ The value is in dotted decimal notation.
+ required: false
+ default: null
+ vrf_rid_auto_sel:
+ description:
+ - If the value is true, VPN BGP instances are enabled to automatically select router IDs.
+ If the value is false, VPN BGP instances are disabled from automatically selecting router IDs.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ nexthop_third_party:
+ description:
+ - If the value is true, the third-party next hop function is enabled.
+ If the value is false, the third-party next hop function is disabled.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ summary_automatic:
+ description:
+ - If the value is true, automatic aggregation is enabled for locally imported routes.
+ If the value is false, automatic aggregation is disabled for locally imported routes.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ auto_frr_enable:
+ description:
+ - If the value is true, BGP auto FRR is enabled.
+ If the value is false, BGP auto FRR is disabled.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ load_balancing_as_path_ignore:
+ description:
+ - Load balancing as path ignore.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ rib_only_enable:
+ description:
+ - If the value is true, BGP routes cannot be advertised to the IP routing table.
+ If the value is false, Routes preferred by BGP are advertised to the IP routing table.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ rib_only_policy_name:
+ description:
+ - Specify the name of a routing policy.
+ The value is a string of 1 to 40 characters.
+ required: false
+ default: null
+ active_route_advertise:
+ description:
+ - If the value is true, BGP is enabled to advertise only optimal routes in the RM to peers.
+ If the value is false, BGP is not enabled to advertise only optimal routes in the RM to peers.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ as_path_neglect:
+ description:
+ - If the value is true, the AS path attribute is ignored when BGP selects an optimal route.
+ If the value is false, the AS path attribute is not ignored when BGP selects an optimal route.
+ An AS path with a smaller length has a higher priority.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ med_none_as_maximum:
+ description:
+ - If the value is true, when BGP selects an optimal route, the system uses 4294967295 as the
+ MED value of a route if the route's attribute does not carry a MED value.
+ If the value is false, the system uses 0 as the MED value of a route if the route's attribute
+ does not carry a MED value.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ router_id_neglect:
+ description:
+ - If the value is true, the router ID attribute is ignored when BGP selects the optimal route.
+ If the value is false, the router ID attribute is not ignored when BGP selects the optimal route.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ igp_metric_ignore:
+ description:
+ - If the value is true, the metrics of next-hop IGP routes are not compared when BGP selects
+ an optimal route.
+ If the value is false, the metrics of next-hop IGP routes are not compared when BGP selects
+ an optimal route.
+ A route with a smaller metric has a higher priority.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ always_compare_med:
+ description:
+ - If the value is true, the MEDs of routes learned from peers in different autonomous systems
+ are compared when BGP selects an optimal route.
+ If the value is false, the MEDs of routes learned from peers in different autonomous systems
+ are not compared when BGP selects an optimal route.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ determin_med:
+ description:
+ - If the value is true, BGP deterministic-MED is enabled.
+ If the value is false, BGP deterministic-MED is disabled.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ preference_external:
+ description:
+ - Set the protocol priority of EBGP routes.
+ The value is an integer ranging from 1 to 255.
+ required: false
+ default: null
+ preference_internal:
+ description:
+ - Set the protocol priority of IBGP routes.
+ The value is an integer ranging from 1 to 255.
+ required: false
+ default: null
+ preference_local:
+ description:
+ - Set the protocol priority of a local BGP route.
+ The value is an integer ranging from 1 to 255.
+ required: false
+ default: null
+ prefrence_policy_name:
+ description:
+ - Set a routing policy to filter routes so that a configured priority is applied to
+ the routes that match the specified policy.
+ The value is a string of 1 to 40 characters.
+ required: false
+ default: null
+ reflect_between_client:
+ description:
+ - If the value is true, route reflection is enabled between clients.
+ If the value is false, route reflection is disabled between clients.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ reflector_cluster_id:
+ description:
+ - Set a cluster ID. Configuring multiple RRs in a cluster can enhance the stability of the network.
+ The value is an integer ranging from 1 to 4294967295.
+ required: false
+ default: null
+ reflector_cluster_ipv4:
+ description:
+ - Set a cluster ipv4 address. The value is expressed in the format of an IPv4 address.
+ required: false
+ default: null
+ rr_filter_number:
+ description:
+ - Set the number of the extended community filter supported by an RR group.
+ The value is a string of 1 to 51 characters.
+ required: false
+ default: null
+ policy_vpn_target:
+ description:
+ - If the value is true, VPN-Target filtering function is performed for received VPN routes.
+ If the value is false, VPN-Target filtering function is not performed for received VPN routes.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ next_hop_sel_depend_type:
+ description:
+ - Next hop select depend type.
+ required: false
+ choices: ['default','dependTunnel', 'dependIp']
+ default: default
+ nhp_relay_route_policy_name:
+ description:
+ - Specify the name of a route-policy for route iteration.
+ The value is a string of 1 to 40 characters.
+ required: false
+ default: null
+ ebgp_if_sensitive:
+ description:
+ - If the value is true, after the fast EBGP interface awareness function is enabled,
+ EBGP sessions on an interface are deleted immediately when the interface goes Down.
+ If the value is false, after the fast EBGP interface awareness function is enabled,
+ EBGP sessions on an interface are not deleted immediately when the interface goes Down.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ reflect_chg_path:
+ description:
+ - If the value is true, the route reflector is enabled to modify route path attributes
+ based on an export policy.
+ If the value is false, the route reflector is disabled from modifying route path attributes
+ based on an export policy.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ add_path_sel_num:
+ description:
+ - Number of Add-Path routes.
+ The value is an integer ranging from 2 to 64.
+ required: false
+ default: null
+ route_sel_delay:
+ description:
+ - Route selection delay.
+ The value is an integer ranging from 0 to 3600.
+ required: false
+ default: null
+ allow_invalid_as:
+ description:
+ - Allow routes with BGP origin AS validation result Invalid to be selected.
+ If the value is true, invalid routes can participate in route selection.
+ If the value is false, invalid routes cannot participate in route selection.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ policy_ext_comm_enable:
+ description:
+ - If the value is true, modifying extended community attributes is allowed.
+ If the value is false, modifying extended community attributes is not allowed.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ supernet_uni_adv:
+ description:
+ - If the value is true, the function to advertise supernetwork unicast routes is enabled.
+ If the value is false, the function to advertise supernetwork unicast routes is disabled.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ supernet_label_adv:
+ description:
+ - If the value is true, the function to advertise supernetwork label is enabled.
+ If the value is false, the function to advertise supernetwork label is disabled.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ ingress_lsp_policy_name:
+ description:
+ - Ingress lsp policy name.
+ required: false
+ default: null
+ originator_prior:
+ description:
+ - Originator prior.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ lowest_priority:
+ description:
+ - If the value is true, enable reduce priority to advertise route.
+ If the value is false, disable reduce priority to advertise route.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ relay_delay_enable:
+ description:
+ - If the value is true, relay delay enable.
+ If the value is false, relay delay disable.
+ required: false
+ choices: ['no_use','true','false']
+ default: no_use
+ import_protocol:
+ description:
+ - Routing protocol from which routes can be imported.
+ required: false
+ choices: ['direct', 'ospf', 'isis', 'static', 'rip', 'ospfv3', 'ripng']
+ default: null
+ import_process_id:
+ description:
+ - Process ID of an imported routing protocol.
+ The value is an integer ranging from 0 to 4294967295.
+ required: false
+ default: null
+ network_address:
+ description:
+ - Specify the IP address advertised by BGP.
+ The value is a string of 0 to 255 characters.
+ required: false
+ default: null
+ mask_len:
+ description:
+ - Specify the mask length of an IP address.
+ The value is an integer ranging from 0 to 128.
+ required: false
+ default: null
+'''
+
+EXAMPLES = '''
+
+- name: CloudEngine BGP address family 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 Address_Family"
+ ce_bgp_af:
+ state: present
+ vrf_name: js
+ af_type: ipv4uni
+ provider: "{{ cli }}"
+
+ - name: "Undo BGP Address_Family"
+ ce_bgp_af:
+ state: absent
+ vrf_name: js
+ af_type: ipv4uni
+ provider: "{{ cli }}"
+
+ - name: "Config import route"
+ ce_bgp_af:
+ state: present
+ vrf_name: js
+ af_type: ipv4uni
+ import_protocol: ospf
+ import_process_id: 123
+ provider: "{{ cli }}"
+
+ - name: "Undo import route"
+ ce_bgp_af:
+ state: absent
+ vrf_name: js
+ af_type: ipv4uni
+ import_protocol: ospf
+ import_process_id: 123
+ provider: "{{ cli }}"
+
+ - name: "Config network route"
+ ce_bgp_af:
+ state: present
+ vrf_name: js
+ af_type: ipv4uni
+ network_address: 1.1.1.1
+ mask_len: 24
+ provider: "{{ cli }}"
+
+ - name: "Undo network route"
+ ce_bgp_af:
+ state: absent
+ vrf_name: js
+ af_type: ipv4uni
+ network_address: 1.1.1.1
+ mask_len: 24
+ 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: {"af_type": "ipv4uni",
+ "state": "present", "vrf_name": "js"}
+existing:
+ description: k/v pairs of existing aaa server
+ returned: always
+ type: dict
+ sample: {}
+end_state:
+ description: k/v pairs of aaa params after module execution
+ returned: always
+ type: dict
+ sample: {"af_type": "ipv4uni", "vrf_name": "js"}
+updates:
+ description: command sent to the device
+ returned: always
+ type: list
+ sample: ["ipv4-family vpn-instance js"]
+'''
+
+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 address family
+CE_GET_BGP_ADDRESS_FAMILY_HEADER = """
+ <filter type="subtree">
+ <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
+ <bgpcomm>
+ <bgpVrfs>
+ <bgpVrf>
+ <vrfName>%s</vrfName>
+ <bgpVrfAFs>
+ <bgpVrfAF>
+ <afType></afType>
+"""
+CE_GET_BGP_ADDRESS_FAMILY_TAIL = """
+ </bgpVrfAF>
+ </bgpVrfAFs>
+ </bgpVrf>
+ </bgpVrfs>
+ </bgpcomm>
+ </bgp>
+ </filter>
+"""
+
+# merge bgp address family
+CE_MERGE_BGP_ADDRESS_FAMILY_HEADER = """
+ <config>
+ <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
+ <bgpcomm>
+ <bgpVrfs>
+ <bgpVrf>
+ <vrfName>%s</vrfName>
+ <bgpVrfAFs>
+ <bgpVrfAF operation="merge">
+ <afType>%s</afType>
+"""
+CE_MERGE_BGP_ADDRESS_FAMILY_TAIL = """
+ </bgpVrfAF>
+ </bgpVrfAFs>
+ </bgpVrf>
+ </bgpVrfs>
+ </bgpcomm>
+ </bgp>
+ </config>
+"""
+
+# create bgp address family
+CE_CREATE_BGP_ADDRESS_FAMILY_HEADER = """
+ <config>
+ <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
+ <bgpcomm>
+ <bgpVrfs>
+ <bgpVrf>
+ <vrfName>%s</vrfName>
+ <bgpVrfAFs>
+ <bgpVrfAF operation="create">
+ <afType>%s</afType>
+"""
+CE_CREATE_BGP_ADDRESS_FAMILY_TAIL = """
+ </bgpVrfAF>
+ </bgpVrfAFs>
+ </bgpVrf>
+ </bgpVrfs>
+ </bgpcomm>
+ </bgp>
+ </config>
+"""
+
+# delete bgp address family
+CE_DELETE_BGP_ADDRESS_FAMILY_HEADER = """
+ <config>
+ <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
+ <bgpcomm>
+ <bgpVrfs>
+ <bgpVrf>
+ <vrfName>%s</vrfName>
+ <bgpVrfAFs>
+ <bgpVrfAF operation="delete">
+ <afType>%s</afType>
+"""
+CE_DELETE_BGP_ADDRESS_FAMILY_TAIL = """
+ </bgpVrfAF>
+ </bgpVrfAFs>
+ </bgpVrf>
+ </bgpVrfs>
+ </bgpcomm>
+ </bgp>
+ </config>
+"""
+
+# get bgp import route
+CE_GET_BGP_IMPORT_AND_NETWORK_ROUTE = """
+ <filter type="subtree">
+ <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
+ <bgpcomm>
+ <bgpVrfs>
+ <bgpVrf>
+ <vrfName>%s</vrfName>
+ <bgpVrfAFs>
+ <bgpVrfAF>
+ <afType>%s</afType>
+ <importRoutes>
+ <importRoute>
+ <importProtocol></importProtocol>
+ <importProcessId></importProcessId>
+ </importRoute>
+ </importRoutes>
+ <networkRoutes>
+ <networkRoute>
+ <networkAddress></networkAddress>
+ <maskLen></maskLen>
+ </networkRoute>
+ </networkRoutes>
+ </bgpVrfAF>
+ </bgpVrfAFs>
+ </bgpVrf>
+ </bgpVrfs>
+ </bgpcomm>
+ </bgp>
+ </filter>
+"""
+
+# merge bgp import route
+CE_MERGE_BGP_IMPORT_ROUTE_HEADER = """
+ <config>
+ <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
+ <bgpcomm>
+ <bgpVrfs>
+ <bgpVrf>
+ <vrfName>%s</vrfName>
+ <bgpVrfAFs>
+ <bgpVrfAF>
+ <afType>%s</afType>
+ <importRoutes>
+ <importRoute operation="merge">
+ <importProtocol>%s</importProtocol>
+ <importProcessId>%s</importProcessId>
+"""
+CE_MERGE_BGP_IMPORT_ROUTE_TAIL = """
+ </importRoute>
+ </importRoutes>
+ </bgpVrfAF>
+ </bgpVrfAFs>
+ </bgpVrf>
+ </bgpVrfs>
+ </bgpcomm>
+ </bgp>
+ </config>
+"""
+
+# create bgp import route
+CE_CREATE_BGP_IMPORT_ROUTE = """
+ <config>
+ <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
+ <bgpcomm>
+ <bgpVrfs>
+ <bgpVrf>
+ <vrfName>%s</vrfName>
+ <bgpVrfAFs>
+ <bgpVrfAF>
+ <afType>%s</afType>
+ <importRoutes>
+ <importRoute operation="create">
+ <importProtocol>%s</importProtocol>
+ <importProcessId>%s</importProcessId>
+ </importRoute>
+ </importRoutes>
+ </bgpVrfAF>
+ </bgpVrfAFs>
+ </bgpVrf>
+ </bgpVrfs>
+ </bgpcomm>
+ </bgp>
+ </config>
+"""
+
+# delete bgp import route
+CE_DELETE_BGP_IMPORT_ROUTE = """
+ <config>
+ <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
+ <bgpcomm>
+ <bgpVrfs>
+ <bgpVrf>
+ <vrfName>%s</vrfName>
+ <bgpVrfAFs>
+ <bgpVrfAF>
+ <afType>%s</afType>
+ <importRoutes>
+ <importRoute operation="delete">
+ <importProtocol>%s</importProtocol>
+ <importProcessId>%s</importProcessId>
+ </importRoute>
+ </importRoutes>
+ </bgpVrfAF>
+ </bgpVrfAFs>
+ </bgpVrf>
+ </bgpVrfs>
+ </bgpcomm>
+ </bgp>
+ </config>
+"""
+
+# get bgp network route
+CE_GET_BGP_NETWORK_ROUTE_HEADER = """
+ <filter type="subtree">
+ <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
+ <bgpcomm>
+ <bgpVrfs>
+ <bgpVrf>
+ <vrfName>%s</vrfName>
+ <bgpVrfAFs>
+ <bgpVrfAF>
+ <afType>%s</afType>
+ <networkRoutes>
+ <networkRoute>
+ <networkAddress></networkAddress>
+ <maskLen></maskLen>
+"""
+CE_GET_BGP_NETWORK_ROUTE_TAIL = """
+ </networkRoute>
+ </networkRoutes>
+ </bgpVrfAF>
+ </bgpVrfAFs>
+ </bgpVrf>
+ </bgpVrfs>
+ </bgpcomm>
+ </bgp>
+ </filter>
+"""
+
+# merge bgp network route
+CE_MERGE_BGP_NETWORK_ROUTE_HEADER = """
+ <config>
+ <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
+ <bgpcomm>
+ <bgpVrfs>
+ <bgpVrf>
+ <vrfName>%s</vrfName>
+ <bgpVrfAFs>
+ <bgpVrfAF>
+ <afType>%s</afType>
+ <networkRoutes>
+ <networkRoute operation="merge">
+ <networkAddress>%s</networkAddress>
+ <maskLen>%s</maskLen>
+"""
+CE_MERGE_BGP_NETWORK_ROUTE_TAIL = """
+ </networkRoute>
+ </networkRoutes>
+ </bgpVrfAF>
+ </bgpVrfAFs>
+ </bgpVrf>
+ </bgpVrfs>
+ </bgpcomm>
+ </bgp>
+ </config>
+"""
+
+# create bgp network route
+CE_CREATE_BGP_NETWORK_ROUTE = """
+ <config>
+ <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
+ <bgpcomm>
+ <bgpVrfs>
+ <bgpVrf>
+ <vrfName>%s</vrfName>
+ <bgpVrfAFs>
+ <bgpVrfAF>
+ <afType>%s</afType>
+ <networkRoutes>
+ <networkRoute operation="create">
+ <networkAddress>%s</networkAddress>
+ <maskLen>%s</maskLen>
+ </networkRoute>
+ </networkRoutes>
+ </bgpVrfAF>
+ </bgpVrfAFs>
+ </bgpVrf>
+ </bgpVrfs>
+ </bgpcomm>
+ </bgp>
+ </config>
+"""
+
+# delete bgp network route
+CE_DELETE_BGP_NETWORK_ROUTE = """
+ <config>
+ <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
+ <bgpcomm>
+ <bgpVrfs>
+ <bgpVrf>
+ <vrfName>%s</vrfName>
+ <bgpVrfAFs>
+ <bgpVrfAF>
+ <afType>%s</afType>
+ <networkRoutes>
+ <networkRoute operation="delete">
+ <networkAddress>%s</networkAddress>
+ <maskLen>%s</maskLen>
+ </networkRoute>
+ </networkRoutes>
+ </bgpVrfAF>
+ </bgpVrfAFs>
+ </bgpVrf>
+ </bgpVrfs>
+ </bgpcomm>
+ </bgp>
+ </config>
+"""
+
+# bgp import and network route header
+CE_BGP_IMPORT_NETWORK_ROUTE_HEADER = """
+ <config>
+ <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
+ <bgpcomm>
+ <bgpVrfs>
+ <bgpVrf>
+ <vrfName>%s</vrfName>
+ <bgpVrfAFs>
+ <bgpVrfAF>
+ <afType>%s</afType>
+"""
+CE_BGP_IMPORT_NETWORK_ROUTE_TAIL = """
+ </bgpVrfAF>
+ </bgpVrfAFs>
+ </bgpVrf>
+ </bgpVrfs>
+ </bgpcomm>
+ </bgp>
+ </config>
+"""
+CE_BGP_MERGE_IMPORT_UNIT = """
+ <importRoutes>
+ <importRoute operation="merge">
+ <importProtocol>%s</importProtocol>
+ <importProcessId>%s</importProcessId>
+ </importRoute>
+ </importRoutes>
+"""
+CE_BGP_CREATE_IMPORT_UNIT = """
+ <importRoutes>
+ <importRoute operation="create">
+ <importProtocol>%s</importProtocol>
+ <importProcessId>%s</importProcessId>
+ </importRoute>
+ </importRoutes>
+"""
+CE_BGP_DELETE_IMPORT_UNIT = """
+ <importRoutes>
+ <importRoute operation="delete">
+ <importProtocol>%s</importProtocol>
+ <importProcessId>%s</importProcessId>
+ </importRoute>
+ </importRoutes>
+"""
+CE_BGP_MERGE_NETWORK_UNIT = """
+ <networkRoutes>
+ <networkRoute operation="merge">
+ <networkAddress>%s</networkAddress>
+ <maskLen>%s</maskLen>
+ </networkRoute>
+ </networkRoutes>
+"""
+CE_BGP_CREATE_NETWORK_UNIT = """
+ <networkRoutes>
+ <networkRoute operation="create">
+ <networkAddress>%s</networkAddress>
+ <maskLen>%s</maskLen>
+ </networkRoute>
+ </networkRoutes>
+"""
+CE_BGP_DELETE_NETWORK_UNIT = """
+ <networkRoutes>
+ <networkRoute operation="delete">
+ <networkAddress>%s</networkAddress>
+ <maskLen>%s</maskLen>
+ </networkRoute>
+ </networkRoutes>
+"""
+
+
+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 BgpAf(object):
+ """ Manages BGP Address-family 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_af_args(self, **kwargs):
+ """ check_bgp_af_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)
+ else:
+ module.fail_json(msg='Error: Please input vrf_name.')
+
+ state = module.params['state']
+ af_type = module.params['af_type']
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if state == "present":
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<afType>(.*)</afType>.*', recv_xml)
+
+ if re_find:
+ result["af_type"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != af_type:
+ need_cfg = True
+ else:
+ need_cfg = True
+ else:
+ if "<data/>" in recv_xml:
+ pass
+ else:
+ re_find = re.findall(
+ r'.*<afType>(.*)</afType>.*', recv_xml)
+
+ if re_find:
+ result["af_type"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] == af_type:
+ need_cfg = True
+
+ result["need_cfg"] = need_cfg
+ return result
+
+ def check_bgp_af_other_can_del(self, **kwargs):
+ """ check_bgp_af_other_can_del """
+ module = kwargs["module"]
+ result = dict()
+ need_cfg = False
+
+ state = module.params['state']
+ vrf_name = module.params['vrf_name']
+
+ router_id = module.params['router_id']
+ if router_id:
+ if len(router_id) > 255:
+ module.fail_json(
+ msg='Error: The len of router_id %s is out of [0 - 255].' % router_id)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<routerId></routerId>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if state == "present":
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<routerId>(.*)</routerId>.*', recv_xml)
+
+ if re_find:
+ if re_find[0] != router_id:
+ need_cfg = True
+ else:
+ need_cfg = True
+ else:
+ if "<data/>" in recv_xml:
+ pass
+ else:
+ re_find = re.findall(
+ r'.*<routerId>(.*)</routerId>.*', recv_xml)
+
+ if re_find:
+ if re_find[0] == router_id:
+ need_cfg = True
+ else:
+ pass
+
+ determin_med = module.params['determin_med']
+ if determin_med != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<determinMed></determinMed>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if state == "present":
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<determinMed>(.*)</determinMed>.*', recv_xml)
+
+ if re_find:
+ if re_find[0] != determin_med:
+ need_cfg = True
+ else:
+ need_cfg = True
+ else:
+ if "<data/>" in recv_xml:
+ pass
+ else:
+ re_find = re.findall(
+ r'.*<determinMed>(.*)</determinMed>.*', recv_xml)
+
+ if re_find:
+ if re_find[0] == determin_med:
+ need_cfg = True
+ else:
+ pass
+
+ ebgp_if_sensitive = module.params['ebgp_if_sensitive']
+ if ebgp_if_sensitive != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<ebgpIfSensitive></ebgpIfSensitive>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if state == "present":
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<ebgpIfSensitive>(.*)</ebgpIfSensitive>.*', recv_xml)
+
+ if re_find:
+ if re_find[0] != ebgp_if_sensitive:
+ need_cfg = True
+ else:
+ need_cfg = True
+ else:
+ if "<data/>" in recv_xml:
+ pass
+ else:
+ re_find = re.findall(
+ r'.*<ebgpIfSensitive>(.*)</ebgpIfSensitive>.*', recv_xml)
+
+ if re_find:
+ if re_find[0] == ebgp_if_sensitive:
+ need_cfg = True
+ else:
+ pass
+
+ relay_delay_enable = module.params['relay_delay_enable']
+ if relay_delay_enable != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<relayDelayEnable></relayDelayEnable>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if state == "present":
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<relayDelayEnable>(.*)</relayDelayEnable>.*', recv_xml)
+
+ if re_find:
+ if re_find[0] != relay_delay_enable:
+ need_cfg = True
+ else:
+ need_cfg = True
+ else:
+ if "<data/>" in recv_xml:
+ pass
+ else:
+ re_find = re.findall(
+ r'.*<relayDelayEnable>(.*)</relayDelayEnable>.*', recv_xml)
+
+ if re_find:
+ if re_find[0] == relay_delay_enable:
+ need_cfg = True
+ else:
+ pass
+
+ result["need_cfg"] = need_cfg
+ return result
+
+ def check_bgp_af_other_args(self, **kwargs):
+ """ check_bgp_af_other_args """
+
+ module = kwargs["module"]
+ result = dict()
+ need_cfg = False
+
+ vrf_name = module.params['vrf_name']
+
+ max_load_ibgp_num = module.params['max_load_ibgp_num']
+ if max_load_ibgp_num:
+ if int(max_load_ibgp_num) > 65535 or int(max_load_ibgp_num) < 1:
+ module.fail_json(
+ msg='Error: The value of max_load_ibgp_num %s is out of [1 - 65535].' % max_load_ibgp_num)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<maxLoadIbgpNum></maxLoadIbgpNum>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<maxLoadIbgpNum>(.*)</maxLoadIbgpNum>.*', recv_xml)
+
+ if re_find:
+ result["max_load_ibgp_num"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != max_load_ibgp_num:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ ibgp_ecmp_nexthop_changed = module.params['ibgp_ecmp_nexthop_changed']
+ if ibgp_ecmp_nexthop_changed != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<ibgpEcmpNexthopChanged></ibgpEcmpNexthopChanged>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<ibgpEcmpNexthopChanged>(.*)</ibgpEcmpNexthopChanged>.*', recv_xml)
+
+ if re_find:
+ result["ibgp_ecmp_nexthop_changed"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != ibgp_ecmp_nexthop_changed:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ max_load_ebgp_num = module.params['max_load_ebgp_num']
+ if max_load_ebgp_num:
+ if int(max_load_ebgp_num) > 65535 or int(max_load_ebgp_num) < 1:
+ module.fail_json(
+ msg='Error: The value of max_load_ebgp_num %s is out of [1 - 65535].' % max_load_ebgp_num)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<maxLoadEbgpNum></maxLoadEbgpNum>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<maxLoadEbgpNum>(.*)</maxLoadEbgpNum>.*', recv_xml)
+
+ if re_find:
+ result["max_load_ebgp_num"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != max_load_ebgp_num:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ ebgp_ecmp_nexthop_changed = module.params['ebgp_ecmp_nexthop_changed']
+ if ebgp_ecmp_nexthop_changed != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<ebgpEcmpNexthopChanged></ebgpEcmpNexthopChanged>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<ebgpEcmpNexthopChanged>(.*)</ebgpEcmpNexthopChanged>.*', recv_xml)
+
+ if re_find:
+ result["ebgp_ecmp_nexthop_changed"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != ebgp_ecmp_nexthop_changed:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ maximum_load_balance = module.params['maximum_load_balance']
+ if maximum_load_balance:
+ if int(maximum_load_balance) > 65535 or int(maximum_load_balance) < 1:
+ module.fail_json(
+ msg='Error: The value of maximum_load_balance %s is out of [1 - 65535].' % maximum_load_balance)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<maximumLoadBalance></maximumLoadBalance>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<maximumLoadBalance>(.*)</maximumLoadBalance>.*', recv_xml)
+
+ if re_find:
+ result["maximum_load_balance"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != maximum_load_balance:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ ecmp_nexthop_changed = module.params['ecmp_nexthop_changed']
+ if ecmp_nexthop_changed != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<ecmpNexthopChanged></ecmpNexthopChanged>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<ecmpNexthopChanged>(.*)</ecmpNexthopChanged>.*', recv_xml)
+
+ if re_find:
+ result["ecmp_nexthop_changed"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != ecmp_nexthop_changed:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ default_local_pref = module.params['default_local_pref']
+ if default_local_pref:
+ if int(default_local_pref) < 0:
+ module.fail_json(
+ msg='Error: The value of default_local_pref %s is out of [0 - 4294967295].' % default_local_pref)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<defaultLocalPref></defaultLocalPref>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<defaultLocalPref>(.*)</defaultLocalPref>.*', recv_xml)
+
+ if re_find:
+ result["default_local_pref"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != default_local_pref:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ default_med = module.params['default_med']
+ if default_med:
+ if int(default_med) < 0:
+ module.fail_json(
+ msg='Error: The value of default_med %s is out of [0 - 4294967295].' % default_med)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<defaultMed></defaultMed>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<defaultMed>(.*)</defaultMed>.*', recv_xml)
+
+ if re_find:
+ result["default_med"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != default_med:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ default_rt_import_enable = module.params['default_rt_import_enable']
+ if default_rt_import_enable != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<defaultRtImportEnable></defaultRtImportEnable>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<defaultRtImportEnable>(.*)</defaultRtImportEnable>.*', recv_xml)
+
+ if re_find:
+ result["default_rt_import_enable"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != default_rt_import_enable:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ router_id = module.params['router_id']
+ if router_id:
+ if len(router_id) > 255:
+ module.fail_json(
+ msg='Error: The len of router_id %s is out of [0 - 255].' % router_id)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<routerId></routerId>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<routerId>(.*)</routerId>.*', recv_xml)
+
+ if re_find:
+ result["router_id"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != router_id:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ vrf_rid_auto_sel = module.params['vrf_rid_auto_sel']
+ if vrf_rid_auto_sel != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<vrfRidAutoSel></vrfRidAutoSel>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<vrfRidAutoSel>(.*)</vrfRidAutoSel>.*', recv_xml)
+
+ if re_find:
+ result["vrf_rid_auto_sel"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != vrf_rid_auto_sel:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ nexthop_third_party = module.params['nexthop_third_party']
+ if nexthop_third_party != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<nexthopThirdParty></nexthopThirdParty>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<nexthopThirdParty>(.*)</nexthopThirdParty>.*', recv_xml)
+
+ if re_find:
+ result["nexthop_third_party"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != nexthop_third_party:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ summary_automatic = module.params['summary_automatic']
+ if summary_automatic != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<summaryAutomatic></summaryAutomatic>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<summaryAutomatic>(.*)</summaryAutomatic>.*', recv_xml)
+
+ if re_find:
+ result["summary_automatic"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != summary_automatic:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ auto_frr_enable = module.params['auto_frr_enable']
+ if auto_frr_enable != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<autoFrrEnable></autoFrrEnable>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<autoFrrEnable>(.*)</autoFrrEnable>.*', recv_xml)
+
+ if re_find:
+ result["auto_frr_enable"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != auto_frr_enable:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ load_balancing_as_path_ignore = module.params['load_balancing_as_path_ignore']
+ if load_balancing_as_path_ignore != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<loadBalancingAsPathIgnore></loadBalancingAsPathIgnore>" + \
+ CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<loadBalancingAsPathIgnore>(.*)</loadBalancingAsPathIgnore>.*', recv_xml)
+
+ if re_find:
+ result["load_balancing_as_path_ignore"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != load_balancing_as_path_ignore:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ rib_only_enable = module.params['rib_only_enable']
+ if rib_only_enable != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<ribOnlyEnable></ribOnlyEnable>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<ribOnlyEnable>(.*)</ribOnlyEnable>.*', recv_xml)
+
+ if re_find:
+ result["rib_only_enable"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != rib_only_enable:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ rib_only_policy_name = module.params['rib_only_policy_name']
+ if rib_only_policy_name:
+ if len(rib_only_policy_name) > 40 or len(rib_only_policy_name) < 1:
+ module.fail_json(
+ msg='Error: The len of rib_only_policy_name %s is out of [1 - 40].' % rib_only_policy_name)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<ribOnlyPolicyName></ribOnlyPolicyName>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<ribOnlyPolicyName>(.*)</ribOnlyPolicyName>.*', recv_xml)
+
+ if re_find:
+ result["rib_only_policy_name"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != rib_only_policy_name:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ active_route_advertise = module.params['active_route_advertise']
+ if active_route_advertise != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<activeRouteAdvertise></activeRouteAdvertise>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<activeRouteAdvertise>(.*)</activeRouteAdvertise>.*', recv_xml)
+
+ if re_find:
+ result["active_route_advertise"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != active_route_advertise:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ as_path_neglect = module.params['as_path_neglect']
+ if as_path_neglect != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<asPathNeglect></asPathNeglect>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<asPathNeglect>(.*)</asPathNeglect>.*', recv_xml)
+
+ if re_find:
+ result["as_path_neglect"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != as_path_neglect:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ med_none_as_maximum = module.params['med_none_as_maximum']
+ if med_none_as_maximum != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<medNoneAsMaximum></medNoneAsMaximum>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<medNoneAsMaximum>(.*)</medNoneAsMaximum>.*', recv_xml)
+
+ if re_find:
+ result["med_none_as_maximum"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != med_none_as_maximum:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ router_id_neglect = module.params['router_id_neglect']
+ if router_id_neglect != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<routerIdNeglect></routerIdNeglect>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<routerIdNeglect>(.*)</routerIdNeglect>.*', recv_xml)
+
+ if re_find:
+ result["router_id_neglect"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != router_id_neglect:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ igp_metric_ignore = module.params['igp_metric_ignore']
+ if igp_metric_ignore != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<igpMetricIgnore></igpMetricIgnore>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<igpMetricIgnore>(.*)</igpMetricIgnore>.*', recv_xml)
+
+ if re_find:
+ result["igp_metric_ignore"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != igp_metric_ignore:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ always_compare_med = module.params['always_compare_med']
+ if always_compare_med != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<alwaysCompareMed></alwaysCompareMed>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<alwaysCompareMed>(.*)</alwaysCompareMed>.*', recv_xml)
+
+ if re_find:
+ result["always_compare_med"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != always_compare_med:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ determin_med = module.params['determin_med']
+ if determin_med != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<determinMed></determinMed>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<determinMed>(.*)</determinMed>.*', recv_xml)
+
+ if re_find:
+ result["determin_med"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != determin_med:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ preference_external = module.params['preference_external']
+ if preference_external:
+ if int(preference_external) > 255 or int(preference_external) < 1:
+ module.fail_json(
+ msg='Error: The value of preference_external %s is out of [1 - 255].' % preference_external)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<preferenceExternal></preferenceExternal>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<preferenceExternal>(.*)</preferenceExternal>.*', recv_xml)
+
+ if re_find:
+ result["preference_external"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != preference_external:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ preference_internal = module.params['preference_internal']
+ if preference_internal:
+ if int(preference_internal) > 255 or int(preference_internal) < 1:
+ module.fail_json(
+ msg='Error: The value of preference_internal %s is out of [1 - 255].' % preference_internal)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<preferenceInternal></preferenceInternal>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<preferenceInternal>(.*)</preferenceInternal>.*', recv_xml)
+
+ if re_find:
+ result["preference_internal"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != preference_internal:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ preference_local = module.params['preference_local']
+ if preference_local:
+ if int(preference_local) > 255 or int(preference_local) < 1:
+ module.fail_json(
+ msg='Error: The value of preference_local %s is out of [1 - 255].' % preference_local)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<preferenceLocal></preferenceLocal>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<preferenceLocal>(.*)</preferenceLocal>.*', recv_xml)
+
+ if re_find:
+ result["preference_local"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != preference_local:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ prefrence_policy_name = module.params['prefrence_policy_name']
+ if prefrence_policy_name:
+ if len(prefrence_policy_name) > 40 or len(prefrence_policy_name) < 1:
+ module.fail_json(
+ msg='Error: The len of prefrence_policy_name %s is out of [1 - 40].' % prefrence_policy_name)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<prefrencePolicyName></prefrencePolicyName>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<prefrencePolicyName>(.*)</prefrencePolicyName>.*', recv_xml)
+
+ if re_find:
+ result["prefrence_policy_name"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != prefrence_policy_name:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ reflect_between_client = module.params['reflect_between_client']
+ if reflect_between_client != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<reflectBetweenClient></reflectBetweenClient>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<reflectBetweenClient>(.*)</reflectBetweenClient>.*', recv_xml)
+
+ if re_find:
+ result["reflect_between_client"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != reflect_between_client:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ reflector_cluster_id = module.params['reflector_cluster_id']
+ if reflector_cluster_id:
+ if int(reflector_cluster_id) < 0:
+ module.fail_json(
+ msg='Error: The value of reflector_cluster_id %s is out of '
+ '[1 - 4294967295].' % reflector_cluster_id)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<reflectorClusterId></reflectorClusterId>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<reflectorClusterId>(.*)</reflectorClusterId>.*', recv_xml)
+
+ if re_find:
+ result["reflector_cluster_id"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != reflector_cluster_id:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ reflector_cluster_ipv4 = module.params['reflector_cluster_ipv4']
+ if reflector_cluster_ipv4:
+ if len(reflector_cluster_ipv4) > 255:
+ module.fail_json(
+ msg='Error: The len of reflector_cluster_ipv4 %s is out of [0 - 255].' % reflector_cluster_ipv4)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<reflectorClusterIpv4></reflectorClusterIpv4>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<reflectorClusterIpv4>(.*)</reflectorClusterIpv4>.*', recv_xml)
+
+ if re_find:
+ result["reflector_cluster_ipv4"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != reflector_cluster_ipv4:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ rr_filter_number = module.params['rr_filter_number']
+ if rr_filter_number:
+ if len(rr_filter_number) > 51 or len(rr_filter_number) < 1:
+ module.fail_json(
+ msg='Error: The len of rr_filter_number %s is out of [1 - 51].' % rr_filter_number)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<rrFilterNumber></rrFilterNumber>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<rrFilterNumber>(.*)</rrFilterNumber>.*', recv_xml)
+
+ if re_find:
+ result["rr_filter_number"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != rr_filter_number:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ policy_vpn_target = module.params['policy_vpn_target']
+ if policy_vpn_target != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<policyVpnTarget></policyVpnTarget>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<policyVpnTarget>(.*)</policyVpnTarget>.*', recv_xml)
+
+ if re_find:
+ result["policy_vpn_target"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != policy_vpn_target:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ next_hop_sel_depend_type = module.params['next_hop_sel_depend_type']
+ if next_hop_sel_depend_type:
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<nextHopSelDependType></nextHopSelDependType>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<nextHopSelDependType>(.*)</nextHopSelDependType>.*', recv_xml)
+
+ if re_find:
+ result["next_hop_sel_depend_type"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != next_hop_sel_depend_type:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ nhp_relay_route_policy_name = module.params[
+ 'nhp_relay_route_policy_name']
+ if nhp_relay_route_policy_name:
+ if len(nhp_relay_route_policy_name) > 40 or len(nhp_relay_route_policy_name) < 1:
+ module.fail_json(
+ msg='Error: The len of nhp_relay_route_policy_name %s is '
+ 'out of [1 - 40].' % nhp_relay_route_policy_name)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<nhpRelayRoutePolicyName></nhpRelayRoutePolicyName>" + \
+ CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<nhpRelayRoutePolicyName>(.*)</nhpRelayRoutePolicyName>.*', recv_xml)
+
+ if re_find:
+ result["nhp_relay_route_policy_name"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != nhp_relay_route_policy_name:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ ebgp_if_sensitive = module.params['ebgp_if_sensitive']
+ if ebgp_if_sensitive != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<ebgpIfSensitive></ebgpIfSensitive>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<ebgpIfSensitive>(.*)</ebgpIfSensitive>.*', recv_xml)
+
+ if re_find:
+ result["ebgp_if_sensitive"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != ebgp_if_sensitive:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ reflect_chg_path = module.params['reflect_chg_path']
+ if reflect_chg_path != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<reflectChgPath></reflectChgPath>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<reflectChgPath>(.*)</reflectChgPath>.*', recv_xml)
+
+ if re_find:
+ result["reflect_chg_path"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != reflect_chg_path:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ add_path_sel_num = module.params['add_path_sel_num']
+ if add_path_sel_num:
+ if int(add_path_sel_num) > 64 or int(add_path_sel_num) < 2:
+ module.fail_json(
+ msg='Error: The value of add_path_sel_num %s is out of [2 - 64].' % add_path_sel_num)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<addPathSelNum></addPathSelNum>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<addPathSelNum>(.*)</addPathSelNum>.*', recv_xml)
+
+ if re_find:
+ result["add_path_sel_num"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != add_path_sel_num:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ route_sel_delay = module.params['route_sel_delay']
+ if route_sel_delay:
+ if int(route_sel_delay) > 3600 or int(route_sel_delay) < 0:
+ module.fail_json(
+ msg='Error: The value of route_sel_delay %s is out of [0 - 3600].' % route_sel_delay)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<routeSelDelay></routeSelDelay>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<routeSelDelay>(.*)</routeSelDelay>.*', recv_xml)
+
+ if re_find:
+ result["route_sel_delay"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != route_sel_delay:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ allow_invalid_as = module.params['allow_invalid_as']
+ if allow_invalid_as != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<allowInvalidAs></allowInvalidAs>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<allowInvalidAs>(.*)</allowInvalidAs>.*', recv_xml)
+
+ if re_find:
+ result["allow_invalid_as"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != allow_invalid_as:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ policy_ext_comm_enable = module.params['policy_ext_comm_enable']
+ if policy_ext_comm_enable != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<policyExtCommEnable></policyExtCommEnable>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<policyExtCommEnable>(.*)</policyExtCommEnable>.*', recv_xml)
+
+ if re_find:
+ result["policy_ext_comm_enable"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != policy_ext_comm_enable:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ supernet_uni_adv = module.params['supernet_uni_adv']
+ if supernet_uni_adv != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<supernetUniAdv></supernetUniAdv>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<supernetUniAdv>(.*)</supernetUniAdv>.*', recv_xml)
+
+ if re_find:
+ result["supernet_uni_adv"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != supernet_uni_adv:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ supernet_label_adv = module.params['supernet_label_adv']
+ if supernet_label_adv != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<supernetLabelAdv></supernetLabelAdv>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<supernetLabelAdv>(.*)</supernetLabelAdv>.*', recv_xml)
+
+ if re_find:
+ result["supernet_label_adv"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != supernet_label_adv:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ ingress_lsp_policy_name = module.params['ingress_lsp_policy_name']
+ if ingress_lsp_policy_name:
+ if len(ingress_lsp_policy_name) > 40 or len(ingress_lsp_policy_name) < 1:
+ module.fail_json(
+ msg='Error: The len of ingress_lsp_policy_name %s is out of [1 - 40].' % ingress_lsp_policy_name)
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<ingressLspPolicyName></ingressLspPolicyName>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<ingressLspPolicyName>(.*)</ingressLspPolicyName>.*', recv_xml)
+
+ if re_find:
+ result["ingress_lsp_policy_name"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != ingress_lsp_policy_name:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ originator_prior = module.params['originator_prior']
+ if originator_prior != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<originatorPrior></originatorPrior>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<originatorPrior>(.*)</originatorPrior>.*', recv_xml)
+
+ if re_find:
+ result["originator_prior"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != originator_prior:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ lowest_priority = module.params['lowest_priority']
+ if lowest_priority != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<lowestPriority></lowestPriority>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<lowestPriority>(.*)</lowestPriority>.*', recv_xml)
+
+ if re_find:
+ result["lowest_priority"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != lowest_priority:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ relay_delay_enable = module.params['relay_delay_enable']
+ if relay_delay_enable != 'no_use':
+
+ conf_str = CE_GET_BGP_ADDRESS_FAMILY_HEADER % vrf_name + \
+ "<relayDelayEnable></relayDelayEnable>" + CE_GET_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if "<data/>" in recv_xml:
+ need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<relayDelayEnable>(.*)</relayDelayEnable>.*', recv_xml)
+
+ if re_find:
+ result["relay_delay_enable"] = re_find
+ result["vrf_name"] = vrf_name
+ if re_find[0] != relay_delay_enable:
+ need_cfg = True
+ else:
+ need_cfg = True
+
+ result["need_cfg"] = need_cfg
+ return result
+
+ def check_bgp_import_network_route(self, **kwargs):
+ """ check_bgp_import_network_route """
+
+ module = kwargs["module"]
+ result = dict()
+ import_need_cfg = False
+ network_need_cfg = False
+
+ vrf_name = module.params['vrf_name']
+
+ state = module.params['state']
+ af_type = module.params['af_type']
+ import_protocol = module.params['import_protocol']
+ import_process_id = module.params['import_process_id']
+
+ if import_protocol and (import_protocol != "direct" and import_protocol != "static"):
+ if not import_process_id:
+ module.fail_json(
+ msg='Error: Please input import_protocol and import_process_id value at the same time.')
+ else:
+ if int(import_process_id) < 0:
+ module.fail_json(
+ msg='Error: The value of import_process_id %s is out of [0 - 4294967295].' % import_process_id)
+
+ if import_process_id:
+ if not import_protocol:
+ module.fail_json(
+ msg='Error: Please input import_protocol and import_process_id value at the same time.')
+
+ network_address = module.params['network_address']
+ mask_len = module.params['mask_len']
+
+ if network_address:
+ if not mask_len:
+ module.fail_json(
+ msg='Error: Please input network_address and mask_len value at the same time.')
+ if mask_len:
+ if not network_address:
+ module.fail_json(
+ msg='Error: Please input network_address and mask_len value at the same time.')
+
+ conf_str = CE_GET_BGP_IMPORT_AND_NETWORK_ROUTE % (vrf_name, af_type)
+ recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
+
+ if import_protocol:
+
+ if import_protocol == "direct" or import_protocol == "static":
+ import_process_id = "0"
+ else:
+ if not import_process_id or import_process_id == "0":
+ module.fail_json(
+ msg='Error: Please input import_process_id not 0 when import_protocol is '
+ '[ospf, isis, rip, ospfv3, ripng].')
+
+ bgp_import_route_new = (import_protocol, import_process_id)
+
+ if state == "present":
+ if "<data/>" in recv_xml:
+ import_need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<importProtocol>(.*)</importProtocol>.*\s.*<importProcessId>(.*)</importProcessId>.*',
+ recv_xml)
+
+ if re_find:
+ result["bgp_import_route"] = re_find
+ result["vrf_name"] = vrf_name
+ if bgp_import_route_new not in re_find:
+ import_need_cfg = True
+ else:
+ import_need_cfg = True
+ else:
+ if "<data/>" in recv_xml:
+ pass
+ else:
+ re_find = re.findall(
+ r'.*<importProtocol>(.*)</importProtocol>.*\s.*<importProcessId>(.*)</importProcessId>.*',
+ recv_xml)
+
+ if re_find:
+ result["bgp_import_route"] = re_find
+ result["vrf_name"] = vrf_name
+ if bgp_import_route_new in re_find:
+ import_need_cfg = True
+
+ if network_address and mask_len:
+
+ bgp_network_route_new = (network_address, mask_len)
+
+ if not check_ip_addr(ipaddr=network_address):
+ module.fail_json(
+ msg='Error: The network_address %s is invalid.' % network_address)
+
+ if len(mask_len) > 128:
+ module.fail_json(
+ msg='Error: The len of mask_len %s is out of [0 - 128].' % mask_len)
+
+ if state == "present":
+ if "<data/>" in recv_xml:
+ network_need_cfg = True
+ else:
+ re_find = re.findall(
+ r'.*<networkAddress>(.*)</networkAddress>.*\s.*<maskLen>(.*)</maskLen>.*', recv_xml)
+
+ if re_find:
+ result["bgp_network_route"] = re_find
+ result["vrf_name"] = vrf_name
+ if bgp_network_route_new not in re_find:
+ network_need_cfg = True
+ else:
+ network_need_cfg = True
+ else:
+ if "<data/>" in recv_xml:
+ pass
+ else:
+ re_find = re.findall(
+ r'.*<networkAddress>(.*)</networkAddress>.*\s.*<maskLen>(.*)</maskLen>.*', recv_xml)
+
+ if re_find:
+ result["bgp_network_route"] = re_find
+ result["vrf_name"] = vrf_name
+ if bgp_network_route_new in re_find:
+ network_need_cfg = True
+
+ result["import_need_cfg"] = import_need_cfg
+ result["network_need_cfg"] = network_need_cfg
+ return result
+
+ def merge_bgp_af(self, **kwargs):
+ """ merge_bgp_af """
+
+ module = kwargs["module"]
+
+ vrf_name = module.params['vrf_name']
+
+ af_type = module.params['af_type']
+
+ conf_str = CE_MERGE_BGP_ADDRESS_FAMILY_HEADER % (
+ vrf_name, af_type) + CE_MERGE_BGP_ADDRESS_FAMILY_TAIL
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "<ok/>" not in recv_xml:
+ module.fail_json(msg='Error: Merge bgp address family failed.')
+
+ cmds = []
+
+ cmd = "ipv4-family vpn-instance %s" % vrf_name
+ cmds.append(cmd)
+
+ if af_type == "ipv4multi":
+ cmd = "ipv4-family multicast"
+ elif af_type == "ipv4vpn":
+ cmd = "ipv4-family vpnv4"
+ elif af_type == "ipv6uni":
+ cmd = "ipv6-family unicast"
+ elif af_type == "ipv6vpn":
+ cmd = "ipv6-family vpnv6"
+ elif af_type == "evpn":
+ cmd = "ipv6-family vpn-instance %s" % vrf_name
+ cmds.append(cmd)
+
+ return cmds
+
+ def create_bgp_af(self, **kwargs):
+ """ create_bgp_af """
+
+ module = kwargs["module"]
+
+ vrf_name = module.params['vrf_name']
+
+ af_type = module.params['af_type']
+
+ conf_str = CE_CREATE_BGP_ADDRESS_FAMILY_HEADER % (
+ vrf_name, af_type) + CE_CREATE_BGP_ADDRESS_FAMILY_TAIL
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "<ok/>" not in recv_xml:
+ module.fail_json(msg='Error: Create bgp address family failed.')
+
+ cmds = []
+
+ cmd = "ipv4-family vpn-instance %s" % vrf_name
+ cmds.append(cmd)
+
+ if af_type == "ipv4multi":
+ cmd = "ipv4-family multicast"
+ elif af_type == "ipv4vpn":
+ cmd = "ipv4-family vpnv4"
+ elif af_type == "ipv6uni":
+ cmd = "ipv6-family unicast"
+ elif af_type == "ipv6vpn":
+ cmd = "ipv6-family vpnv6"
+ elif af_type == "evpn":
+ cmd = "ipv6-family vpn-instance %s" % vrf_name
+ cmds.append(cmd)
+
+ return cmds
+
+ def delete_bgp_af(self, **kwargs):
+ """ delete_bgp_af """
+
+ module = kwargs["module"]
+
+ vrf_name = module.params['vrf_name']
+
+ af_type = module.params['af_type']
+
+ conf_str = CE_DELETE_BGP_ADDRESS_FAMILY_HEADER % (
+ vrf_name, af_type) + CE_DELETE_BGP_ADDRESS_FAMILY_TAIL
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "<ok/>" not in recv_xml:
+ module.fail_json(msg='Error: Delete bgp address family failed.')
+
+ cmds = []
+
+ cmd = "undo ipv4-family vpn-instance %s" % vrf_name
+ cmds.append(cmd)
+
+ if af_type == "ipv4multi":
+ cmd = "undo ipv4-family multicast"
+ elif af_type == "ipv4vpn":
+ cmd = "undo ipv4-family vpnv4"
+ elif af_type == "ipv6uni":
+ cmd = "undo ipv6-family unicast"
+ elif af_type == "ipv6vpn":
+ cmd = "undo ipv6-family vpnv6"
+ elif af_type == "evpn":
+ cmd = "undo ipv6-family vpn-instance %s" % vrf_name
+ cmds.append(cmd)
+
+ return cmds
+
+ def merge_bgp_af_other(self, **kwargs):
+ """ merge_bgp_af_other """
+
+ module = kwargs["module"]
+ vrf_name = module.params['vrf_name']
+ af_type = module.params['af_type']
+
+ conf_str = CE_MERGE_BGP_ADDRESS_FAMILY_HEADER % (vrf_name, af_type)
+
+ cmds = []
+
+ max_load_ibgp_num = module.params['max_load_ibgp_num']
+ if max_load_ibgp_num:
+ conf_str += "<maxLoadIbgpNum>%s</maxLoadIbgpNum>" % max_load_ibgp_num
+
+ cmd = "maximum load-balancing ibgp %s" % max_load_ibgp_num
+ cmds.append(cmd)
+
+ ibgp_ecmp_nexthop_changed = module.params['ibgp_ecmp_nexthop_changed']
+ if ibgp_ecmp_nexthop_changed != 'no_use':
+ conf_str += "<ibgpEcmpNexthopChanged>%s</ibgpEcmpNexthopChanged>" % ibgp_ecmp_nexthop_changed
+
+ if ibgp_ecmp_nexthop_changed == "true":
+ cmd = "maximum load-balancing ibgp %s ecmp-nexthop-changed" % max_load_ibgp_num
+ cmds.append(cmd)
+
+ max_load_ebgp_num = module.params['max_load_ebgp_num']
+ if max_load_ebgp_num:
+ conf_str += "<maxLoadEbgpNum>%s</maxLoadEbgpNum>" % max_load_ebgp_num
+
+ cmd = "maximum load-balancing ebgp %s" % max_load_ebgp_num
+ cmds.append(cmd)
+
+ ebgp_ecmp_nexthop_changed = module.params['ebgp_ecmp_nexthop_changed']
+ if ebgp_ecmp_nexthop_changed != 'no_use':
+ conf_str += "<ebgpEcmpNexthopChanged>%s</ebgpEcmpNexthopChanged>" % ebgp_ecmp_nexthop_changed
+
+ if ebgp_ecmp_nexthop_changed == "true":
+ cmd = "maximum load-balancing ebgp %s ecmp-nexthop-changed" % max_load_ebgp_num
+ else:
+ cmd = "undo maximum load-balancing ebgp %s ecmp-nexthop-changed" % max_load_ebgp_num
+ cmds.append(cmd)
+
+ maximum_load_balance = module.params['maximum_load_balance']
+ if maximum_load_balance:
+ conf_str += "<maximumLoadBalance>%s</maximumLoadBalance>" % maximum_load_balance
+
+ cmd = "maximum load-balancing %s" % maximum_load_balance
+ cmds.append(cmd)
+
+ ecmp_nexthop_changed = module.params['ecmp_nexthop_changed']
+ if ecmp_nexthop_changed != 'no_use':
+ conf_str += "<ecmpNexthopChanged>%s</ecmpNexthopChanged>" % ecmp_nexthop_changed
+
+ if ecmp_nexthop_changed == "true":
+ cmd = "maximum load-balancing %s ecmp-nexthop-changed" % maximum_load_balance
+ else:
+ cmd = "undo maximum load-balancing %s ecmp-nexthop-changed" % maximum_load_balance
+ cmds.append(cmd)
+
+ default_local_pref = module.params['default_local_pref']
+ if default_local_pref:
+ conf_str += "<defaultLocalPref>%s</defaultLocalPref>" % default_local_pref
+
+ cmd = "default local-preference %s" % default_local_pref
+ cmds.append(cmd)
+
+ default_med = module.params['default_med']
+ if default_med:
+ conf_str += "<defaultMed>%s</defaultMed>" % default_med
+
+ cmd = "default med %s" % default_med
+ cmds.append(cmd)
+
+ default_rt_import_enable = module.params['default_rt_import_enable']
+ if default_rt_import_enable != 'no_use':
+ conf_str += "<defaultRtImportEnable>%s</defaultRtImportEnable>" % default_rt_import_enable
+
+ if default_rt_import_enable == "true":
+ cmd = "default-route imported"
+ else:
+ cmd = "undo default-route imported"
+ cmds.append(cmd)
+
+ router_id = module.params['router_id']
+ if router_id:
+ conf_str += "<routerId>%s</routerId>" % router_id
+
+ cmd = "router-id %s" % router_id
+ cmds.append(cmd)
+
+ vrf_rid_auto_sel = module.params['vrf_rid_auto_sel']
+ if vrf_rid_auto_sel != 'no_use':
+ conf_str += "<vrfRidAutoSel>%s</vrfRidAutoSel>" % vrf_rid_auto_sel
+
+ if vrf_rid_auto_sel == "true":
+ cmd = "router-id %s vpn-instance auto-select" % router_id
+ else:
+ cmd = "undo router-id %s vpn-instance auto-select" % router_id
+ cmds.append(cmd)
+
+ nexthop_third_party = module.params['nexthop_third_party']
+ if nexthop_third_party != 'no_use':
+ conf_str += "<nexthopThirdParty>%s</nexthopThirdParty>" % nexthop_third_party
+
+ if nexthop_third_party == "true":
+ cmd = "nexthop third-party"
+ else:
+ cmd = "undo nexthop third-party"
+ cmds.append(cmd)
+
+ summary_automatic = module.params['summary_automatic']
+ if summary_automatic != 'no_use':
+ conf_str += "<summaryAutomatic>%s</summaryAutomatic>" % summary_automatic
+
+ if summary_automatic == "true":
+ cmd = "summary automatic"
+ else:
+ cmd = "undo summary automatic"
+ cmds.append(cmd)
+
+ auto_frr_enable = module.params['auto_frr_enable']
+ if auto_frr_enable != 'no_use':
+ conf_str += "<autoFrrEnable>%s</autoFrrEnable>" % auto_frr_enable
+
+ if auto_frr_enable == "true":
+ cmd = "auto-frr"
+ else:
+ cmd = "undo auto-frr"
+ cmds.append(cmd)
+
+ load_balancing_as_path_ignore = module.params[
+ 'load_balancing_as_path_ignore']
+ if load_balancing_as_path_ignore != 'no_use':
+ conf_str += "<loadBalancingAsPathIgnore>%s</loadBalancingAsPathIgnore>" % load_balancing_as_path_ignore
+
+ if load_balancing_as_path_ignore == "true":
+ cmd = "load-balancing as-path-ignore"
+ else:
+ cmd = "undo load-balancing as-path-ignore"
+ cmds.append(cmd)
+
+ rib_only_enable = module.params['rib_only_enable']
+ if rib_only_enable != 'no_use':
+ conf_str += "<ribOnlyEnable>%s</ribOnlyEnable>" % rib_only_enable
+
+ if rib_only_enable == "true":
+ cmd = "routing-table rib-only"
+ else:
+ cmd = "undo routing-table rib-only"
+ cmds.append(cmd)
+
+ rib_only_policy_name = module.params['rib_only_policy_name']
+ if rib_only_policy_name:
+ conf_str += "<ribOnlyPolicyName>%s</ribOnlyPolicyName>" % rib_only_policy_name
+
+ cmd = "routing-table rib-only route-policy %s" % rib_only_policy_name
+ cmds.append(cmd)
+
+ active_route_advertise = module.params['active_route_advertise']
+ if active_route_advertise != 'no_use':
+ conf_str += "<activeRouteAdvertise>%s</activeRouteAdvertise>" % active_route_advertise
+
+ if active_route_advertise == "true":
+ cmd = "active-route-advertise"
+ else:
+ cmd = "undo active-route-advertise"
+ cmds.append(cmd)
+
+ as_path_neglect = module.params['as_path_neglect']
+ if as_path_neglect != 'no_use':
+ conf_str += "<asPathNeglect>%s</asPathNeglect>" % as_path_neglect
+
+ if as_path_neglect == "true":
+ cmd = "bestroute as-path-ignore"
+ else:
+ cmd = "undo bestroute as-path-ignore"
+ cmds.append(cmd)
+
+ med_none_as_maximum = module.params['med_none_as_maximum']
+ if med_none_as_maximum != 'no_use':
+ conf_str += "<medNoneAsMaximum>%s</medNoneAsMaximum>" % med_none_as_maximum
+
+ if med_none_as_maximum:
+ cmd = "bestroute med-none-as-maximum"
+ else:
+ cmd = "undo bestroute med-none-as-maximum"
+ cmds.append(cmd)
+
+ router_id_neglect = module.params['router_id_neglect']
+ if router_id_neglect != 'no_use':
+ conf_str += "<routerIdNeglect>%s</routerIdNeglect>" % router_id_neglect
+
+ if router_id_neglect == "true":
+ cmd = "bestroute router-id-ignore"
+ else:
+ cmd = "undo bestroute router-id-ignore"
+ cmds.append(cmd)
+
+ igp_metric_ignore = module.params['igp_metric_ignore']
+ if igp_metric_ignore != 'no_use':
+ conf_str += "<igpMetricIgnore>%s</igpMetricIgnore>" % igp_metric_ignore
+
+ if igp_metric_ignore == "true":
+ cmd = "bestroute igp-metric-ignore"
+ cmds.append(cmd)
+
+ always_compare_med = module.params['always_compare_med']
+ if always_compare_med != 'no_use':
+ conf_str += "<alwaysCompareMed>%s</alwaysCompareMed>" % always_compare_med
+
+ if always_compare_med == "true":
+ cmd = "compare-different-as-med"
+ cmds.append(cmd)
+
+ determin_med = module.params['determin_med']
+ if determin_med != 'no_use':
+ conf_str += "<determinMed>%s</determinMed>" % determin_med
+
+ if determin_med == "true":
+ cmd = "deterministic-med"
+ cmds.append(cmd)
+
+ preference_external = module.params['preference_external']
+ if preference_external:
+ conf_str += "<preferenceExternal>%s</preferenceExternal>" % preference_external
+
+ preference_internal = module.params['preference_internal']
+ if preference_internal:
+ conf_str += "<preferenceInternal>%s</preferenceInternal>" % preference_internal
+
+ preference_local = module.params['preference_local']
+ if preference_local:
+ conf_str += "<preferenceLocal>%s</preferenceLocal>" % preference_local
+
+ cmd = "preference %s %s %s" % (
+ preference_external, preference_internal, preference_local)
+ cmds.append(cmd)
+
+ prefrence_policy_name = module.params['prefrence_policy_name']
+ if prefrence_policy_name:
+ conf_str += "<prefrencePolicyName>%s</prefrencePolicyName>" % prefrence_policy_name
+
+ cmd = "preference route-policy %s" % prefrence_policy_name
+ cmds.append(cmd)
+
+ reflect_between_client = module.params['reflect_between_client']
+ if reflect_between_client != 'no_use':
+ conf_str += "<reflectBetweenClient>%s</reflectBetweenClient>" % reflect_between_client
+
+ if reflect_between_client == "true":
+ cmd = "reflect between-clients"
+ else:
+ cmd = "undo reflect between-clients"
+ cmds.append(cmd)
+
+ reflector_cluster_id = module.params['reflector_cluster_id']
+ if reflector_cluster_id:
+ conf_str += "<reflectorClusterId>%s</reflectorClusterId>" % reflector_cluster_id
+
+ cmd = "reflector cluster-id %s" % reflector_cluster_id
+ cmds.append(cmd)
+
+ reflector_cluster_ipv4 = module.params['reflector_cluster_ipv4']
+ if reflector_cluster_ipv4:
+ conf_str += "<reflectorClusterIpv4>%s</reflectorClusterIpv4>" % reflector_cluster_ipv4
+
+ cmd = "reflector cluster-id %s" % reflector_cluster_ipv4
+ cmds.append(cmd)
+
+ rr_filter_number = module.params['rr_filter_number']
+ if rr_filter_number:
+ conf_str += "<rrFilterNumber>%s</rrFilterNumber>" % rr_filter_number
+
+ policy_vpn_target = module.params['policy_vpn_target']
+ if policy_vpn_target != 'no_use':
+ conf_str += "<policyVpnTarget>%s</policyVpnTarget>" % policy_vpn_target
+
+ next_hop_sel_depend_type = module.params['next_hop_sel_depend_type']
+ if next_hop_sel_depend_type:
+ conf_str += "<nextHopSelDependType>%s</nextHopSelDependType>" % next_hop_sel_depend_type
+
+ nhp_relay_route_policy_name = module.params[
+ 'nhp_relay_route_policy_name']
+ if nhp_relay_route_policy_name:
+ conf_str += "<nhpRelayRoutePolicyName>%s</nhpRelayRoutePolicyName>" % nhp_relay_route_policy_name
+
+ cmd = "nexthop recursive-lookup route-policy %s" % nhp_relay_route_policy_name
+ cmds.append(cmd)
+
+ ebgp_if_sensitive = module.params['ebgp_if_sensitive']
+ if ebgp_if_sensitive != 'no_use':
+ conf_str += "<ebgpIfSensitive>%s</ebgpIfSensitive>" % ebgp_if_sensitive
+
+ if ebgp_if_sensitive == "true":
+ cmd = "ebgp-interface-sensitive"
+ else:
+ cmd = "undo ebgp-interface-sensitive"
+ cmds.append(cmd)
+
+ reflect_chg_path = module.params['reflect_chg_path']
+ if reflect_chg_path != 'no_use':
+ conf_str += "<reflectChgPath>%s</reflectChgPath>" % reflect_chg_path
+
+ if reflect_chg_path == "true":
+ cmd = "reflect change-path-attribute"
+ else:
+ cmd = "undo reflect change-path-attribute"
+ cmds.append(cmd)
+
+ add_path_sel_num = module.params['add_path_sel_num']
+ if add_path_sel_num:
+ conf_str += "<addPathSelNum>%s</addPathSelNum>" % add_path_sel_num
+
+ cmd = "bestroute add-path path-number %s" % add_path_sel_num
+ cmds.append(cmd)
+
+ route_sel_delay = module.params['route_sel_delay']
+ if route_sel_delay:
+ conf_str += "<routeSelDelay>%s</routeSelDelay>" % route_sel_delay
+
+ cmd = "route-select delay %s" % route_sel_delay
+ cmds.append(cmd)
+
+ allow_invalid_as = module.params['allow_invalid_as']
+ if allow_invalid_as != 'no_use':
+ conf_str += "<allowInvalidAs>%s</allowInvalidAs>" % allow_invalid_as
+
+ policy_ext_comm_enable = module.params['policy_ext_comm_enable']
+ if policy_ext_comm_enable != 'no_use':
+ conf_str += "<policyExtCommEnable>%s</policyExtCommEnable>" % policy_ext_comm_enable
+
+ if policy_ext_comm_enable == "true":
+ cmd = "ext-community-change enable"
+ else:
+ cmd = "undo ext-community-change enable"
+ cmds.append(cmd)
+
+ supernet_uni_adv = module.params['supernet_uni_adv']
+ if supernet_uni_adv != 'no_use':
+ conf_str += "<supernetUniAdv>%s</supernetUniAdv>" % supernet_uni_adv
+
+ if supernet_uni_adv == "true":
+ cmd = "supernet unicast advertise enable"
+ else:
+ cmd = "undo supernet unicast advertise enable"
+ cmds.append(cmd)
+
+ supernet_label_adv = module.params['supernet_label_adv']
+ if supernet_label_adv != 'no_use':
+ conf_str += "<supernetLabelAdv>%s</supernetLabelAdv>" % supernet_label_adv
+
+ if supernet_label_adv == "true":
+ cmd = "supernet label-route advertise enable"
+ else:
+ cmd = "undo supernet label-route advertise enable"
+ cmds.append(cmd)
+
+ ingress_lsp_policy_name = module.params['ingress_lsp_policy_name']
+ if ingress_lsp_policy_name:
+ conf_str += "<ingressLspPolicyName>%s</ingressLspPolicyName>" % ingress_lsp_policy_name
+
+ originator_prior = module.params['originator_prior']
+ if originator_prior != 'no_use':
+ conf_str += "<originatorPrior>%s</originatorPrior>" % originator_prior
+
+ lowest_priority = module.params['lowest_priority']
+ if lowest_priority != 'no_use':
+ conf_str += "<lowestPriority>%s</lowestPriority>" % lowest_priority
+
+ if lowest_priority == "true":
+ cmd = "advertise lowest-priority on-startup"
+ else:
+ cmd = "undo advertise lowest-priority on-startup"
+ cmds.append(cmd)
+
+ relay_delay_enable = module.params['relay_delay_enable']
+ if relay_delay_enable != 'no_use':
+ conf_str += "<relayDelayEnable>%s</relayDelayEnable>" % relay_delay_enable
+
+ conf_str += CE_MERGE_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "<ok/>" not in recv_xml:
+ module.fail_json(
+ msg='Error: Merge bgp address family other agrus failed.')
+
+ return cmds
+
+ def delete_bgp_af_other(self, **kwargs):
+ """ delete_bgp_af_other """
+
+ module = kwargs["module"]
+ vrf_name = module.params['vrf_name']
+ af_type = module.params['af_type']
+
+ conf_str = CE_MERGE_BGP_ADDRESS_FAMILY_HEADER % (vrf_name, af_type)
+
+ cmds = []
+
+ router_id = module.params['router_id']
+ if router_id:
+ conf_str += "<routerId></routerId>"
+
+ cmd = "undo router-id %s" % router_id
+ cmds.append(cmd)
+
+ determin_med = module.params['determin_med']
+ if determin_med != 'no_use':
+ conf_str += "<determinMed></determinMed>"
+
+ cmd = "undo deterministic-med"
+ cmds.append(cmd)
+
+ ebgp_if_sensitive = module.params['ebgp_if_sensitive']
+ if ebgp_if_sensitive != 'no_use':
+ conf_str += "<ebgpIfSensitive></ebgpIfSensitive>"
+
+ cmd = "undo ebgp-interface-sensitive"
+ cmds.append(cmd)
+
+ relay_delay_enable = module.params['relay_delay_enable']
+ if relay_delay_enable != 'no_use':
+ conf_str += "<relayDelayEnable></relayDelayEnable>"
+
+ conf_str += CE_MERGE_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "<ok/>" not in recv_xml:
+ module.fail_json(
+ msg='Error: Merge bgp address family other agrus failed.')
+
+ return cmds
+
+ def merge_bgp_import_route(self, **kwargs):
+ """ merge_bgp_import_route """
+
+ module = kwargs["module"]
+
+ vrf_name = module.params['vrf_name']
+
+ af_type = module.params['af_type']
+ import_protocol = module.params['import_protocol']
+ import_process_id = module.params['import_process_id']
+
+ if import_protocol == "direct" or import_protocol == "static":
+ import_process_id = "0"
+
+ conf_str = CE_MERGE_BGP_IMPORT_ROUTE_HEADER % (
+ vrf_name, af_type, import_protocol, import_process_id) + CE_MERGE_BGP_ADDRESS_FAMILY_TAIL
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "<ok/>" not in recv_xml:
+ module.fail_json(msg='Error: Merge bgp import route failed.')
+
+ cmds = []
+ cmd = "import-route %s %s" % (import_protocol, import_process_id)
+ cmds.append(cmd)
+
+ return cmds
+
+ def create_bgp_import_route(self, **kwargs):
+ """ create_bgp_import_route """
+
+ module = kwargs["module"]
+
+ vrf_name = module.params['vrf_name']
+
+ af_type = module.params['af_type']
+ import_protocol = module.params['import_protocol']
+ import_process_id = module.params['import_process_id']
+
+ if import_protocol == "direct" or import_protocol == "static":
+ import_process_id = "0"
+
+ conf_str = CE_CREATE_BGP_IMPORT_ROUTE % (
+ vrf_name, af_type, import_protocol, import_process_id)
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "<ok/>" not in recv_xml:
+ module.fail_json(msg='Error: Create bgp import route failed.')
+
+ cmds = []
+ cmd = "import-route %s %s" % (import_protocol, import_process_id)
+ cmds.append(cmd)
+
+ return cmds
+
+ def delete_bgp_import_route(self, **kwargs):
+ """ delete_bgp_import_route """
+
+ module = kwargs["module"]
+
+ vrf_name = module.params['vrf_name']
+
+ af_type = module.params['af_type']
+ import_protocol = module.params['import_protocol']
+ import_process_id = module.params['import_process_id']
+
+ if import_protocol == "direct" or import_protocol == "static":
+ import_process_id = "0"
+
+ conf_str = CE_DELETE_BGP_IMPORT_ROUTE % (
+ vrf_name, af_type, import_protocol, import_process_id)
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "<ok/>" not in recv_xml:
+ module.fail_json(msg='Error: Delete bgp import route failed.')
+
+ cmds = []
+ cmd = "undo import-route %s %s" % (import_protocol, import_process_id)
+ cmds.append(cmd)
+
+ return cmds
+
+ def merge_bgp_network_route(self, **kwargs):
+ """ merge_bgp_network_route """
+
+ module = kwargs["module"]
+
+ vrf_name = module.params['vrf_name']
+
+ af_type = module.params['af_type']
+ network_address = module.params['network_address']
+ mask_len = module.params['mask_len']
+
+ conf_str = CE_MERGE_BGP_NETWORK_ROUTE_HEADER % (
+ vrf_name, af_type, network_address, mask_len) + CE_MERGE_BGP_NETWORK_ROUTE_TAIL
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "<ok/>" not in recv_xml:
+ module.fail_json(msg='Error: Merge bgp network route failed.')
+
+ cmds = []
+ cmd = "network %s %s" % (network_address, mask_len)
+ cmds.append(cmd)
+
+ return cmds
+
+ def create_bgp_network_route(self, **kwargs):
+ """ create_bgp_network_route """
+
+ module = kwargs["module"]
+
+ vrf_name = module.params['vrf_name']
+
+ af_type = module.params['af_type']
+ network_address = module.params['network_address']
+ mask_len = module.params['mask_len']
+
+ conf_str = CE_CREATE_BGP_NETWORK_ROUTE % (
+ vrf_name, af_type, network_address, mask_len)
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "<ok/>" not in recv_xml:
+ module.fail_json(msg='Error: Create bgp network route failed.')
+
+ cmds = []
+ cmd = "network %s %s" % (network_address, mask_len)
+ cmds.append(cmd)
+
+ return cmds
+
+ def delete_bgp_network_route(self, **kwargs):
+ """ delete_bgp_network_route """
+
+ module = kwargs["module"]
+
+ vrf_name = module.params['vrf_name']
+
+ af_type = module.params['af_type']
+ network_address = module.params['network_address']
+ mask_len = module.params['mask_len']
+
+ conf_str = CE_DELETE_BGP_NETWORK_ROUTE % (
+ vrf_name, af_type, network_address, mask_len)
+
+ recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
+
+ if "<ok/>" not in recv_xml:
+ module.fail_json(msg='Error: Delete bgp network route failed.')
+
+ cmds = []
+ cmd = "undo network %s %s" % (network_address, mask_len)
+ cmds.append(cmd)
+
+ return cmds
+
+
+def main():
+ """ main """
+
+ argument_spec = dict(
+ state=dict(choices=['present', 'absent'], default='present'),
+ vrf_name=dict(type='str', required=True),
+ af_type=dict(choices=['ipv4uni', 'ipv4multi', 'ipv4vpn',
+ 'ipv6uni', 'ipv6vpn', 'evpn'], required=True),
+ max_load_ibgp_num=dict(type='str'),
+ ibgp_ecmp_nexthop_changed=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ max_load_ebgp_num=dict(type='str'),
+ ebgp_ecmp_nexthop_changed=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ maximum_load_balance=dict(type='str'),
+ ecmp_nexthop_changed=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ default_local_pref=dict(type='str'),
+ default_med=dict(type='str'),
+ default_rt_import_enable=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ router_id=dict(type='str'),
+ vrf_rid_auto_sel=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ nexthop_third_party=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ summary_automatic=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ auto_frr_enable=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ load_balancing_as_path_ignore=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ rib_only_enable=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ rib_only_policy_name=dict(type='str'),
+ active_route_advertise=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ as_path_neglect=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ med_none_as_maximum=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ router_id_neglect=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ igp_metric_ignore=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ always_compare_med=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ determin_med=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ preference_external=dict(type='str'),
+ preference_internal=dict(type='str'),
+ preference_local=dict(type='str'),
+ prefrence_policy_name=dict(type='str'),
+ reflect_between_client=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ reflector_cluster_id=dict(type='str'),
+ reflector_cluster_ipv4=dict(type='str'),
+ rr_filter_number=dict(type='str'),
+ policy_vpn_target=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ next_hop_sel_depend_type=dict(
+ choices=['default', 'dependTunnel', 'dependIp']),
+ nhp_relay_route_policy_name=dict(type='str'),
+ ebgp_if_sensitive=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ reflect_chg_path=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ add_path_sel_num=dict(type='str'),
+ route_sel_delay=dict(type='str'),
+ allow_invalid_as=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ policy_ext_comm_enable=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ supernet_uni_adv=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ supernet_label_adv=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ ingress_lsp_policy_name=dict(type='str'),
+ originator_prior=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ lowest_priority=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ relay_delay_enable=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
+ import_protocol=dict(
+ choices=['direct', 'ospf', 'isis', 'static', 'rip', 'ospfv3', 'ripng']),
+ import_process_id=dict(type='str'),
+ network_address=dict(type='str'),
+ mask_len=dict(type='str'))
+
+ 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']
+ af_type = module.params['af_type']
+ max_load_ibgp_num = module.params['max_load_ibgp_num']
+ ibgp_ecmp_nexthop_changed = module.params['ibgp_ecmp_nexthop_changed']
+ max_load_ebgp_num = module.params['max_load_ebgp_num']
+ ebgp_ecmp_nexthop_changed = module.params['ebgp_ecmp_nexthop_changed']
+ maximum_load_balance = module.params['maximum_load_balance']
+ ecmp_nexthop_changed = module.params['ecmp_nexthop_changed']
+ default_local_pref = module.params['default_local_pref']
+ default_med = module.params['default_med']
+ default_rt_import_enable = module.params['default_rt_import_enable']
+ router_id = module.params['router_id']
+ vrf_rid_auto_sel = module.params['vrf_rid_auto_sel']
+ nexthop_third_party = module.params['nexthop_third_party']
+ summary_automatic = module.params['summary_automatic']
+ auto_frr_enable = module.params['auto_frr_enable']
+ load_balancing_as_path_ignore = module.params[
+ 'load_balancing_as_path_ignore']
+ rib_only_enable = module.params['rib_only_enable']
+ rib_only_policy_name = module.params['rib_only_policy_name']
+ active_route_advertise = module.params['active_route_advertise']
+ as_path_neglect = module.params['as_path_neglect']
+ med_none_as_maximum = module.params['med_none_as_maximum']
+ router_id_neglect = module.params['router_id_neglect']
+ igp_metric_ignore = module.params['igp_metric_ignore']
+ always_compare_med = module.params['always_compare_med']
+ determin_med = module.params['determin_med']
+ preference_external = module.params['preference_external']
+ preference_internal = module.params['preference_internal']
+ preference_local = module.params['preference_local']
+ prefrence_policy_name = module.params['prefrence_policy_name']
+ reflect_between_client = module.params['reflect_between_client']
+ reflector_cluster_id = module.params['reflector_cluster_id']
+ reflector_cluster_ipv4 = module.params['reflector_cluster_ipv4']
+ rr_filter_number = module.params['rr_filter_number']
+ policy_vpn_target = module.params['policy_vpn_target']
+ next_hop_sel_depend_type = module.params['next_hop_sel_depend_type']
+ nhp_relay_route_policy_name = module.params['nhp_relay_route_policy_name']
+ ebgp_if_sensitive = module.params['ebgp_if_sensitive']
+ reflect_chg_path = module.params['reflect_chg_path']
+ add_path_sel_num = module.params['add_path_sel_num']
+ route_sel_delay = module.params['route_sel_delay']
+ allow_invalid_as = module.params['allow_invalid_as']
+ policy_ext_comm_enable = module.params['policy_ext_comm_enable']
+ supernet_uni_adv = module.params['supernet_uni_adv']
+ supernet_label_adv = module.params['supernet_label_adv']
+ ingress_lsp_policy_name = module.params['ingress_lsp_policy_name']
+ originator_prior = module.params['originator_prior']
+ lowest_priority = module.params['lowest_priority']
+ relay_delay_enable = module.params['relay_delay_enable']
+ import_protocol = module.params['import_protocol']
+ import_process_id = module.params['import_process_id']
+ network_address = module.params['network_address']
+ mask_len = module.params['mask_len']
+
+ ce_bgp_af_obj = BgpAf()
+
+ if not ce_bgp_af_obj:
+ module.fail_json(msg='Error: Init module failed.')
+
+ # get proposed
+ proposed["state"] = state
+ if vrf_name:
+ proposed["vrf_name"] = vrf_name
+ if af_type:
+ proposed["af_type"] = af_type
+ if max_load_ibgp_num:
+ proposed["max_load_ibgp_num"] = max_load_ibgp_num
+ if ibgp_ecmp_nexthop_changed != 'no_use':
+ proposed["ibgp_ecmp_nexthop_changed"] = ibgp_ecmp_nexthop_changed
+ if max_load_ebgp_num:
+ proposed["max_load_ebgp_num"] = max_load_ebgp_num
+ if ebgp_ecmp_nexthop_changed != 'no_use':
+ proposed["ebgp_ecmp_nexthop_changed"] = ebgp_ecmp_nexthop_changed
+ if maximum_load_balance:
+ proposed["maximum_load_balance"] = maximum_load_balance
+ if ecmp_nexthop_changed != 'no_use':
+ proposed["ecmp_nexthop_changed"] = ecmp_nexthop_changed
+ if default_local_pref:
+ proposed["default_local_pref"] = default_local_pref
+ if default_med:
+ proposed["default_med"] = default_med
+ if default_rt_import_enable != 'no_use':
+ proposed["default_rt_import_enable"] = default_rt_import_enable
+ if router_id:
+ proposed["router_id"] = router_id
+ if vrf_rid_auto_sel != 'no_use':
+ proposed["vrf_rid_auto_sel"] = vrf_rid_auto_sel
+ if nexthop_third_party != 'no_use':
+ proposed["nexthop_third_party"] = nexthop_third_party
+ if summary_automatic != 'no_use':
+ proposed["summary_automatic"] = summary_automatic
+ if auto_frr_enable != 'no_use':
+ proposed["auto_frr_enable"] = auto_frr_enable
+ if load_balancing_as_path_ignore != 'no_use':
+ proposed["load_balancing_as_path_ignore"] = load_balancing_as_path_ignore
+ if rib_only_enable != 'no_use':
+ proposed["rib_only_enable"] = rib_only_enable
+ if rib_only_policy_name:
+ proposed["rib_only_policy_name"] = rib_only_policy_name
+ if active_route_advertise != 'no_use':
+ proposed["active_route_advertise"] = active_route_advertise
+ if as_path_neglect != 'no_use':
+ proposed["as_path_neglect"] = as_path_neglect
+ if med_none_as_maximum != 'no_use':
+ proposed["med_none_as_maximum"] = med_none_as_maximum
+ if router_id_neglect != 'no_use':
+ proposed["router_id_neglect"] = router_id_neglect
+ if igp_metric_ignore != 'no_use':
+ proposed["igp_metric_ignore"] = igp_metric_ignore
+ if always_compare_med != 'no_use':
+ proposed["always_compare_med"] = always_compare_med
+ if determin_med != 'no_use':
+ proposed["determin_med"] = determin_med
+ if preference_external:
+ proposed["preference_external"] = preference_external
+ if preference_internal:
+ proposed["preference_internal"] = preference_internal
+ if preference_local:
+ proposed["preference_local"] = preference_local
+ if prefrence_policy_name:
+ proposed["prefrence_policy_name"] = prefrence_policy_name
+ if reflect_between_client != 'no_use':
+ proposed["reflect_between_client"] = reflect_between_client
+ if reflector_cluster_id:
+ proposed["reflector_cluster_id"] = reflector_cluster_id
+ if reflector_cluster_ipv4:
+ proposed["reflector_cluster_ipv4"] = reflector_cluster_ipv4
+ if rr_filter_number:
+ proposed["rr_filter_number"] = rr_filter_number
+ if policy_vpn_target != 'no_use':
+ proposed["policy_vpn_target"] = policy_vpn_target
+ if next_hop_sel_depend_type:
+ proposed["next_hop_sel_depend_type"] = next_hop_sel_depend_type
+ if nhp_relay_route_policy_name:
+ proposed["nhp_relay_route_policy_name"] = nhp_relay_route_policy_name
+ if ebgp_if_sensitive != 'no_use':
+ proposed["ebgp_if_sensitive"] = ebgp_if_sensitive
+ if reflect_chg_path != 'no_use':
+ proposed["reflect_chg_path"] = reflect_chg_path
+ if add_path_sel_num:
+ proposed["add_path_sel_num"] = add_path_sel_num
+ if route_sel_delay:
+ proposed["route_sel_delay"] = route_sel_delay
+ if allow_invalid_as != 'no_use':
+ proposed["allow_invalid_as"] = allow_invalid_as
+ if policy_ext_comm_enable != 'no_use':
+ proposed["policy_ext_comm_enable"] = policy_ext_comm_enable
+ if supernet_uni_adv != 'no_use':
+ proposed["supernet_uni_adv"] = supernet_uni_adv
+ if supernet_label_adv != 'no_use':
+ proposed["supernet_label_adv"] = supernet_label_adv
+ if ingress_lsp_policy_name:
+ proposed["ingress_lsp_policy_name"] = ingress_lsp_policy_name
+ if originator_prior != 'no_use':
+ proposed["originator_prior"] = originator_prior
+ if lowest_priority != 'no_use':
+ proposed["lowest_priority"] = lowest_priority
+ if relay_delay_enable != 'no_use':
+ proposed["relay_delay_enable"] = relay_delay_enable
+ if import_protocol:
+ proposed["import_protocol"] = import_protocol
+ if import_process_id:
+ proposed["import_process_id"] = import_process_id
+ if network_address:
+ proposed["network_address"] = network_address
+ if mask_len:
+ proposed["mask_len"] = mask_len
+
+ bgp_af_rst = ce_bgp_af_obj.check_bgp_af_args(module=module)
+ bgp_af_other_rst = ce_bgp_af_obj.check_bgp_af_other_args(module=module)
+ bgp_af_other_can_del_rst = ce_bgp_af_obj.check_bgp_af_other_can_del(
+ module=module)
+ bgp_import_network_route_rst = ce_bgp_af_obj.check_bgp_import_network_route(
+ module=module)
+
+ # state exist bgp address family config
+ exist_tmp = dict()
+ for item in bgp_af_rst:
+ if item != "need_cfg":
+ exist_tmp[item] = bgp_af_rst[item]
+
+ if exist_tmp:
+ existing["bgp af"] = exist_tmp
+ # state exist bgp address family other config
+ exist_tmp = dict()
+ for item in bgp_af_other_rst:
+ if item != "need_cfg":
+ exist_tmp[item] = bgp_af_other_rst[item]
+ if exist_tmp:
+ existing["bgp af other"] = exist_tmp
+ # state exist bgp import route config
+ exist_tmp = dict()
+ for item in bgp_import_network_route_rst:
+ if item != "need_cfg":
+ exist_tmp[item] = bgp_import_network_route_rst[item]
+
+ if exist_tmp:
+ existing["bgp import & network route"] = exist_tmp
+
+ if state == "present":
+ if bgp_af_rst["need_cfg"] and bgp_import_network_route_rst["import_need_cfg"] and \
+ bgp_import_network_route_rst["network_need_cfg"]:
+ changed = True
+ if "af_type" in bgp_af_rst.keys():
+ conf_str = CE_MERGE_BGP_ADDRESS_FAMILY_HEADER % (
+ vrf_name, af_type)
+ else:
+ conf_str = CE_CREATE_BGP_ADDRESS_FAMILY_HEADER % (
+ vrf_name, af_type)
+
+ if "bgp_import_route" in bgp_import_network_route_rst.keys():
+ conf_str += CE_BGP_MERGE_IMPORT_UNIT % (
+ import_protocol, import_process_id)
+ else:
+ conf_str += CE_BGP_CREATE_IMPORT_UNIT % (
+ import_protocol, import_process_id)
+
+ if "bgp_network_route" in bgp_import_network_route_rst.keys():
+ conf_str += CE_BGP_MERGE_NETWORK_UNIT % (
+ network_address, mask_len)
+ else:
+ conf_str += CE_BGP_CREATE_NETWORK_UNIT % (
+ network_address, mask_len)
+
+ conf_str += CE_MERGE_BGP_ADDRESS_FAMILY_TAIL
+ recv_xml = ce_bgp_af_obj.netconf_set_config(
+ module=module, conf_str=conf_str)
+
+ if "<ok/>" not in recv_xml:
+ module.fail_json(
+ msg='Error: Present bgp af_type import and network route failed.')
+
+ cmd = "import-route %s %s" % (import_protocol, import_process_id)
+ updates.append(cmd)
+ cmd = "network %s %s" % (network_address, mask_len)
+ updates.append(cmd)
+
+ elif bgp_import_network_route_rst["import_need_cfg"] and bgp_import_network_route_rst["network_need_cfg"]:
+ changed = True
+ conf_str = CE_BGP_IMPORT_NETWORK_ROUTE_HEADER % (vrf_name, af_type)
+
+ if "bgp_import_route" in bgp_import_network_route_rst.keys():
+ conf_str += CE_BGP_MERGE_IMPORT_UNIT % (
+ import_protocol, import_process_id)
+ else:
+ conf_str += CE_BGP_CREATE_IMPORT_UNIT % (
+ import_protocol, import_process_id)
+
+ if "bgp_network_route" in bgp_import_network_route_rst.keys():
+ conf_str += CE_BGP_MERGE_NETWORK_UNIT % (
+ network_address, mask_len)
+ else:
+ conf_str += CE_BGP_CREATE_NETWORK_UNIT % (
+ network_address, mask_len)
+
+ conf_str += CE_BGP_IMPORT_NETWORK_ROUTE_TAIL
+ recv_xml = ce_bgp_af_obj.netconf_set_config(
+ module=module, conf_str=conf_str)
+
+ if "<ok/>" not in recv_xml:
+ module.fail_json(
+ msg='Error: Present bgp import and network route failed.')
+
+ cmd = "import-route %s %s" % (import_protocol, import_process_id)
+ updates.append(cmd)
+ cmd = "network %s %s" % (network_address, mask_len)
+ updates.append(cmd)
+
+ else:
+ if bgp_af_rst["need_cfg"]:
+ if "af_type" in bgp_af_rst.keys():
+ cmd = ce_bgp_af_obj.merge_bgp_af(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+ else:
+ cmd = ce_bgp_af_obj.create_bgp_af(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+
+ if bgp_af_other_rst["need_cfg"]:
+ cmd = ce_bgp_af_obj.merge_bgp_af_other(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+
+ if bgp_import_network_route_rst["import_need_cfg"]:
+ if "bgp_import_route" in bgp_import_network_route_rst.keys():
+ cmd = ce_bgp_af_obj.merge_bgp_import_route(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+ else:
+ cmd = ce_bgp_af_obj.create_bgp_import_route(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+
+ if bgp_import_network_route_rst["network_need_cfg"]:
+ if "bgp_network_route" in bgp_import_network_route_rst.keys():
+ cmd = ce_bgp_af_obj.merge_bgp_network_route(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+ else:
+ cmd = ce_bgp_af_obj.create_bgp_network_route(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+
+ else:
+ if bgp_import_network_route_rst["import_need_cfg"] and bgp_import_network_route_rst["network_need_cfg"]:
+ changed = True
+ conf_str = CE_BGP_IMPORT_NETWORK_ROUTE_HEADER % (vrf_name, af_type)
+ conf_str += CE_BGP_DELETE_IMPORT_UNIT % (
+ import_protocol, import_process_id)
+ conf_str += CE_BGP_DELETE_NETWORK_UNIT % (
+ network_address, mask_len)
+
+ conf_str += CE_BGP_IMPORT_NETWORK_ROUTE_TAIL
+ recv_xml = ce_bgp_af_obj.netconf_set_config(
+ module=module, conf_str=conf_str)
+
+ if "<ok/>" not in recv_xml:
+ module.fail_json(
+ msg='Error: Absent bgp import and network route failed.')
+
+ cmd = "undo import-route %s %s" % (import_protocol,
+ import_process_id)
+ updates.append(cmd)
+ cmd = "undo network %s %s" % (network_address, mask_len)
+ updates.append(cmd)
+
+ else:
+ if bgp_import_network_route_rst["import_need_cfg"]:
+ cmd = ce_bgp_af_obj.delete_bgp_import_route(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+
+ if bgp_import_network_route_rst["network_need_cfg"]:
+ cmd = ce_bgp_af_obj.delete_bgp_network_route(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+
+ if bgp_af_other_can_del_rst["need_cfg"]:
+ cmd = ce_bgp_af_obj.delete_bgp_af_other(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+
+ if bgp_af_rst["need_cfg"] and not bgp_af_other_can_del_rst["need_cfg"]:
+ cmd = ce_bgp_af_obj.delete_bgp_af(module=module)
+ changed = True
+ for item in cmd:
+ updates.append(item)
+
+ if bgp_af_other_rst["need_cfg"]:
+ pass
+
+ # state end bgp address family config
+ bgp_af_rst = ce_bgp_af_obj.check_bgp_af_args(module=module)
+ end_tmp = dict()
+ for item in bgp_af_rst:
+ if item != "need_cfg":
+ end_tmp[item] = bgp_af_rst[item]
+ if end_tmp:
+ end_state["bgp af"] = end_tmp
+ # state end bgp address family other config
+ bgp_af_other_rst = ce_bgp_af_obj.check_bgp_af_other_args(module=module)
+ end_tmp = dict()
+ for item in bgp_af_other_rst:
+ if item != "need_cfg":
+ end_tmp[item] = bgp_af_other_rst[item]
+ if end_tmp:
+ end_state["bgp af other"] = end_tmp
+ # state end bgp import route config
+ bgp_import_network_route_rst = ce_bgp_af_obj.check_bgp_import_network_route(
+ module=module)
+ end_tmp = dict()
+ for item in bgp_import_network_route_rst:
+ if item != "need_cfg":
+ end_tmp[item] = bgp_import_network_route_rst[item]
+ if end_tmp:
+ end_state["bgp import & network route"] = 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()