We made it to the part where we are going to actually configure something using python. In this post we are going to add a function called deployconfig that will check for diffs in the the running config against our templates. If any are found the configuration will be updated. To accomplish this we are going to use Napalm.

Topology

L3LS

Here are the changes to configureleafspine.py

configureleafspine.py

#!/usr/bin/env python3

from jinja2 import Environment, FileSystemLoader
import yaml
from napalm import get_network_driver


class ConfigureLeafSpine():
    """Class to configure and maintain leaf spine switches"""

--snip--

    def deployconfig(self):
        """Checks for diffs and deploys configs using NAPALM"""
        driver = get_network_driver('eos')
        for key, value in self.hosts.items():
            device = driver(key, 'admin', 'admin')
            device.open()
            device.load_merge_candidate(
                filename='configs/{0}.config'.format(key)
                )
            diffs = device.compare_config()
            if diffs:
                print("{0} Diffs: ".format(key))
                print("\n{0}".format(diffs))
                device.commit_config()
            device.close()


if __name__ == "__main__":
    lsconfig = ConfigureLeafSpine(
        'hosts.yaml',
        'groups.yaml',
        'baseconfig.j2',
        'spine.yaml',
        'spine.j2',
        'leaf.yaml',
        'leaf.j2'
    )
    lsconfig.generatebaseconfig()
    lsconfig.generatespineconfig()
    lsconfig.generateleafconfig()
    lsconfig.deployconfig()

Running the file with python3 configfigureleafspine.py will produce the following output.

spine-1 Diffs: 

@@ -24,8 +24,18 @@
 vrf definition management
 !
 interface Ethernet1
+   description P2P Link to Leaf-1
+   logging event link-status
+   no switchport
+   ip address 172.16.0.1/30
+   arp timeout 900
 !
 interface Ethernet2
+   description P2P Link to Leaf-2
+   logging event link-status
+   no switchport
+   ip address 172.16.0.5/30
+   arp timeout 900
 !
 interface Ethernet3
 !
@@ -47,14 +57,27 @@
 !
 interface Ethernet12
 !
+interface Loopback0
+   ip address 192.168.0.1/32
+!
 interface Management1
    vrf forwarding management
    ip address 198.51.100.254/24
 !
 ip route vrf management 0.0.0.0/0 198.51.100.1
 !
-no ip routing
+ip routing
 no ip routing vrf management
+!
+router bgp 65000
+   distance bgp 20 200 200
+   maximum-paths 4 ecmp 64
+   neighbor EBGP-TO-LEAF peer-group
+   neighbor EBGP-TO-LEAF remote-as 65100
+   neighbor EBGP-TO-LEAF maximum-routes 12000 
+   neighbor 172.16.0.2 peer-group EBGP-TO-LEAF
+   neighbor 172.16.0.6 peer-group EBGP-TO-LEAF
+   network 192.168.0.1/32
 !
 management api http-commands
    protocol http
spine-2 Diffs: 

@@ -24,8 +24,18 @@
 vrf definition management
 !
 interface Ethernet1
+   description P2P Link to Leaf-1
+   logging event link-status
+   no switchport
+   ip address 172.16.0.9/30
+   arp timeout 900
 !
 interface Ethernet2
+   description P2P Link to Leaf-2
+   logging event link-status
+   no switchport
+   ip address 172.16.0.13/30
+   arp timeout 900
 !
 interface Ethernet3
 !
@@ -47,14 +57,27 @@
 !
 interface Ethernet12
 !
+interface Loopback0
+   ip address 192.168.0.2/32
+!
 interface Management1
    vrf forwarding management
    ip address 198.51.100.253/24
 !
 ip route vrf management 0.0.0.0/0 198.51.100.1
 !
-no ip routing
+ip routing
 no ip routing vrf management
+!
+router bgp 65000
+   distance bgp 20 200 200
+   maximum-paths 4 ecmp 64
+   neighbor EBGP-TO-LEAF peer-group
+   neighbor EBGP-TO-LEAF remote-as 65100
+   neighbor EBGP-TO-LEAF maximum-routes 12000 
+   neighbor 172.16.0.10 peer-group EBGP-TO-LEAF
+   neighbor 172.16.0.14 peer-group EBGP-TO-LEAF
+   network 192.168.0.2/32
 !
 management api http-commands
    protocol http
leaf-1 Diffs: 

@@ -21,11 +21,26 @@
 !
 clock timezone America/New_York
 !
+vlan 100
+   name Servers1
+!
 vrf definition management
 !
 interface Ethernet1
+   description P2P Link to Spine-1
+   mtu 9214
+   logging event link-status
+   no switchport
+   ip address 172.16.0.2/30
+   arp timeout 900
 !
 interface Ethernet2
+   description P2P Link to Spine-2
+   mtu 9214
+   logging event link-status
+   no switchport
+   ip address 172.16.0.10/30
+   arp timeout 900
 !
 interface Ethernet3
 !
@@ -40,6 +55,10 @@
 interface Ethernet8
 !
 interface Ethernet9
