1#
2# (c) 2019, Ansible by Red Hat, inc
3# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
4#
5
6from __future__ import (absolute_import, division, print_function)
7__metaclass__ = type
8
9from ansible.module_utils.network.frr.providers.cli.config.bgp.process import Provider
10from ansible.modules.network.frr import frr_bgp
11from .frr_module import TestFrrModule, load_fixture
12
13
14class TestFrrBgpModule(TestFrrModule):
15    module = frr_bgp
16
17    def setUp(self):
18        super(TestFrrBgpModule, self).setUp()
19        self._bgp_config = load_fixture('frr_bgp_config')
20
21    def test_frr_bgp(self):
22        obj = Provider(params=dict(config=dict(bgp_as=64496, router_id='192.0.2.2', networks=None,
23                                               address_family=None), operation='merge'))
24        commands = obj.render(self._bgp_config)
25        self.assertEqual(commands, ['router bgp 64496', 'bgp router-id 192.0.2.2', 'exit'])
26
27    def test_frr_bgp_idempotent(self):
28        obj = Provider(params=dict(config=dict(bgp_as=64496, router_id='192.0.2.1', networks=None,
29                                               address_family=None), operation='merge'))
30        commands = obj.render(self._bgp_config)
31        self.assertEqual(commands, [])
32
33    def test_frr_bgp_remove(self):
34        obj = Provider(params=dict(config=dict(bgp_as=64496, networks=None,
35                                               address_family=None), operation='delete'))
36        commands = obj.render(self._bgp_config)
37        self.assertEqual(commands, ['no router bgp 64496'])
38
39    def test_frr_bgp_neighbor(self):
40        obj = Provider(params=dict(config=dict(bgp_as=64496, neighbors=[dict(neighbor='192.51.100.2', remote_as=64496)],
41                                               networks=None, address_family=None),
42                                   operation='merge'))
43        commands = obj.render(self._bgp_config)
44        self.assertEqual(commands, ['router bgp 64496', 'neighbor 192.51.100.2 remote-as 64496', 'exit'])
45
46    def test_frr_bgp_neighbor_idempotent(self):
47        obj = Provider(params=dict(config=dict(bgp_as=64496, neighbors=[dict(neighbor='192.51.100.1', remote_as=64496,
48                                                                             timers=dict(keepalive=120, holdtime=360))],
49                                               networks=None, address_family=None),
50                                   operation='merge'))
51        commands = obj.render(self._bgp_config)
52        self.assertEqual(commands, [])
53
54    def test_frr_bgp_network(self):
55        obj = Provider(params=dict(config=dict(bgp_as=64496, networks=[dict(prefix='192.0.2.0', masklen=24, route_map='RMAP_1')],
56                                               address_family=None),
57                                   operation='merge'))
58        commands = obj.render(self._bgp_config)
59        self.assertEqual(sorted(commands), sorted(['router bgp 64496', 'network 192.0.2.0/24 route-map RMAP_1', 'exit']))
60
61    def test_frr_bgp_network_idempotent(self):
62        obj = Provider(params=dict(config=dict(bgp_as=64496, networks=[dict(prefix='192.0.1.0', masklen=24, route_map='RMAP_1'),
63                                                                       dict(prefix='198.51.100.0', masklen=24, route_map='RMAP_2')],
64                                               address_family=None),
65                                   operation='merge'))
66        commands = obj.render(self._bgp_config)
67        self.assertEqual(commands, [])
68
69    def test_frr_bgp_address_family_redistribute(self):
70        rd_1 = dict(protocol='ospf', id='233', metric=90, route_map=None)
71
72        config = dict(bgp_as=64496, address_family=[dict(afi='ipv4', safi='unicast', redistribute=[rd_1])],
73                      networks=None)
74
75        obj = Provider(params=dict(config=config, operation='merge'))
76
77        commands = obj.render(self._bgp_config)
78        cmd = ['router bgp 64496', 'address-family ipv4 unicast', 'redistribute ospf 233 metric 90',
79               'exit-address-family', 'exit']
80        self.assertEqual(sorted(commands), sorted(cmd))
81
82    def test_frr_bgp_address_family_redistribute_idempotent(self):
83        rd_1 = dict(protocol='eigrp', metric=10, route_map='RMAP_3', id=None)
84        rd_2 = dict(protocol='static', metric=100, id=None, route_map=None)
85
86        config = dict(bgp_as=64496, address_family=[dict(afi='ipv4', safi='unicast', redistribute=[rd_1, rd_2])],
87                      networks=None)
88
89        obj = Provider(params=dict(config=config, operation='merge'))
90
91        commands = obj.render(self._bgp_config)
92        self.assertEqual(commands, [])
93
94    def test_frr_bgp_address_family_neighbors(self):
95        af_nbr_1 = dict(neighbor='192.51.100.1', maximum_prefix=35, activate=True)
96        af_nbr_2 = dict(neighbor='192.51.100.3', route_reflector_client=True, activate=True)
97
98        config = dict(bgp_as=64496, address_family=[dict(afi='ipv4', safi='multicast', neighbors=[af_nbr_1, af_nbr_2])],
99                      networks=None)
100
101        obj = Provider(params=dict(config=config, operation='merge'))
102
103        commands = obj.render(self._bgp_config)
104        cmd = ['router bgp 64496', 'address-family ipv4 multicast', 'neighbor 192.51.100.1 activate',
105               'neighbor 192.51.100.1 maximum-prefix 35', 'neighbor 192.51.100.3 activate',
106               'neighbor 192.51.100.3 route-reflector-client', 'exit-address-family', 'exit']
107        self.assertEqual(sorted(commands), sorted(cmd))
108
109    def test_frr_bgp_address_family_neighbors_idempotent(self):
110        af_nbr_1 = dict(neighbor='2.2.2.2', remove_private_as=True, maximum_prefix=100)
111
112        config = dict(bgp_as=64496, address_family=[dict(afi='ipv4', safi='unicast', neighbors=[af_nbr_1])],
113                      networks=None)
114
115        obj = Provider(params=dict(config=config, operation='merge'))
116
117        commands = obj.render(self._bgp_config)
118        self.assertEqual(commands, [])
119
120    def test_frr_bgp_address_family_networks(self):
121        net = dict(prefix='1.0.0.0', masklen=8, route_map='RMAP_1')
122        net2 = dict(prefix='192.168.1.0', masklen=24, route_map='RMAP_2')
123
124        config = dict(bgp_as=64496, address_family=[dict(afi='ipv4', safi='multicast', networks=[net, net2])],
125                      networks=None)
126
127        obj = Provider(params=dict(config=config, operation='merge'))
128
129        commands = obj.render(self._bgp_config)
130        cmd = ['router bgp 64496', 'address-family ipv4 multicast', 'network 1.0.0.0/8 route-map RMAP_1',
131               'network 192.168.1.0/24 route-map RMAP_2', 'exit-address-family', 'exit']
132        self.assertEqual(sorted(commands), sorted(cmd))
133
134    def test_frr_bgp_address_family_networks_idempotent(self):
135        net = dict(prefix='10.0.0.0', masklen=8, route_map='RMAP_1')
136        net2 = dict(prefix='20.0.0.0', masklen=8, route_map='RMAP_2')
137
138        config = dict(bgp_as=64496, address_family=[dict(afi='ipv4', safi='multicast', networks=[net, net2])],
139                      networks=None)
140
141        obj = Provider(params=dict(config=config, operation='merge'))
142
143        commands = obj.render(self._bgp_config)
144        self.assertEqual(commands, [])
145
146    def test_frr_bgp_operation_override(self):
147        net_1 = dict(prefix='1.0.0.0', masklen=8, route_map='RMAP_1')
148        net_2 = dict(prefix='192.168.1.0', masklen=24, route_map='RMAP_2')
149        nbr_1 = dict(neighbor='192.51.100.1', remote_as=64496, advertisement_interval=120)
150        nbr_2 = dict(neighbor='192.51.100.3', remote_as=64496, timers=dict(keepalive=300, holdtime=360))
151        af_nbr_1 = dict(neighbor='192.51.100.1', maximum_prefix=35)
152        af_nbr_2 = dict(neighbor='192.51.100.3', route_reflector_client=True)
153
154        af_1 = dict(afi='ipv4', safi='unicast', neighbors=[af_nbr_1, af_nbr_2])
155        af_2 = dict(afi='ipv4', safi='multicast', networks=[net_1, net_2])
156        config = dict(bgp_as=64496, neighbors=[nbr_1, nbr_2], address_family=[af_1, af_2], networks=None)
157
158        obj = Provider(params=dict(config=config, operation='override'))
159        commands = obj.render(self._bgp_config)
160
161        cmd = ['no router bgp 64496', 'router bgp 64496', 'neighbor 192.51.100.1 remote-as 64496',
162               'neighbor 192.51.100.1 advertisement-interval 120', 'neighbor 192.51.100.3 remote-as 64496',
163               'neighbor 192.51.100.3 timers 300 360', 'address-family ipv4 unicast',
164               'neighbor 192.51.100.1 maximum-prefix 35', 'neighbor 192.51.100.3 route-reflector-client', 'exit-address-family',
165               'address-family ipv4 multicast', 'network 1.0.0.0/8 route-map RMAP_1', 'network 192.168.1.0/24 route-map RMAP_2',
166               'exit-address-family', 'exit']
167
168        self.assertEqual(sorted(commands), sorted(cmd))
169
170    def test_frr_bgp_operation_replace(self):
171        rd = dict(protocol='ospf', id=223, metric=110, route_map=None)
172        net = dict(prefix='10.0.0.0', masklen=8, route_map='RMAP_1')
173        net2 = dict(prefix='20.0.0.0', masklen=8, route_map='RMAP_2')
174
175        af_1 = dict(afi='ipv4', safi='unicast', redistribute=[rd])
176        af_2 = dict(afi='ipv4', safi='multicast', networks=[net, net2])
177
178        config = dict(bgp_as=64496, address_family=[af_1, af_2], networks=None)
179        obj = Provider(params=dict(config=config, operation='replace'))
180        commands = obj.render(self._bgp_config)
181
182        cmd = ['router bgp 64496', 'address-family ipv4 unicast', 'redistribute ospf 223 metric 110', 'no redistribute eigrp',
183               'no redistribute static', 'exit-address-family', 'exit']
184
185        self.assertEqual(sorted(commands), sorted(cmd))
186
187    def test_frr_bgp_operation_replace_with_new_as(self):
188        rd = dict(protocol='ospf', id=223, metric=110, route_map=None)
189
190        af_1 = dict(afi='ipv4', safi='unicast', redistribute=[rd])
191
192        config = dict(bgp_as=64497, address_family=[af_1], networks=None)
193        obj = Provider(params=dict(config=config, operation='replace'))
194        commands = obj.render(self._bgp_config)
195
196        cmd = ['no router bgp 64496', 'router bgp 64497', 'address-family ipv4 unicast', 'redistribute ospf 223 metric 110',
197               'exit-address-family', 'exit']
198
199        self.assertEqual(sorted(commands), sorted(cmd))
200