1#!/usr/local/bin/python3.8
2#
3# This file is part of Ansible
4#
5# Ansible is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# Ansible is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
17#
18
19from __future__ import (absolute_import, division, print_function)
20__metaclass__ = type
21
22DOCUMENTATION = '''
23---
24module: ce_bgp_neighbor
25short_description: Manages BGP peer configuration on HUAWEI CloudEngine switches.
26description:
27    - Manages BGP peer configurations on HUAWEI CloudEngine switches.
28author:
29    - wangdezhuang (@QijunPan)
30notes:
31  - This module requires the netconf system service be enabled on the remote device being managed.
32  - Recommended connection is C(netconf).
33  - This module also works with C(local) connections for legacy playbooks.
34options:
35    state:
36        description:
37            - Specify desired state of the resource.
38        default: present
39        choices: ['present','absent']
40    vrf_name:
41        description:
42            - Name of a BGP instance. The name is a case-sensitive string of characters.
43              The BGP instance can be used only after the corresponding VPN instance is created.
44        required: true
45    peer_addr:
46        description:
47            - Connection address of a peer, which can be an IPv4 or IPv6 address.
48        required: true
49    remote_as:
50        description:
51            - AS number of a peer.
52              The value is a string of 1 to 11 characters.
53        required: true
54    description:
55        description:
56            - Description of a peer, which can be letters or digits.
57              The value is a string of 1 to 80 characters.
58    fake_as:
59        description:
60            - Fake AS number that is specified for a local peer.
61              The value is a string of 1 to 11 characters.
62    dual_as:
63        description:
64            - If the value is true, the EBGP peer can use either a fake AS number or the actual AS number.
65              If the value is false, the EBGP peer can only use a fake AS number.
66        choices: ['no_use','true','false']
67        default: no_use
68    conventional:
69        description:
70            - If the value is true, the router has all extended capabilities.
71              If the value is false, the router does not have all extended capabilities.
72        choices: ['no_use','true','false']
73        default: no_use
74    route_refresh:
75        description:
76            - If the value is true, BGP is enabled to advertise REFRESH packets.
77              If the value is false, the route refresh function is enabled.
78        choices: ['no_use','true','false']
79        default: no_use
80    is_ignore:
81        description:
82            - If the value is true, the session with a specified peer is torn down and all related
83              routing entries are cleared.
84              If the value is false, the session with a specified peer is retained.
85        choices: ['no_use','true','false']
86        default: no_use
87    local_if_name:
88        description:
89            - Name of a source interface that sends BGP packets.
90              The value is a string of 1 to 63 characters.
91    ebgp_max_hop:
92        description:
93            - Maximum number of hops in an indirect EBGP connection.
94              The value is an ranging from 1 to 255.
95    valid_ttl_hops:
96        description:
97            - Enable GTSM on a peer or peer group.
98              The valid-TTL-Value parameter is used to specify the number of TTL hops to be detected.
99              The value is an integer ranging from 1 to 255.
100    connect_mode:
101        description:
102            - The value can be Connect-only, Listen-only, or Both.
103    is_log_change:
104        description:
105            - If the value is true, BGP is enabled to record peer session status and event information.
106              If the value is false, BGP is disabled from recording peer session status and event information.
107        choices: ['no_use','true','false']
108        default: no_use
109    pswd_type:
110        description:
111            - Enable BGP peers to establish a TCP connection and perform the Message Digest 5 (MD5)
112              authentication for BGP messages.
113        choices: ['null','cipher','simple']
114    pswd_cipher_text:
115        description:
116            - The character string in a password identifies the contents of the password, spaces not supported.
117              The value is a string of 1 to 255 characters.
118    keep_alive_time:
119        description:
120            - Specify the Keepalive time of a peer or peer group.
121              The value is an integer ranging from 0 to 21845. The default value is 60.
122    hold_time:
123        description:
124            - Specify the Hold time of a peer or peer group.
125              The value is 0 or an integer ranging from 3 to 65535.
126    min_hold_time:
127        description:
128            - Specify the Min hold time of a peer or peer group.
129    key_chain_name:
130        description:
131            - Specify the Keychain authentication name used when BGP peers establish a TCP connection.
132              The value is a string of 1 to 47 case-insensitive characters.
133    conn_retry_time:
134        description:
135            - ConnectRetry interval.
136              The value is an integer ranging from 1 to 65535.
137    tcp_MSS:
138        description:
139            - Maximum TCP MSS value used for TCP connection establishment for a peer.
140              The value is an integer ranging from 176 to 4096.
141    mpls_local_ifnet_disable:
142        description:
143            - If the value is true, peer create MPLS Local IFNET disable.
144              If the value is false, peer create MPLS Local IFNET enable.
145        choices: ['no_use','true','false']
146        default: no_use
147    prepend_global_as:
148        description:
149            - Add the global AS number to the Update packets to be advertised.
150        choices: ['no_use','true','false']
151        default: no_use
152    prepend_fake_as:
153        description:
154            - Add the Fake AS number to received Update packets.
155        choices: ['no_use','true','false']
156        default: no_use
157    is_bfd_block:
158        description:
159            - If the value is true, peers are enabled to inherit the BFD function from the peer group.
160              If the value is false, peers are disabled to inherit the BFD function from the peer group.
161        choices: ['no_use','true','false']
162        default: no_use
163    multiplier:
164        description:
165            - Specify the detection multiplier. The default value is 3.
166              The value is an integer ranging from 3 to 50.
167    is_bfd_enable:
168        description:
169            - If the value is true, BFD is enabled.
170              If the value is false, BFD is disabled.
171        choices: ['no_use','true','false']
172        default: no_use
173    rx_interval:
174        description:
175            - Specify the minimum interval at which BFD packets are received.
176              The value is an integer ranging from 50 to 1000, in milliseconds.
177    tx_interval:
178        description:
179            - Specify the minimum interval at which BFD packets are sent.
180              The value is an integer ranging from 50 to 1000, in milliseconds.
181    is_single_hop:
182        description:
183            - If the value is true, the system is enabled to preferentially use the single-hop mode for
184              BFD session setup between IBGP peers.
185              If the value is false, the system is disabled from preferentially using the single-hop
186              mode for BFD session setup between IBGP peers.
187        choices: ['no_use','true','false']
188        default: no_use
189'''
190
191EXAMPLES = '''
192
193- name: CloudEngine BGP neighbor test
194  hosts: cloudengine
195  connection: local
196  gather_facts: no
197  vars:
198    cli:
199      host: "{{ inventory_hostname }}"
200      port: "{{ ansible_ssh_port }}"
201      username: "{{ username }}"
202      password: "{{ password }}"
203      transport: cli
204
205  tasks:
206
207  - name: "Config bgp peer"
208    community.network.ce_bgp_neighbor:
209      state: present
210      vrf_name: js
211      peer_addr: 192.168.10.10
212      remote_as: 500
213      provider: "{{ cli }}"
214
215  - name: "Config bgp route id"
216    community.network.ce_bgp_neighbor:
217      state: absent
218      vrf_name: js
219      peer_addr: 192.168.10.10
220      provider: "{{ cli }}"
221'''
222
223RETURN = '''
224changed:
225    description: check to see if a change was made on the device
226    returned: always
227    type: bool
228    sample: true
229proposed:
230    description: k/v pairs of parameters passed into module
231    returned: always
232    type: dict
233    sample: {"peer_addr": "192.168.10.10", "remote_as": "500", "state": "present", "vrf_name": "js"}
234existing:
235    description: k/v pairs of existing aaa server
236    returned: always
237    type: dict
238    sample: {"bgp peer": []}
239end_state:
240    description: k/v pairs of aaa params after module execution
241    returned: always
242    type: dict
243    sample: {"bgp peer": [["192.168.10.10", "500"]]}
244updates:
245    description: command sent to the device
246    returned: always
247    type: list
248    sample: ["peer 192.168.10.10 as-number 500"]
249'''
250
251import re
252from ansible.module_utils.basic import AnsibleModule
253from ansible_collections.community.network.plugins.module_utils.network.cloudengine.ce import get_nc_config, set_nc_config, ce_argument_spec, check_ip_addr
254
255
256# get bgp peer
257CE_GET_BGP_PEER_HEADER = """
258    <filter type="subtree">
259      <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
260        <bgpcomm>
261          <bgpVrfs>
262            <bgpVrf>
263              <vrfName>%s</vrfName>
264              <bgpPeers>
265                <bgpPeer>
266                  <peerAddr>%s</peerAddr>
267"""
268CE_GET_BGP_PEER_TAIL = """
269                </bgpPeer>
270              </bgpPeers>
271            </bgpVrf>
272          </bgpVrfs>
273        </bgpcomm>
274      </bgp>
275    </filter>
276"""
277
278# merge bgp peer
279CE_MERGE_BGP_PEER_HEADER = """
280    <config>
281      <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
282        <bgpcomm>
283          <bgpVrfs>
284            <bgpVrf>
285              <vrfName>%s</vrfName>
286              <bgpPeers>
287                <bgpPeer operation="merge">
288                  <peerAddr>%s</peerAddr>
289"""
290CE_MERGE_BGP_PEER_TAIL = """
291                </bgpPeer>
292              </bgpPeers>
293            </bgpVrf>
294          </bgpVrfs>
295        </bgpcomm>
296      </bgp>
297    </config>
298"""
299
300# create bgp peer
301CE_CREATE_BGP_PEER_HEADER = """
302    <config>
303      <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
304        <bgpcomm>
305          <bgpVrfs>
306            <bgpVrf>
307              <vrfName>%s</vrfName>
308              <bgpPeers>
309                <bgpPeer operation="create">
310                  <peerAddr>%s</peerAddr>
311"""
312CE_CREATE_BGP_PEER_TAIL = """
313                </bgpPeer>
314              </bgpPeers>
315            </bgpVrf>
316          </bgpVrfs>
317        </bgpcomm>
318      </bgp>
319    </config>
320"""
321
322# delete bgp peer
323CE_DELETE_BGP_PEER_HEADER = """
324    <config>
325      <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
326        <bgpcomm>
327          <bgpVrfs>
328            <bgpVrf>
329              <vrfName>%s</vrfName>
330              <bgpPeers>
331                <bgpPeer operation="delete">
332                  <peerAddr>%s</peerAddr>
333"""
334CE_DELETE_BGP_PEER_TAIL = """
335                </bgpPeer>
336              </bgpPeers>
337            </bgpVrf>
338          </bgpVrfs>
339        </bgpcomm>
340      </bgp>
341    </config>
342"""
343
344# get peer bfd
345CE_GET_PEER_BFD_HEADER = """
346    <filter type="subtree">
347      <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
348        <bgpcomm>
349          <bgpVrfs>
350            <bgpVrf>
351              <vrfName>%s</vrfName>
352              <bgpPeers>
353                <bgpPeer>
354                  <peerAddr>%s</peerAddr>
355                  <peerBfd>
356"""
357CE_GET_PEER_BFD_TAIL = """
358                  </peerBfd>
359                </bgpPeer>
360              </bgpPeers>
361            </bgpVrf>
362          </bgpVrfs>
363        </bgpcomm>
364      </bgp>
365    </filter>
366"""
367
368# merge peer bfd
369CE_MERGE_PEER_BFD_HEADER = """
370    <config>
371      <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
372        <bgpcomm>
373          <bgpVrfs>
374            <bgpVrf>
375              <vrfName>%s</vrfName>
376              <bgpPeers>
377                <bgpPeer>
378                  <peerAddr>%s</peerAddr>
379                  <peerBfd operation="merge">
380"""
381CE_MERGE_PEER_BFD_TAIL = """
382                  </peerBfd>
383                </bgpPeer>
384              </bgpPeers>
385            </bgpVrf>
386          </bgpVrfs>
387        </bgpcomm>
388      </bgp>
389    </config>
390"""
391
392# delete peer bfd
393CE_DELETE_PEER_BFD_HEADER = """
394    <config>
395      <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
396        <bgpcomm>
397          <bgpVrfs>
398            <bgpVrf>
399              <vrfName>%s</vrfName>
400              <bgpPeers>
401                <bgpPeer>
402                  <peerAddr>%s</peerAddr>
403                  <peerBfd operation="delete">
404"""
405CE_DELETE_PEER_BFD_TAIL = """
406                  </peerBfd>
407                </bgpPeer>
408              </bgpPeers>
409            </bgpVrf>
410          </bgpVrfs>
411        </bgpcomm>
412      </bgp>
413    </config>
414"""
415
416
417class BgpNeighbor(object):
418    """ Manages BGP peer configuration """
419
420    def netconf_get_config(self, **kwargs):
421        """ netconf_get_config """
422
423        module = kwargs["module"]
424        conf_str = kwargs["conf_str"]
425
426        xml_str = get_nc_config(module, conf_str)
427
428        return xml_str
429
430    def netconf_set_config(self, **kwargs):
431        """ netconf_set_config """
432
433        module = kwargs["module"]
434        conf_str = kwargs["conf_str"]
435
436        xml_str = set_nc_config(module, conf_str)
437
438        return xml_str
439
440    def check_bgp_peer_args(self, **kwargs):
441        """ check_bgp_peer_args """
442
443        module = kwargs["module"]
444        result = dict()
445        need_cfg = False
446
447        vrf_name = module.params['vrf_name']
448        if vrf_name:
449            if len(vrf_name) > 31 or len(vrf_name) == 0:
450                module.fail_json(
451                    msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)
452
453        peer_addr = module.params['peer_addr']
454        if peer_addr:
455            if not check_ip_addr(ipaddr=peer_addr):
456                module.fail_json(
457                    msg='Error: The peer_addr %s is invalid.' % peer_addr)
458
459            need_cfg = True
460
461        remote_as = module.params['remote_as']
462        if remote_as:
463            if len(remote_as) > 11 or len(remote_as) < 1:
464                module.fail_json(
465                    msg='Error: The len of remote_as %s is out of [1 - 11].' % remote_as)
466
467            need_cfg = True
468
469        result["need_cfg"] = need_cfg
470        return result
471
472    def check_bgp_peer_other_args(self, **kwargs):
473        """ check_bgp_peer_other_args """
474
475        module = kwargs["module"]
476        result = dict()
477        need_cfg = False
478
479        peerip = module.params['peer_addr']
480        vrf_name = module.params['vrf_name']
481        if vrf_name:
482            if len(vrf_name) > 31 or len(vrf_name) == 0:
483                module.fail_json(
484                    msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)
485
486        description = module.params['description']
487        if description:
488            if len(description) > 80 or len(description) < 1:
489                module.fail_json(
490                    msg='Error: The len of description %s is out of [1 - 80].' % description)
491
492            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
493                "<description></description>" + CE_GET_BGP_PEER_TAIL
494            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
495
496            if "<data/>" in recv_xml:
497                need_cfg = True
498            else:
499                re_find = re.findall(
500                    r'.*<description>(.*)</description>.*', recv_xml)
501
502                if re_find:
503                    result["description"] = re_find
504                    if re_find[0] != description:
505                        need_cfg = True
506                else:
507                    need_cfg = True
508
509        fake_as = module.params['fake_as']
510        if fake_as:
511            if len(fake_as) > 11 or len(fake_as) < 1:
512                module.fail_json(
513                    msg='Error: The len of fake_as %s is out of [1 - 11].' % fake_as)
514
515            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
516                "<fakeAs></fakeAs>" + CE_GET_BGP_PEER_TAIL
517            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
518
519            if "<data/>" in recv_xml:
520                need_cfg = True
521            else:
522                re_find = re.findall(
523                    r'.*<fakeAs>(.*)</fakeAs>.*', recv_xml)
524
525                if re_find:
526                    result["fake_as"] = re_find
527                    if re_find[0] != fake_as:
528                        need_cfg = True
529                else:
530                    need_cfg = True
531
532        dual_as = module.params['dual_as']
533        if dual_as != 'no_use':
534            if not fake_as:
535                module.fail_json(msg='fake_as must exist.')
536            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
537                "<dualAs></dualAs>" + CE_GET_BGP_PEER_TAIL
538            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
539
540            if "<data/>" in recv_xml:
541                need_cfg = True
542            else:
543                re_find = re.findall(
544                    r'.*<dualAs>(.*)</dualAs>.*', recv_xml)
545
546                if re_find:
547                    result["dual_as"] = re_find
548                    if re_find[0] != dual_as:
549                        need_cfg = True
550                else:
551                    need_cfg = True
552
553        conventional = module.params['conventional']
554        if conventional != 'no_use':
555
556            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
557                "<conventional></conventional>" + CE_GET_BGP_PEER_TAIL
558            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
559            if "<data/>" in recv_xml:
560                need_cfg = True
561            else:
562                re_find = re.findall(
563                    r'.*<conventional>(.*)</conventional>.*', recv_xml)
564
565                if re_find:
566                    result["conventional"] = re_find
567                    if re_find[0] != conventional:
568                        need_cfg = True
569                else:
570                    need_cfg = True
571
572        route_refresh = module.params['route_refresh']
573        if route_refresh != 'no_use':
574
575            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
576                "<routeRefresh></routeRefresh>" + CE_GET_BGP_PEER_TAIL
577            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
578
579            if "<data/>" in recv_xml:
580                need_cfg = True
581            else:
582                re_find = re.findall(
583                    r'.*<routeRefresh>(.*)</routeRefresh>.*', recv_xml)
584
585                if re_find:
586                    result["route_refresh"] = re_find
587                    if re_find[0] != route_refresh:
588                        need_cfg = True
589                else:
590                    need_cfg = True
591
592        four_byte_as = module.params['four_byte_as']
593        if four_byte_as != 'no_use':
594
595            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
596                "<fourByteAs></fourByteAs>" + CE_GET_BGP_PEER_TAIL
597            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
598
599            if "<data/>" in recv_xml:
600                need_cfg = True
601            else:
602                re_find = re.findall(
603                    r'.*<fourByteAs>(.*)</fourByteAs>.*', recv_xml)
604
605                if re_find:
606                    result["four_byte_as"] = re_find
607                    if re_find[0] != four_byte_as:
608                        need_cfg = True
609                else:
610                    need_cfg = True
611
612        is_ignore = module.params['is_ignore']
613        if is_ignore != 'no_use':
614
615            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
616                "<isIgnore></isIgnore>" + CE_GET_BGP_PEER_TAIL
617            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
618
619            if "<data/>" in recv_xml:
620                need_cfg = True
621            else:
622                re_find = re.findall(
623                    r'.*<isIgnore>(.*)</isIgnore>.*', recv_xml)
624
625                if re_find:
626                    result["is_ignore"] = re_find
627                    if re_find[0] != is_ignore:
628                        need_cfg = True
629                else:
630                    need_cfg = True
631
632        local_if_name = module.params['local_if_name']
633        if local_if_name:
634            if len(local_if_name) > 63 or len(local_if_name) < 1:
635                module.fail_json(
636                    msg='Error: The len of local_if_name %s is out of [1 - 63].' % local_if_name)
637
638            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
639                "<localIfName></localIfName>" + CE_GET_BGP_PEER_TAIL
640            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
641
642            if "<data/>" in recv_xml:
643                need_cfg = True
644            else:
645                re_find = re.findall(
646                    r'.*<localIfName>(.*)</localIfName>.*', recv_xml)
647
648                if re_find:
649                    result["local_if_name"] = re_find
650                    if re_find[0].lower() != local_if_name.lower():
651                        need_cfg = True
652                else:
653                    need_cfg = True
654
655        ebgp_max_hop = module.params['ebgp_max_hop']
656        if ebgp_max_hop:
657            if int(ebgp_max_hop) > 255 or int(ebgp_max_hop) < 1:
658                module.fail_json(
659                    msg='Error: The value of ebgp_max_hop %s is out of [1 - 255].' % ebgp_max_hop)
660
661            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
662                "<ebgpMaxHop></ebgpMaxHop>" + CE_GET_BGP_PEER_TAIL
663            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
664
665            if "<data/>" in recv_xml:
666                need_cfg = True
667            else:
668                re_find = re.findall(
669                    r'.*<ebgpMaxHop>(.*)</ebgpMaxHop>.*', recv_xml)
670
671                if re_find:
672                    result["ebgp_max_hop"] = re_find
673                    if re_find[0] != ebgp_max_hop:
674                        need_cfg = True
675                else:
676                    need_cfg = True
677
678        valid_ttl_hops = module.params['valid_ttl_hops']
679        if valid_ttl_hops:
680            if int(valid_ttl_hops) > 255 or int(valid_ttl_hops) < 1:
681                module.fail_json(
682                    msg='Error: The value of valid_ttl_hops %s is out of [1 - 255].' % valid_ttl_hops)
683
684            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
685                "<validTtlHops></validTtlHops>" + CE_GET_BGP_PEER_TAIL
686            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
687
688            if "<data/>" in recv_xml:
689                need_cfg = True
690            else:
691                re_find = re.findall(
692                    r'.*<validTtlHops>(.*)</validTtlHops>.*', recv_xml)
693
694                if re_find:
695                    result["valid_ttl_hops"] = re_find
696                    if re_find[0] != valid_ttl_hops:
697                        need_cfg = True
698                else:
699                    need_cfg = True
700
701        connect_mode = module.params['connect_mode']
702        if connect_mode:
703
704            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
705                "<connectMode></connectMode>" + CE_GET_BGP_PEER_TAIL
706            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
707
708            if "<data/>" in recv_xml:
709                need_cfg = True
710            else:
711                re_find = re.findall(
712                    r'.*<connectMode>(.*)</connectMode>.*', recv_xml)
713
714                if re_find:
715                    result["connect_mode"] = re_find
716                    if re_find[0] != connect_mode:
717                        need_cfg = True
718                else:
719                    need_cfg = True
720
721        is_log_change = module.params['is_log_change']
722        if is_log_change != 'no_use':
723
724            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
725                "<isLogChange></isLogChange>" + CE_GET_BGP_PEER_TAIL
726            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
727
728            if "<data/>" in recv_xml:
729                need_cfg = True
730            else:
731                re_find = re.findall(
732                    r'.*<isLogChange>(.*)</isLogChange>.*', recv_xml)
733
734                if re_find:
735                    result["is_log_change"] = re_find
736                    if re_find[0] != is_log_change:
737                        need_cfg = True
738                else:
739                    need_cfg = True
740
741        pswd_type = module.params['pswd_type']
742        if pswd_type:
743
744            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
745                "<pswdType></pswdType>" + CE_GET_BGP_PEER_TAIL
746            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
747
748            if "<data/>" in recv_xml:
749                need_cfg = True
750            else:
751                re_find = re.findall(
752                    r'.*<pswdType>(.*)</pswdType>.*', recv_xml)
753
754                if re_find:
755                    result["pswd_type"] = re_find
756                    if re_find[0] != pswd_type:
757                        need_cfg = True
758                else:
759                    need_cfg = True
760
761        pswd_cipher_text = module.params['pswd_cipher_text']
762        if pswd_cipher_text:
763            if len(pswd_cipher_text) > 255 or len(pswd_cipher_text) < 1:
764                module.fail_json(
765                    msg='Error: The len of pswd_cipher_text %s is out of [1 - 255].' % pswd_cipher_text)
766
767            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
768                "<pswdCipherText></pswdCipherText>" + CE_GET_BGP_PEER_TAIL
769            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
770
771            if "<data/>" in recv_xml:
772                need_cfg = True
773            else:
774                re_find = re.findall(
775                    r'.*<pswdCipherText>(.*)</pswdCipherText>.*', recv_xml)
776
777                if re_find:
778                    result["pswd_cipher_text"] = re_find
779                    if re_find[0] != pswd_cipher_text:
780                        need_cfg = True
781                else:
782                    need_cfg = True
783
784        keep_alive_time = module.params['keep_alive_time']
785        if keep_alive_time:
786            if int(keep_alive_time) > 21845 or len(keep_alive_time) < 0:
787                module.fail_json(
788                    msg='Error: The len of keep_alive_time %s is out of [0 - 21845].' % keep_alive_time)
789
790            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
791                "<keepAliveTime></keepAliveTime>" + CE_GET_BGP_PEER_TAIL
792            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
793
794            if "<data/>" in recv_xml:
795                need_cfg = True
796            else:
797                re_find = re.findall(
798                    r'.*<keepAliveTime>(.*)</keepAliveTime>.*', recv_xml)
799
800                if re_find:
801                    result["keep_alive_time"] = re_find
802                    if re_find[0] != keep_alive_time:
803                        need_cfg = True
804                else:
805                    need_cfg = True
806
807        hold_time = module.params['hold_time']
808        if hold_time:
809            if int(hold_time) != 0 and (int(hold_time) > 65535 or int(hold_time) < 3):
810                module.fail_json(
811                    msg='Error: The value of hold_time %s is out of [0 or 3 - 65535].' % hold_time)
812
813            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
814                "<holdTime></holdTime>" + CE_GET_BGP_PEER_TAIL
815            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
816
817            if "<data/>" in recv_xml:
818                need_cfg = True
819            else:
820                re_find = re.findall(
821                    r'.*<holdTime>(.*)</holdTime>.*', recv_xml)
822
823                if re_find:
824                    result["hold_time"] = re_find
825                    if re_find[0] != hold_time:
826                        need_cfg = True
827                else:
828                    need_cfg = True
829
830        min_hold_time = module.params['min_hold_time']
831        if min_hold_time:
832            if int(min_hold_time) != 0 and (int(min_hold_time) > 65535 or int(min_hold_time) < 20):
833                module.fail_json(
834                    msg='Error: The value of min_hold_time %s is out of [0 or 20 - 65535].' % min_hold_time)
835
836            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
837                "<minHoldTime></minHoldTime>" + CE_GET_BGP_PEER_TAIL
838            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
839
840            if "<data/>" in recv_xml:
841                need_cfg = True
842            else:
843                re_find = re.findall(
844                    r'.*<minHoldTime>(.*)</minHoldTime>.*', recv_xml)
845
846                if re_find:
847                    result["min_hold_time"] = re_find
848                    if re_find[0] != min_hold_time:
849                        need_cfg = True
850                else:
851                    need_cfg = True
852
853        key_chain_name = module.params['key_chain_name']
854        if key_chain_name:
855            if len(key_chain_name) > 47 or len(key_chain_name) < 1:
856                module.fail_json(
857                    msg='Error: The len of key_chain_name %s is out of [1 - 47].' % key_chain_name)
858
859            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
860                "<keyChainName></keyChainName>" + CE_GET_BGP_PEER_TAIL
861            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
862
863            if "<data/>" in recv_xml:
864                need_cfg = True
865            else:
866                re_find = re.findall(
867                    r'.*<keyChainName>(.*)</keyChainName>.*', recv_xml)
868
869                if re_find:
870                    result["key_chain_name"] = re_find
871                    if re_find[0] != key_chain_name:
872                        need_cfg = True
873                else:
874                    need_cfg = True
875
876        conn_retry_time = module.params['conn_retry_time']
877        if conn_retry_time:
878            if int(conn_retry_time) > 65535 or int(conn_retry_time) < 1:
879                module.fail_json(
880                    msg='Error: The value of conn_retry_time %s is out of [1 - 65535].' % conn_retry_time)
881
882            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
883                "<connRetryTime></connRetryTime>" + CE_GET_BGP_PEER_TAIL
884            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
885
886            if "<data/>" in recv_xml:
887                need_cfg = True
888            else:
889                re_find = re.findall(
890                    r'.*<connRetryTime>(.*)</connRetryTime>.*', recv_xml)
891
892                if re_find:
893                    result["conn_retry_time"] = re_find
894                    if re_find[0] != conn_retry_time:
895                        need_cfg = True
896                else:
897                    need_cfg = True
898
899        tcp_mss = module.params['tcp_MSS']
900        if tcp_mss:
901            if int(tcp_mss) > 4096 or int(tcp_mss) < 176:
902                module.fail_json(
903                    msg='Error: The value of tcp_mss %s is out of [176 - 4096].' % tcp_mss)
904
905            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
906                "<tcpMSS></tcpMSS>" + CE_GET_BGP_PEER_TAIL
907            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
908
909            if "<data/>" in recv_xml:
910                need_cfg = True
911            else:
912                re_find = re.findall(
913                    r'.*<tcpMSS>(.*)</tcpMSS>.*', recv_xml)
914
915                if re_find:
916                    result["tcp_MSS"] = re_find
917                    if re_find[0] != tcp_mss:
918                        need_cfg = True
919                else:
920                    need_cfg = True
921
922        mpls_local_ifnet_disable = module.params['mpls_local_ifnet_disable']
923        if mpls_local_ifnet_disable != 'no_use':
924
925            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
926                "<mplsLocalIfnetDisable></mplsLocalIfnetDisable>" + CE_GET_BGP_PEER_TAIL
927            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
928
929            if "<data/>" in recv_xml:
930                need_cfg = True
931            else:
932                re_find = re.findall(
933                    r'.*<mplsLocalIfnetDisable>(.*)</mplsLocalIfnetDisable>.*', recv_xml)
934
935                if re_find:
936                    result["mpls_local_ifnet_disable"] = re_find
937                    if re_find[0] != mpls_local_ifnet_disable:
938                        need_cfg = True
939                else:
940                    need_cfg = True
941
942        prepend_global_as = module.params['prepend_global_as']
943        if prepend_global_as != 'no_use':
944            if not fake_as:
945                module.fail_json(msg='fake_as must exist.')
946            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
947                "<prependGlobalAs></prependGlobalAs>" + CE_GET_BGP_PEER_TAIL
948            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
949
950            if "<data/>" in recv_xml:
951                need_cfg = True
952            else:
953                re_find = re.findall(
954                    r'.*<prependGlobalAs>(.*)</prependGlobalAs>.*', recv_xml)
955
956                if re_find:
957                    result["prepend_global_as"] = re_find
958                    if re_find[0] != prepend_global_as:
959                        need_cfg = True
960                else:
961                    need_cfg = True
962
963        prepend_fake_as = module.params['prepend_fake_as']
964        if prepend_fake_as != 'no_use':
965            if not fake_as:
966                module.fail_json(msg='fake_as must exist.')
967            conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
968                "<prependFakeAs></prependFakeAs>" + CE_GET_BGP_PEER_TAIL
969            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
970
971            if "<data/>" in recv_xml:
972                need_cfg = True
973            else:
974                re_find = re.findall(
975                    r'.*<prependFakeAs>(.*)</prependFakeAs>.*', recv_xml)
976
977                if re_find:
978                    result["prepend_fake_as"] = re_find
979                    if re_find[0] != prepend_fake_as:
980                        need_cfg = True
981                else:
982                    need_cfg = True
983
984        result["need_cfg"] = need_cfg
985        return result
986
987    def check_peer_bfd_merge_args(self, **kwargs):
988        """ check_peer_bfd_merge_args """
989
990        module = kwargs["module"]
991        result = dict()
992        need_cfg = False
993
994        state = module.params['state']
995        if state == "absent":
996            result["need_cfg"] = need_cfg
997            return result
998
999        vrf_name = module.params['vrf_name']
1000        if vrf_name:
1001            if len(vrf_name) > 31 or len(vrf_name) == 0:
1002                module.fail_json(
1003                    msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)
1004
1005        peer_addr = module.params['peer_addr']
1006
1007        is_bfd_block = module.params['is_bfd_block']
1008        if is_bfd_block != 'no_use':
1009
1010            conf_str = CE_GET_PEER_BFD_HEADER % (
1011                vrf_name, peer_addr) + "<isBfdBlock></isBfdBlock>" + CE_GET_PEER_BFD_TAIL
1012            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
1013
1014            if "<data/>" in recv_xml:
1015                need_cfg = True
1016            else:
1017                re_find = re.findall(
1018                    r'.*<isBfdBlock>(.*)</isBfdBlock>.*', recv_xml)
1019
1020                if re_find:
1021                    result["is_bfd_block"] = re_find
1022                    if re_find[0] != is_bfd_block:
1023                        need_cfg = True
1024                else:
1025                    need_cfg = True
1026
1027        multiplier = module.params['multiplier']
1028        if multiplier:
1029            if int(multiplier) > 50 or int(multiplier) < 3:
1030                module.fail_json(
1031                    msg='Error: The value of multiplier %s is out of [3 - 50].' % multiplier)
1032
1033            conf_str = CE_GET_PEER_BFD_HEADER % (
1034                vrf_name, peer_addr) + "<multiplier></multiplier>" + CE_GET_PEER_BFD_TAIL
1035            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
1036
1037            if "<data/>" in recv_xml:
1038                need_cfg = True
1039            else:
1040                re_find = re.findall(
1041                    r'.*<multiplier>(.*)</multiplier>.*', recv_xml)
1042
1043                if re_find:
1044                    result["multiplier"] = re_find
1045                    if re_find[0] != multiplier:
1046                        need_cfg = True
1047                else:
1048                    need_cfg = True
1049
1050        is_bfd_enable = module.params['is_bfd_enable']
1051        if is_bfd_enable != 'no_use':
1052
1053            conf_str = CE_GET_PEER_BFD_HEADER % (
1054                vrf_name, peer_addr) + "<isBfdEnable></isBfdEnable>" + CE_GET_PEER_BFD_TAIL
1055            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
1056
1057            if "<data/>" in recv_xml:
1058                need_cfg = True
1059            else:
1060                re_find = re.findall(
1061                    r'.*<isBfdEnable>(.*)</isBfdEnable>.*', recv_xml)
1062
1063                if re_find:
1064                    result["is_bfd_enable"] = re_find
1065                    if re_find[0] != is_bfd_enable:
1066                        need_cfg = True
1067                else:
1068                    need_cfg = True
1069
1070        rx_interval = module.params['rx_interval']
1071        if rx_interval:
1072            if int(rx_interval) > 1000 or int(rx_interval) < 50:
1073                module.fail_json(
1074                    msg='Error: The value of rx_interval %s is out of [50 - 1000].' % rx_interval)
1075
1076            conf_str = CE_GET_PEER_BFD_HEADER % (
1077                vrf_name, peer_addr) + "<rxInterval></rxInterval>" + CE_GET_PEER_BFD_TAIL
1078            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
1079
1080            if "<data/>" in recv_xml:
1081                need_cfg = True
1082            else:
1083                re_find = re.findall(
1084                    r'.*<rxInterval>(.*)</rxInterval>.*', recv_xml)
1085
1086                if re_find:
1087                    result["rx_interval"] = re_find
1088                    if re_find[0] != rx_interval:
1089                        need_cfg = True
1090                else:
1091                    need_cfg = True
1092
1093        tx_interval = module.params['tx_interval']
1094        if tx_interval:
1095            if int(tx_interval) > 1000 or int(tx_interval) < 50:
1096                module.fail_json(
1097                    msg='Error: The value of tx_interval %s is out of [50 - 1000].' % tx_interval)
1098
1099            conf_str = CE_GET_PEER_BFD_HEADER % (
1100                vrf_name, peer_addr) + "<txInterval></txInterval>" + CE_GET_PEER_BFD_TAIL
1101            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
1102
1103            if "<data/>" in recv_xml:
1104                need_cfg = True
1105            else:
1106                re_find = re.findall(
1107                    r'.*<txInterval>(.*)</txInterval>.*', recv_xml)
1108
1109                if re_find:
1110                    result["tx_interval"] = re_find
1111                    if re_find[0] != tx_interval:
1112                        need_cfg = True
1113                else:
1114                    need_cfg = True
1115
1116        is_single_hop = module.params['is_single_hop']
1117        if is_single_hop != 'no_use':
1118
1119            conf_str = CE_GET_PEER_BFD_HEADER % (
1120                vrf_name, peer_addr) + "<isSingleHop></isSingleHop>" + CE_GET_PEER_BFD_TAIL
1121            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
1122
1123            if "<data/>" in recv_xml:
1124                need_cfg = True
1125            else:
1126                re_find = re.findall(
1127                    r'.*<isSingleHop>(.*)</isSingleHop>.*', recv_xml)
1128
1129                if re_find:
1130                    result["is_single_hop"] = re_find
1131                    if re_find[0] != is_single_hop:
1132                        need_cfg = True
1133                else:
1134                    need_cfg = True
1135
1136        result["need_cfg"] = need_cfg
1137        return result
1138
1139    def check_peer_bfd_delete_args(self, **kwargs):
1140        """ check_peer_bfd_delete_args """
1141
1142        module = kwargs["module"]
1143        result = dict()
1144        need_cfg = False
1145
1146        state = module.params['state']
1147        if state == "present":
1148            result["need_cfg"] = need_cfg
1149            return result
1150
1151        vrf_name = module.params['vrf_name']
1152        if vrf_name:
1153            if len(vrf_name) > 31 or len(vrf_name) == 0:
1154                module.fail_json(
1155                    msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)
1156
1157        peer_addr = module.params['peer_addr']
1158
1159        is_bfd_block = module.params['is_bfd_block']
1160        if is_bfd_block != 'no_use':
1161
1162            conf_str = CE_GET_PEER_BFD_HEADER % (
1163                vrf_name, peer_addr) + "<isBfdBlock></isBfdBlock>" + CE_GET_PEER_BFD_TAIL
1164            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
1165
1166            if "<data/>" in recv_xml:
1167                pass
1168            else:
1169                re_find = re.findall(
1170                    r'.*<isBfdBlock>(.*)</isBfdBlock>.*', recv_xml)
1171
1172                if re_find:
1173                    result["is_bfd_block"] = re_find
1174                    if re_find[0] == is_bfd_block:
1175                        need_cfg = True
1176
1177        multiplier = module.params['multiplier']
1178        if multiplier:
1179            if int(multiplier) > 50 or int(multiplier) < 3:
1180                module.fail_json(
1181                    msg='Error: The value of multiplier %s is out of [3 - 50].' % multiplier)
1182
1183            conf_str = CE_GET_PEER_BFD_HEADER % (
1184                vrf_name, peer_addr) + "<multiplier></multiplier>" + CE_GET_PEER_BFD_TAIL
1185            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
1186
1187            if "<data/>" in recv_xml:
1188                pass
1189            else:
1190                re_find = re.findall(
1191                    r'.*<multiplier>(.*)</multiplier>.*', recv_xml)
1192
1193                if re_find:
1194                    result["multiplier"] = re_find
1195                    if re_find[0] == multiplier:
1196                        need_cfg = True
1197
1198        is_bfd_enable = module.params['is_bfd_enable']
1199        if is_bfd_enable != 'no_use':
1200
1201            conf_str = CE_GET_PEER_BFD_HEADER % (
1202                vrf_name, peer_addr) + "<isBfdEnable></isBfdEnable>" + CE_GET_PEER_BFD_TAIL
1203            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
1204
1205            if "<data/>" in recv_xml:
1206                pass
1207            else:
1208                re_find = re.findall(
1209                    r'.*<isBfdEnable>(.*)</isBfdEnable>.*', recv_xml)
1210
1211                if re_find:
1212                    result["is_bfd_enable"] = re_find
1213                    if re_find[0] == is_bfd_enable:
1214                        need_cfg = True
1215
1216        rx_interval = module.params['rx_interval']
1217        if rx_interval:
1218            if int(rx_interval) > 1000 or int(rx_interval) < 50:
1219                module.fail_json(
1220                    msg='Error: The value of rx_interval %s is out of [50 - 1000].' % rx_interval)
1221
1222            conf_str = CE_GET_PEER_BFD_HEADER % (
1223                vrf_name, peer_addr) + "<rxInterval></rxInterval>" + CE_GET_PEER_BFD_TAIL
1224            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
1225
1226            if "<data/>" in recv_xml:
1227                pass
1228            else:
1229                re_find = re.findall(
1230                    r'.*<rxInterval>(.*)</rxInterval>.*', recv_xml)
1231
1232                if re_find:
1233                    result["rx_interval"] = re_find
1234                    if re_find[0] == rx_interval:
1235                        need_cfg = True
1236
1237        tx_interval = module.params['tx_interval']
1238        if tx_interval:
1239            if int(tx_interval) > 1000 or int(tx_interval) < 50:
1240                module.fail_json(
1241                    msg='Error: The value of tx_interval %s is out of [50 - 1000].' % tx_interval)
1242
1243            conf_str = CE_GET_PEER_BFD_HEADER % (
1244                vrf_name, peer_addr) + "<txInterval></txInterval>" + CE_GET_PEER_BFD_TAIL
1245            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
1246
1247            if "<data/>" in recv_xml:
1248                pass
1249            else:
1250                re_find = re.findall(
1251                    r'.*<txInterval>(.*)</txInterval>.*', recv_xml)
1252
1253                if re_find:
1254                    result["tx_interval"] = re_find
1255                    if re_find[0] == tx_interval:
1256                        need_cfg = True
1257
1258        is_single_hop = module.params['is_single_hop']
1259        if is_single_hop != 'no_use':
1260
1261            conf_str = CE_GET_PEER_BFD_HEADER % (
1262                vrf_name, peer_addr) + "<isSingleHop></isSingleHop>" + CE_GET_PEER_BFD_TAIL
1263            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)
1264
1265            if "<data/>" in recv_xml:
1266                pass
1267            else:
1268                re_find = re.findall(
1269                    r'.*<isSingleHop>(.*)</isSingleHop>.*', recv_xml)
1270
1271                if re_find:
1272                    result["is_single_hop"] = re_find
1273                    if re_find[0] == is_single_hop:
1274                        need_cfg = True
1275
1276        result["need_cfg"] = need_cfg
1277        return result
1278
1279    def get_bgp_peer(self, **kwargs):
1280        """ get_bgp_peer """
1281
1282        module = kwargs["module"]
1283        peerip = module.params['peer_addr']
1284        vrf_name = module.params['vrf_name']
1285        if vrf_name:
1286            if len(vrf_name) > 31 or len(vrf_name) == 0:
1287                module.fail_json(
1288                    msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)
1289
1290        conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + \
1291            "<remoteAs></remoteAs>" + CE_GET_BGP_PEER_TAIL
1292
1293        xml_str = self.netconf_get_config(module=module, conf_str=conf_str)
1294
1295        result = list()
1296
1297        if "<data/>" in xml_str:
1298            return result
1299        else:
1300            re_find = re.findall(
1301                r'.*<peerAddr>(.*)</peerAddr>.*\s.*<remoteAs>(.*)</remoteAs>.*', xml_str)
1302
1303            if re_find:
1304                return re_find
1305            else:
1306                return result
1307
1308    def get_bgp_del_peer(self, **kwargs):
1309        """ get_bgp_del_peer """
1310
1311        module = kwargs["module"]
1312        peerip = module.params['peer_addr']
1313        vrf_name = module.params['vrf_name']
1314        if vrf_name:
1315            if len(vrf_name) > 31 or len(vrf_name) == 0:
1316                module.fail_json(
1317                    msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)
1318
1319        conf_str = CE_GET_BGP_PEER_HEADER % (vrf_name, peerip) + CE_GET_BGP_PEER_TAIL
1320
1321        xml_str = self.netconf_get_config(module=module, conf_str=conf_str)
1322
1323        result = list()
1324
1325        if "<data/>" in xml_str:
1326            return result
1327        else:
1328            re_find = re.findall(
1329                r'.*<peerAddr>(.*)</peerAddr>.*', xml_str)
1330
1331            if re_find:
1332                return re_find
1333            else:
1334                return result
1335
1336    def merge_bgp_peer(self, **kwargs):
1337        """ merge_bgp_peer """
1338
1339        module = kwargs["module"]
1340        vrf_name = module.params['vrf_name']
1341        peer_addr = module.params['peer_addr']
1342        remote_as = module.params['remote_as']
1343
1344        conf_str = CE_MERGE_BGP_PEER_HEADER % (
1345            vrf_name, peer_addr) + "<remoteAs>%s</remoteAs>" % remote_as + CE_MERGE_BGP_PEER_TAIL
1346
1347        recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
1348
1349        if "<ok/>" not in recv_xml:
1350            module.fail_json(msg='Error: Merge bgp peer failed.')
1351
1352        cmds = []
1353        cmd = "peer %s as-number %s" % (peer_addr, remote_as)
1354        cmds.append(cmd)
1355
1356        return cmds
1357
1358    def create_bgp_peer(self, **kwargs):
1359        """ create_bgp_peer """
1360
1361        module = kwargs["module"]
1362
1363        vrf_name = module.params['vrf_name']
1364
1365        peer_addr = module.params['peer_addr']
1366        remote_as = module.params['remote_as']
1367
1368        conf_str = CE_CREATE_BGP_PEER_HEADER % (
1369            vrf_name, peer_addr) + "<remoteAs>%s</remoteAs>" % remote_as + CE_CREATE_BGP_PEER_TAIL
1370
1371        recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
1372
1373        if "<ok/>" not in recv_xml:
1374            module.fail_json(msg='Error: Create bgp peer failed.')
1375
1376        cmds = []
1377        cmd = "peer %s as-number %s" % (peer_addr, remote_as)
1378        cmds.append(cmd)
1379
1380        return cmds
1381
1382    def delete_bgp_peer(self, **kwargs):
1383        """ delete_bgp_peer """
1384
1385        module = kwargs["module"]
1386        vrf_name = module.params['vrf_name']
1387        peer_addr = module.params['peer_addr']
1388
1389        conf_str = CE_DELETE_BGP_PEER_HEADER % (
1390            vrf_name, peer_addr) + CE_DELETE_BGP_PEER_TAIL
1391
1392        recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
1393
1394        if "<ok/>" not in recv_xml:
1395            module.fail_json(msg='Error: Delete bgp peer failed.')
1396
1397        cmds = []
1398        cmd = "undo peer %s" % peer_addr
1399        cmds.append(cmd)
1400
1401        return cmds
1402
1403    def merge_bgp_peer_other(self, **kwargs):
1404        """ merge_bgp_peer """
1405
1406        module = kwargs["module"]
1407        vrf_name = module.params['vrf_name']
1408        peer_addr = module.params['peer_addr']
1409
1410        conf_str = CE_MERGE_BGP_PEER_HEADER % (vrf_name, peer_addr)
1411
1412        cmds = []
1413
1414        description = module.params['description']
1415        if description:
1416            conf_str += "<description>%s</description>" % description
1417
1418            cmd = "peer %s description %s" % (peer_addr, description)
1419            cmds.append(cmd)
1420
1421        fake_as = module.params['fake_as']
1422        if fake_as:
1423            conf_str += "<fakeAs>%s</fakeAs>" % fake_as
1424
1425            cmd = "peer %s local-as %s" % (peer_addr, fake_as)
1426            cmds.append(cmd)
1427
1428        dual_as = module.params['dual_as']
1429        if dual_as != 'no_use':
1430            conf_str += "<dualAs>%s</dualAs>" % dual_as
1431
1432            if dual_as == "true":
1433                cmd = "peer %s local-as %s dual-as" % (peer_addr, fake_as)
1434            else:
1435                cmd = "peer %s local-as %s" % (peer_addr, fake_as)
1436            cmds.append(cmd)
1437
1438        conventional = module.params['conventional']
1439        if conventional != 'no_use':
1440            conf_str += "<conventional>%s</conventional>" % conventional
1441            if conventional == "true":
1442                cmd = "peer %s capability-advertise conventional" % peer_addr
1443            else:
1444                cmd = "undo peer %s capability-advertise conventional" % peer_addr
1445            cmds.append(cmd)
1446
1447        route_refresh = module.params['route_refresh']
1448        if route_refresh != 'no_use':
1449            conf_str += "<routeRefresh>%s</routeRefresh>" % route_refresh
1450
1451            if route_refresh == "true":
1452                cmd = "peer %s capability-advertise route-refresh" % peer_addr
1453            else:
1454                cmd = "undo peer %s capability-advertise route-refresh" % peer_addr
1455            cmds.append(cmd)
1456
1457        four_byte_as = module.params['four_byte_as']
1458        if four_byte_as != 'no_use':
1459            conf_str += "<fourByteAs>%s</fourByteAs>" % four_byte_as
1460
1461            if four_byte_as == "true":
1462                cmd = "peer %s capability-advertise 4-byte-as" % peer_addr
1463            else:
1464                cmd = "undo peer %s capability-advertise 4-byte-as" % peer_addr
1465            cmds.append(cmd)
1466
1467        is_ignore = module.params['is_ignore']
1468        if is_ignore != 'no_use':
1469            conf_str += "<isIgnore>%s</isIgnore>" % is_ignore
1470
1471            if is_ignore == "true":
1472                cmd = "peer %s ignore" % peer_addr
1473            else:
1474                cmd = "undo peer %s ignore" % peer_addr
1475            cmds.append(cmd)
1476
1477        local_if_name = module.params['local_if_name']
1478        if local_if_name:
1479            conf_str += "<localIfName>%s</localIfName>" % local_if_name
1480
1481            cmd = "peer %s connect-interface %s" % (peer_addr, local_if_name)
1482            cmds.append(cmd)
1483
1484        ebgp_max_hop = module.params['ebgp_max_hop']
1485        if ebgp_max_hop:
1486            conf_str += "<ebgpMaxHop>%s</ebgpMaxHop>" % ebgp_max_hop
1487
1488            cmd = "peer %s ebgp-max-hop %s" % (peer_addr, ebgp_max_hop)
1489            cmds.append(cmd)
1490
1491        valid_ttl_hops = module.params['valid_ttl_hops']
1492        if valid_ttl_hops:
1493            conf_str += "<validTtlHops>%s</validTtlHops>" % valid_ttl_hops
1494
1495            cmd = "peer %s valid-ttl-hops %s" % (peer_addr, valid_ttl_hops)
1496            cmds.append(cmd)
1497
1498        connect_mode = module.params['connect_mode']
1499        if connect_mode:
1500
1501            if connect_mode == "listenOnly":
1502                cmd = "peer %s listen-only" % peer_addr
1503                cmds.append(cmd)
1504            elif connect_mode == "connectOnly":
1505                cmd = "peer %s connect-only" % peer_addr
1506                cmds.append(cmd)
1507            elif connect_mode == "both":
1508                connect_mode = "null"
1509                cmd = "peer %s listen-only" % peer_addr
1510                cmds.append(cmd)
1511                cmd = "peer %s connect-only" % peer_addr
1512                cmds.append(cmd)
1513            conf_str += "<connectMode>%s</connectMode>" % connect_mode
1514
1515        is_log_change = module.params['is_log_change']
1516        if is_log_change != 'no_use':
1517            conf_str += "<isLogChange>%s</isLogChange>" % is_log_change
1518
1519            if is_log_change == "true":
1520                cmd = "peer %s log-change" % peer_addr
1521            else:
1522                cmd = "undo peer %s log-change" % peer_addr
1523            cmds.append(cmd)
1524
1525        pswd_type = module.params['pswd_type']
1526        if pswd_type:
1527            conf_str += "<pswdType>%s</pswdType>" % pswd_type
1528
1529        pswd_cipher_text = module.params['pswd_cipher_text']
1530        if pswd_cipher_text:
1531            conf_str += "<pswdCipherText>%s</pswdCipherText>" % pswd_cipher_text
1532
1533            if pswd_type == "cipher":
1534                cmd = "peer %s password cipher %s" % (
1535                    peer_addr, pswd_cipher_text)
1536            elif pswd_type == "simple":
1537                cmd = "peer %s password simple %s" % (
1538                    peer_addr, pswd_cipher_text)
1539            cmds.append(cmd)
1540
1541        keep_alive_time = module.params['keep_alive_time']
1542        if keep_alive_time:
1543            conf_str += "<keepAliveTime>%s</keepAliveTime>" % keep_alive_time
1544
1545            cmd = "peer %s timer keepalive %s" % (peer_addr, keep_alive_time)
1546            cmds.append(cmd)
1547
1548        hold_time = module.params['hold_time']
1549        if hold_time:
1550            conf_str += "<holdTime>%s</holdTime>" % hold_time
1551
1552            cmd = "peer %s timer hold %s" % (peer_addr, hold_time)
1553            cmds.append(cmd)
1554
1555        min_hold_time = module.params['min_hold_time']
1556        if min_hold_time:
1557            conf_str += "<minHoldTime>%s</minHoldTime>" % min_hold_time
1558
1559            cmd = "peer %s timer min-holdtime %s" % (peer_addr, min_hold_time)
1560            cmds.append(cmd)
1561
1562        key_chain_name = module.params['key_chain_name']
1563        if key_chain_name:
1564            conf_str += "<keyChainName>%s</keyChainName>" % key_chain_name
1565
1566            cmd = "peer %s keychain %s" % (peer_addr, key_chain_name)
1567            cmds.append(cmd)
1568
1569        conn_retry_time = module.params['conn_retry_time']
1570        if conn_retry_time:
1571            conf_str += "<connRetryTime>%s</connRetryTime>" % conn_retry_time
1572
1573            cmd = "peer %s timer connect-retry %s" % (
1574                peer_addr, conn_retry_time)
1575            cmds.append(cmd)
1576
1577        tcp_mss = module.params['tcp_MSS']
1578        if tcp_mss:
1579            conf_str += "<tcpMSS>%s</tcpMSS>" % tcp_mss
1580
1581            cmd = "peer %s tcp-mss %s" % (peer_addr, tcp_mss)
1582            cmds.append(cmd)
1583
1584        mpls_local_ifnet_disable = module.params['mpls_local_ifnet_disable']
1585        if mpls_local_ifnet_disable != 'no_use':
1586            conf_str += "<mplsLocalIfnetDisable>%s</mplsLocalIfnetDisable>" % mpls_local_ifnet_disable
1587
1588            if mpls_local_ifnet_disable == "false":
1589                cmd = "undo peer %s mpls-local-ifnet disable" % peer_addr
1590            else:
1591                cmd = "peer %s mpls-local-ifnet disable" % peer_addr
1592            cmds.append(cmd)
1593
1594        prepend_global_as = module.params['prepend_global_as']
1595        if prepend_global_as != 'no_use':
1596            conf_str += "<prependGlobalAs>%s</prependGlobalAs>" % prepend_global_as
1597
1598            if prepend_global_as == "true":
1599                cmd = "peer %s local-as %s prepend-global-as" % (peer_addr, fake_as)
1600            else:
1601                cmd = "undo peer %s local-as %s prepend-global-as" % (peer_addr, fake_as)
1602            cmds.append(cmd)
1603
1604        prepend_fake_as = module.params['prepend_fake_as']
1605        if prepend_fake_as != 'no_use':
1606            conf_str += "<prependFakeAs>%s</prependFakeAs>" % prepend_fake_as
1607
1608            if prepend_fake_as == "true":
1609                cmd = "peer %s local-as %s prepend-local-as" % (peer_addr, fake_as)
1610            else:
1611                cmd = "undo peer %s local-as %s prepend-local-as" % (peer_addr, fake_as)
1612            cmds.append(cmd)
1613
1614        conf_str += CE_MERGE_BGP_PEER_TAIL
1615
1616        recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
1617
1618        if "<ok/>" not in recv_xml:
1619            module.fail_json(msg='Error: Merge bgp peer other failed.')
1620
1621        return cmds
1622
1623    def merge_peer_bfd(self, **kwargs):
1624        """ merge_peer_bfd """
1625
1626        module = kwargs["module"]
1627        vrf_name = module.params['vrf_name']
1628        peer_addr = module.params['peer_addr']
1629
1630        conf_str = CE_MERGE_PEER_BFD_HEADER % (vrf_name, peer_addr)
1631
1632        cmds = []
1633
1634        is_bfd_block = module.params['is_bfd_block']
1635        if is_bfd_block != 'no_use':
1636            conf_str += "<isBfdBlock>%s</isBfdBlock>" % is_bfd_block
1637
1638            if is_bfd_block == "true":
1639                cmd = "peer %s bfd block" % peer_addr
1640            else:
1641                cmd = "undo peer %s bfd block" % peer_addr
1642            cmds.append(cmd)
1643
1644        multiplier = module.params['multiplier']
1645        if multiplier:
1646            conf_str += "<multiplier>%s</multiplier>" % multiplier
1647
1648            cmd = "peer %s bfd detect-multiplier %s" % (peer_addr, multiplier)
1649            cmds.append(cmd)
1650
1651        is_bfd_enable = module.params['is_bfd_enable']
1652        if is_bfd_enable != 'no_use':
1653            conf_str += "<isBfdEnable>%s</isBfdEnable>" % is_bfd_enable
1654
1655            if is_bfd_enable == "true":
1656                cmd = "peer %s bfd enable" % peer_addr
1657            else:
1658                cmd = "undo peer %s bfd enable" % peer_addr
1659            cmds.append(cmd)
1660
1661        rx_interval = module.params['rx_interval']
1662        if rx_interval:
1663            conf_str += "<rxInterval>%s</rxInterval>" % rx_interval
1664
1665            cmd = "peer %s bfd min-rx-interval %s" % (peer_addr, rx_interval)
1666            cmds.append(cmd)
1667
1668        tx_interval = module.params['tx_interval']
1669        if tx_interval:
1670            conf_str += "<txInterval>%s</txInterval>" % tx_interval
1671
1672            cmd = "peer %s bfd min-tx-interval %s" % (peer_addr, tx_interval)
1673            cmds.append(cmd)
1674
1675        is_single_hop = module.params['is_single_hop']
1676        if is_single_hop != 'no_use':
1677            conf_str += "<isSingleHop>%s</isSingleHop>" % is_single_hop
1678
1679            if is_single_hop == "true":
1680                cmd = "peer %s bfd enable single-hop-prefer" % peer_addr
1681            else:
1682                cmd = "undo peer %s bfd enable single-hop-prefer" % peer_addr
1683            cmds.append(cmd)
1684
1685        conf_str += CE_MERGE_PEER_BFD_TAIL
1686
1687        recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
1688
1689        if "<ok/>" not in recv_xml:
1690            module.fail_json(msg='Error: Merge peer bfd failed.')
1691
1692        return cmds
1693
1694    def delete_peer_bfd(self, **kwargs):
1695        """ delete_peer_bfd """
1696
1697        module = kwargs["module"]
1698        vrf_name = module.params['vrf_name']
1699        peer_addr = module.params['peer_addr']
1700
1701        conf_str = CE_DELETE_PEER_BFD_HEADER % (vrf_name, peer_addr)
1702
1703        cmds = []
1704
1705        is_bfd_block = module.params['is_bfd_block']
1706        if is_bfd_block != 'no_use':
1707            conf_str += "<isBfdBlock>%s</isBfdBlock>" % is_bfd_block
1708
1709            cmd = "undo peer %s bfd block" % peer_addr
1710            cmds.append(cmd)
1711
1712        multiplier = module.params['multiplier']
1713        if multiplier:
1714            conf_str += "<multiplier>%s</multiplier>" % multiplier
1715
1716            cmd = "undo peer %s bfd detect-multiplier %s" % (
1717                peer_addr, multiplier)
1718            cmds.append(cmd)
1719
1720        is_bfd_enable = module.params['is_bfd_enable']
1721        if is_bfd_enable != 'no_use':
1722            conf_str += "<isBfdEnable>%s</isBfdEnable>" % is_bfd_enable
1723
1724            cmd = "undo peer %s bfd enable" % peer_addr
1725            cmds.append(cmd)
1726
1727        rx_interval = module.params['rx_interval']
1728        if rx_interval:
1729            conf_str += "<rxInterval>%s</rxInterval>" % rx_interval
1730
1731            cmd = "undo peer %s bfd min-rx-interval %s" % (
1732                peer_addr, rx_interval)
1733            cmds.append(cmd)
1734
1735        tx_interval = module.params['tx_interval']
1736        if tx_interval:
1737            conf_str += "<txInterval>%s</txInterval>" % tx_interval
1738
1739            cmd = "undo peer %s bfd min-tx-interval %s" % (
1740                peer_addr, tx_interval)
1741            cmds.append(cmd)
1742
1743        is_single_hop = module.params['is_single_hop']
1744        if is_single_hop != 'no_use':
1745            conf_str += "<isSingleHop>%s</isSingleHop>" % is_single_hop
1746
1747            cmd = "undo peer %s bfd enable single-hop-prefer" % peer_addr
1748            cmds.append(cmd)
1749
1750        conf_str += CE_DELETE_PEER_BFD_TAIL
1751
1752        recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)
1753
1754        if "<ok/>" not in recv_xml:
1755            module.fail_json(msg='Error: Delete peer bfd failed.')
1756
1757        return cmds
1758
1759
1760def main():
1761    """ main """
1762
1763    argument_spec = dict(
1764        state=dict(choices=['present', 'absent'], default='present'),
1765        vrf_name=dict(type='str', required=True),
1766        peer_addr=dict(type='str', required=True),
1767        remote_as=dict(type='str', required=True),
1768        description=dict(type='str'),
1769        fake_as=dict(type='str'),
1770        dual_as=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
1771        conventional=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
1772        route_refresh=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
1773        four_byte_as=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
1774        is_ignore=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
1775        local_if_name=dict(type='str'),
1776        ebgp_max_hop=dict(type='str'),
1777        valid_ttl_hops=dict(type='str'),
1778        connect_mode=dict(choices=['listenOnly', 'connectOnly', 'both']),
1779        is_log_change=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
1780        pswd_type=dict(choices=['null', 'cipher', 'simple']),
1781        pswd_cipher_text=dict(type='str', no_log=True),
1782        keep_alive_time=dict(type='str'),
1783        hold_time=dict(type='str'),
1784        min_hold_time=dict(type='str'),
1785        key_chain_name=dict(type='str'),
1786        conn_retry_time=dict(type='str'),
1787        tcp_MSS=dict(type='str'),
1788        mpls_local_ifnet_disable=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
1789        prepend_global_as=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
1790        prepend_fake_as=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
1791        is_bfd_block=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
1792        multiplier=dict(type='str'),
1793        is_bfd_enable=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
1794        rx_interval=dict(type='str'),
1795        tx_interval=dict(type='str'),
1796        is_single_hop=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']))
1797
1798    argument_spec.update(ce_argument_spec)
1799    module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
1800
1801    changed = False
1802    proposed = dict()
1803    existing = dict()
1804    end_state = dict()
1805    updates = []
1806
1807    state = module.params['state']
1808    vrf_name = module.params['vrf_name']
1809    peer_addr = module.params['peer_addr']
1810    remote_as = module.params['remote_as']
1811    description = module.params['description']
1812    fake_as = module.params['fake_as']
1813    dual_as = module.params['dual_as']
1814    conventional = module.params['conventional']
1815    route_refresh = module.params['route_refresh']
1816    four_byte_as = module.params['four_byte_as']
1817    is_ignore = module.params['is_ignore']
1818    local_if_name = module.params['local_if_name']
1819    ebgp_max_hop = module.params['ebgp_max_hop']
1820    valid_ttl_hops = module.params['valid_ttl_hops']
1821    connect_mode = module.params['connect_mode']
1822    is_log_change = module.params['is_log_change']
1823    pswd_type = module.params['pswd_type']
1824    pswd_cipher_text = module.params['pswd_cipher_text']
1825    keep_alive_time = module.params['keep_alive_time']
1826    hold_time = module.params['hold_time']
1827    min_hold_time = module.params['min_hold_time']
1828    key_chain_name = module.params['key_chain_name']
1829    conn_retry_time = module.params['conn_retry_time']
1830    tcp_mss = module.params['tcp_MSS']
1831    mpls_local_ifnet_disable = module.params['mpls_local_ifnet_disable']
1832    prepend_global_as = module.params['prepend_global_as']
1833    prepend_fake_as = module.params['prepend_fake_as']
1834    is_bfd_block = module.params['is_bfd_block']
1835    multiplier = module.params['multiplier']
1836    is_bfd_enable = module.params['is_bfd_enable']
1837    rx_interval = module.params['rx_interval']
1838    tx_interval = module.params['tx_interval']
1839    is_single_hop = module.params['is_single_hop']
1840
1841    ce_bgp_peer_obj = BgpNeighbor()
1842
1843    # get proposed
1844    proposed["state"] = state
1845    if vrf_name:
1846        proposed["vrf_name"] = vrf_name
1847    if peer_addr:
1848        proposed["peer_addr"] = peer_addr
1849    if remote_as:
1850        proposed["remote_as"] = remote_as
1851    if description:
1852        proposed["description"] = description
1853    if fake_as:
1854        proposed["fake_as"] = fake_as
1855    if dual_as != 'no_use':
1856        proposed["dual_as"] = dual_as
1857    if conventional != 'no_use':
1858        proposed["conventional"] = conventional
1859    if route_refresh != 'no_use':
1860        proposed["route_refresh"] = route_refresh
1861    if four_byte_as != 'no_use':
1862        proposed["four_byte_as"] = four_byte_as
1863    if is_ignore != 'no_use':
1864        proposed["is_ignore"] = is_ignore
1865    if local_if_name:
1866        proposed["local_if_name"] = local_if_name
1867    if ebgp_max_hop:
1868        proposed["ebgp_max_hop"] = ebgp_max_hop
1869    if valid_ttl_hops:
1870        proposed["valid_ttl_hops"] = valid_ttl_hops
1871    if connect_mode:
1872        proposed["connect_mode"] = connect_mode
1873    if is_log_change != 'no_use':
1874        proposed["is_log_change"] = is_log_change
1875    if pswd_type:
1876        proposed["pswd_type"] = pswd_type
1877    if pswd_cipher_text:
1878        proposed["pswd_cipher_text"] = pswd_cipher_text
1879    if keep_alive_time:
1880        proposed["keep_alive_time"] = keep_alive_time
1881    if hold_time:
1882        proposed["hold_time"] = hold_time
1883    if min_hold_time:
1884        proposed["min_hold_time"] = min_hold_time
1885    if key_chain_name:
1886        proposed["key_chain_name"] = key_chain_name
1887    if conn_retry_time:
1888        proposed["conn_retry_time"] = conn_retry_time
1889    if tcp_mss:
1890        proposed["tcp_MSS"] = tcp_mss
1891    if mpls_local_ifnet_disable != 'no_use':
1892        proposed["mpls_local_ifnet_disable"] = mpls_local_ifnet_disable
1893    if prepend_global_as != 'no_use':
1894        proposed["prepend_global_as"] = prepend_global_as
1895    if prepend_fake_as != 'no_use':
1896        proposed["prepend_fake_as"] = prepend_fake_as
1897    if is_bfd_block != 'no_use':
1898        proposed["is_bfd_block"] = is_bfd_block
1899    if multiplier:
1900        proposed["multiplier"] = multiplier
1901    if is_bfd_enable != 'no_use':
1902        proposed["is_bfd_enable"] = is_bfd_enable
1903    if rx_interval:
1904        proposed["rx_interval"] = rx_interval
1905    if tx_interval:
1906        proposed["tx_interval"] = tx_interval
1907    if is_single_hop != 'no_use':
1908        proposed["is_single_hop"] = is_single_hop
1909
1910    if not ce_bgp_peer_obj:
1911        module.fail_json(msg='Error: Init module failed.')
1912
1913    need_bgp_peer_enable = ce_bgp_peer_obj.check_bgp_peer_args(module=module)
1914    need_bgp_peer_other_rst = ce_bgp_peer_obj.check_bgp_peer_other_args(
1915        module=module)
1916    need_peer_bfd_merge_rst = ce_bgp_peer_obj.check_peer_bfd_merge_args(
1917        module=module)
1918    need_peer_bfd_del_rst = ce_bgp_peer_obj.check_peer_bfd_delete_args(
1919        module=module)
1920
1921    # bgp peer config
1922    if need_bgp_peer_enable["need_cfg"]:
1923
1924        if state == "present":
1925
1926            if remote_as:
1927
1928                bgp_peer_exist = ce_bgp_peer_obj.get_bgp_peer(module=module)
1929                existing["bgp peer"] = bgp_peer_exist
1930
1931                bgp_peer_new = (peer_addr, remote_as)
1932                if len(bgp_peer_exist) == 0:
1933                    cmd = ce_bgp_peer_obj.create_bgp_peer(module=module)
1934                    changed = True
1935                    for item in cmd:
1936                        updates.append(item)
1937
1938                elif bgp_peer_new in bgp_peer_exist:
1939                    pass
1940
1941                else:
1942                    cmd = ce_bgp_peer_obj.merge_bgp_peer(module=module)
1943                    changed = True
1944                    for item in cmd:
1945                        updates.append(item)
1946
1947                bgp_peer_end = ce_bgp_peer_obj.get_bgp_peer(module=module)
1948                end_state["bgp peer"] = bgp_peer_end
1949
1950        else:
1951
1952            bgp_peer_exist = ce_bgp_peer_obj.get_bgp_del_peer(module=module)
1953            existing["bgp peer"] = bgp_peer_exist
1954
1955            bgp_peer_new = (peer_addr)
1956
1957            if len(bgp_peer_exist) == 0:
1958                pass
1959
1960            elif bgp_peer_new in bgp_peer_exist:
1961                cmd = ce_bgp_peer_obj.delete_bgp_peer(module=module)
1962                changed = True
1963                for item in cmd:
1964                    updates.append(item)
1965
1966            bgp_peer_end = ce_bgp_peer_obj.get_bgp_del_peer(module=module)
1967            end_state["bgp peer"] = bgp_peer_end
1968
1969    # bgp peer other args
1970    exist_tmp = dict()
1971    for item in need_bgp_peer_other_rst:
1972        if item != "need_cfg":
1973            exist_tmp[item] = need_bgp_peer_other_rst[item]
1974    if exist_tmp:
1975        existing["bgp peer other"] = exist_tmp
1976
1977    if need_bgp_peer_other_rst["need_cfg"]:
1978
1979        if state == "present":
1980            cmd = ce_bgp_peer_obj.merge_bgp_peer_other(module=module)
1981            changed = True
1982            for item in cmd:
1983                updates.append(item)
1984
1985    need_bgp_peer_other_rst = ce_bgp_peer_obj.check_bgp_peer_other_args(
1986        module=module)
1987    end_tmp = dict()
1988    for item in need_bgp_peer_other_rst:
1989        if item != "need_cfg":
1990            end_tmp[item] = need_bgp_peer_other_rst[item]
1991    if end_tmp:
1992        end_state["bgp peer other"] = end_tmp
1993
1994    # peer bfd args
1995    if state == "present":
1996        exist_tmp = dict()
1997        for item in need_peer_bfd_merge_rst:
1998            if item != "need_cfg":
1999                exist_tmp[item] = need_peer_bfd_merge_rst[item]
2000        if exist_tmp:
2001            existing["peer bfd"] = exist_tmp
2002
2003        if need_peer_bfd_merge_rst["need_cfg"]:
2004            cmd = ce_bgp_peer_obj.merge_peer_bfd(module=module)
2005            changed = True
2006            for item in cmd:
2007                updates.append(item)
2008
2009        need_peer_bfd_merge_rst = ce_bgp_peer_obj.check_peer_bfd_merge_args(
2010            module=module)
2011        end_tmp = dict()
2012        for item in need_peer_bfd_merge_rst:
2013            if item != "need_cfg":
2014                end_tmp[item] = need_peer_bfd_merge_rst[item]
2015        if end_tmp:
2016            end_state["peer bfd"] = end_tmp
2017    else:
2018        exist_tmp = dict()
2019        for item in need_peer_bfd_del_rst:
2020            if item != "need_cfg":
2021                exist_tmp[item] = need_peer_bfd_del_rst[item]
2022        if exist_tmp:
2023            existing["peer bfd"] = exist_tmp
2024
2025        # has already delete with bgp peer
2026
2027        need_peer_bfd_del_rst = ce_bgp_peer_obj.check_peer_bfd_delete_args(
2028            module=module)
2029        end_tmp = dict()
2030        for item in need_peer_bfd_del_rst:
2031            if item != "need_cfg":
2032                end_tmp[item] = need_peer_bfd_del_rst[item]
2033        if end_tmp:
2034            end_state["peer bfd"] = end_tmp
2035
2036    results = dict()
2037    results['proposed'] = proposed
2038    results['existing'] = existing
2039    results['changed'] = changed
2040    results['end_state'] = end_state
2041    results['updates'] = updates
2042
2043    module.exit_json(**results)
2044
2045
2046if __name__ == '__main__':
2047    main()
2048