+   switchport access vlan 100
+   no snmp trap link-status
+   spanning-tree portfast
+   spanning-tree bpduguard enable
 !
 interface Ethernet10
 !
@@ -47,14 +66,42 @@
 !
 interface Ethernet12
 !
+interface Loopback0
+   ip address 192.168.0.3/32
+!
 interface Management1
    vrf forwarding management
    ip address 198.51.100.252/24
 !
+interface Vlan100
+   description Servers1
+   mtu 9214
+   ip address 10.1.100.1/24
+   arp timeout 900
+!
 ip route vrf management 0.0.0.0/0 198.51.100.1
 !
-no ip routing
+ip routing
 no ip routing vrf management
+!
+ip prefix-list PREFIX-LIST-OUT seq 10 permit 192.168.0.3/32
+ip prefix-list PREFIX-LIST-OUT seq 20 permit 172.16.0.0/16
+ip prefix-list PREFIX-LIST-OUT seq 30 permit 10.1.100.0/24
+!
+route-map ROUTE-MAP-OUT permit 10
+   match ip address prefix-list PREFIX-LIST-OUT
+!
+router bgp 65100
+   distance bgp 20 200 200
+   maximum-paths 4 ecmp 4
+   neighbor EBGP-TO-SPINE peer-group
+   neighbor EBGP-TO-SPINE remote-as 65000
+   neighbor EBGP-TO-SPINE allowas-in 1
+   neighbor EBGP-TO-SPINE maximum-routes 12000 
+   neighbor 172.16.0.1 peer-group EBGP-TO-SPINE
+   neighbor 172.16.0.9 peer-group EBGP-TO-SPINE
+   network 192.168.0.3/32
+   redistribute connected
 !
 management api http-commands
    protocol http
leaf-2 Diffs: 

@@ -21,11 +21,26 @@
 !
 clock timezone America/New_York
 !
+vlan 100
+   name Servers1
+!
 vrf definition management
 !
 interface Ethernet1
+   description P2P Link to Spine-1
+   mtu 9214
+   logging event link-status
+   no switchport
+   ip address 172.16.0.6/30
+   arp timeout 900
 !
 interface Ethernet2
+   description P2P Link to Spine-2
+   mtu 9214
+   logging event link-status
+   no switchport
+   ip address 172.16.0.14/30
+   arp timeout 900
 !
 interface Ethernet3
 !
@@ -40,6 +55,10 @@
 interface Ethernet8
 !
 interface Ethernet9
+   switchport access vlan 100
+   no snmp trap link-status
+   spanning-tree portfast
+   spanning-tree bpduguard enable
 !
 interface Ethernet10
 !
@@ -47,14 +66,42 @@
 !
 interface Ethernet12
 !
+interface Loopback0
+   ip address 192.168.0.4/32
+!
 interface Management1
    vrf forwarding management
    ip address 198.51.100.251/24
 !
+interface Vlan100
+   description Servers1
+   mtu 9214
+   ip address 10.2.100.1/24
+   arp timeout 900
+!
 ip route vrf management 0.0.0.0/0 198.51.100.1
 !
-no ip routing
+ip routing
 no ip routing vrf management
+!
+ip prefix-list PREFIX-LIST-OUT seq 10 permit 192.168.0.4/32
+ip prefix-list PREFIX-LIST-OUT seq 20 permit 172.16.0.0/16
+ip prefix-list PREFIX-LIST-OUT seq 30 permit 10.2.100.0/24
+!
+route-map ROUTE-MAP-OUT permit 10
+   match ip address prefix-list PREFIX-LIST-OUT
+!
+router bgp 65100
+   distance bgp 20 200 200
+   maximum-paths 4 ecmp 4
+   neighbor EBGP-TO-SPINE peer-group
+   neighbor EBGP-TO-SPINE remote-as 65000
+   neighbor EBGP-TO-SPINE allowas-in 1
+   neighbor EBGP-TO-SPINE maximum-routes 12000 
+   neighbor 172.16.0.5 peer-group EBGP-TO-SPINE
+   neighbor 172.16.0.13 peer-group EBGP-TO-SPINE
+   network 192.168.0.4/32
+   redistribute connected
 !
 management api http-commands
    protocol http

The function found diffs so it merged the configuration. So lets see if it all worked.

spine-1#show ip route bgp 

VRF: default
Codes: C - connected, S - static, K - kernel, 
       O - OSPF, IA - OSPF inter area, E1 - OSPF external type 1,
       E2 - OSPF external type 2, N1 - OSPF NSSA external type 1,
       N2 - OSPF NSSA external type2, B I - iBGP, B E - eBGP,
       R - RIP, I L1 - IS-IS level 1, I L2 - IS-IS level 2,
       O3 - OSPFv3, A B - BGP Aggregate, A O - OSPF Summary,
       NG - Nexthop Group Static Route, V - VXLAN Control Service,
       DH - Dhcp client installed default route

 B E    10.1.100.0/24 [20/0] via 172.16.0.2, Ethernet1
 B E    10.2.100.0/24 [20/0] via 172.16.0.6, Ethernet2
 B E    172.16.0.8/30 [20/0] via 172.16.0.2, Ethernet1
 B E    172.16.0.12/30 [20/0] via 172.16.0.6, Ethernet2
 B E    192.168.0.3/32 [20/0] via 172.16.0.2, Ethernet1
 B E    192.168.0.4/32 [20/0] via 172.16.0.6, Ethernet2
spine-2#show ip route bgp 

VRF: default
Codes: C - connected, S - static, K - kernel, 
       O - OSPF, IA - OSPF inter area, E1 - OSPF external type 1,
       E2 - OSPF external type 2, N1 - OSPF NSSA external type 1,
       N2 - OSPF NSSA external type2, B I - iBGP, B E - eBGP,
       R - RIP, I L1 - IS-IS level 1, I L2 - IS-IS level 2,
       O3 - OSPFv3, A B - BGP Aggregate, A O - OSPF Summary,
       NG - Nexthop Group Static Route, V - VXLAN Control Service,
       DH - Dhcp client installed default route

 B E    10.1.100.0/24 [20/0] via 172.16.0.10, Ethernet1
 B E    10.2.100.0/24 [20/0] via 172.16.0.14, Ethernet2
 B E    172.16.0.0/30 [20/0] via 172.16.0.10, Ethernet1
 B E    172.16.0.4/30 [20/0] via 172.16.0.14, Ethernet2
 B E    192.168.0.3/32 [20/0] via 172.16.0.10, Ethernet1
 B E    192.168.0.4/32 [20/0] via 172.16.0.14, Ethernet2
spine-2#show ip route bgp 

VRF: default
Codes: C - connected, S - static, K - kernel, 
       O - OSPF, IA - OSPF inter area, E1 - OSPF external type 1,
       E2 - OSPF external type 2, N1 - OSPF NSSA external type 1,
       N2 - OSPF NSSA external type2, B I - iBGP, B E - eBGP,
       R - RIP, I L1 - IS-IS level 1, I L2 - IS-IS level 2,
       O3 - OSPFv3, A B - BGP Aggregate, A O - OSPF Summary,
       NG - Nexthop Group Static Route, V - VXLAN Control Service,
       DH - Dhcp client installed default route

 B E    10.1.100.0/24 [20/0] via 172.16.0.10, Ethernet1
 B E    10.2.100.0/24 [20/0] via 172.16.0.14, Ethernet2
 B E    172.16.0.0/30 [20/0] via 172.16.0.10, Ethernet1
 B E    172.16.0.4/30 [20/0] via 172.16.0.14, Ethernet2
 B E    192.168.0.3/32 [20/0] via 172.16.0.10, Ethernet1
 B E    192.168.0.4/32 [20/0] via 172.16.0.14, Ethernet2
spine-2#show ip route bgp 

VRF: default
Codes: C - connected, S - static, K - kernel, 
       O - OSPF, IA - OSPF inter area, E1 - OSPF external type 1,
       E2 - OSPF external type 2, N1 - OSPF NSSA external type 1,
       N2 - OSPF NSSA external type2, B I - iBGP, B E - eBGP,
       R - RIP, I L1 - IS-IS level 1, I L2 - IS-IS level 2,
       O3 - OSPFv3, A B - BGP Aggregate, A O - OSPF Summary,
       NG - Nexthop Group Static Route, V - VXLAN Control Service,
       DH - Dhcp client installed default route

 B E    10.1.100.0/24 [20/0] via 172.16.0.10, Ethernet1
 B E    10.2.100.0/24 [20/0] via 172.16.0.14, Ethernet2
 B E    172.16.0.0/30 [20/0] via 172.16.0.10, Ethernet1
 B E    172.16.0.4/30 [20/0] via 172.16.0.14, Ethernet2
 B E    192.168.0.3/32 [20/0] via 172.16.0.10, Ethernet1
 B E    192.168.0.4/32 [20/0] via 172.16.0.14, Ethernet2

For completeness.

leaf-1#ping 10.2.100.1 source 10.1.100.1
PING 10.2.100.1 (10.2.100.1) from 10.1.100.1 : 72(100) bytes of data.
80 bytes from 10.2.100.1: icmp_seq=1 ttl=63 time=22.2 ms
80 bytes from 10.2.100.1: icmp_seq=2 ttl=63 time=25.5 ms
80 bytes from 10.2.100.1: icmp_seq=3 ttl=63 time=27.6 ms
80 bytes from 10.2.100.1: icmp_seq=4 ttl=63 time=24.7 ms
80 bytes from 10.2.100.1: icmp_seq=5 ttl=63 time=19.8 ms

--- 10.2.100.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 92ms
rtt min/avg/max/mdev = 19.846/24.004/27.610/2.692 ms, pipe 2, ipg/ewma 23.103/2s

If we run the function again nothing will happen because there are no diffs. In the next post we are going to add a new vlan to the leaf switches. The code for this part can be found here.