파이썬 네트워크 자동화
Netmiko를 이용하여 다양한 연습을 하기 위해서 기존 랩이 아닌 새로운 랩을 다시 구성하였습니다. 기존에 랩은 각 밴더 별로 장비 한 대씩 구축했으나, ospf, bgp 등의 프로토콜을 구현하는데 제약이 있고, 추가로 Juniper image가 제대로 동작하지 않기 때문에 사용 가능한 cisco router, switch, 그리고 arista router을 주 장비로 구축했습니다.
파이썬 네트워크 자동화
가상 장비는 총 8대이고, cisco router image 3대, cisco switch image 2대, 마지막으로 arista image 3대로 정리했습니다. 위에 나와 있는 것은 management switch이며, 각 장비와 mgmt switch 간에 연결이 되어 있으나 network diagram을 보기 편하게 하기 위해서 보이지 않고 gns3에서 설정하였습니다.
각 장비 별 연결은 아래와 같이 되어 있습니다.
장비 구성은 "red", "blue" enterprise 네트워크와 "isp" 역할인 "as3356, as7922, as1299, as16509"로 구성했습니다.
각 장비 별로 기본 설정은 "https://brunch.co.kr/@bnetwork/6" 글에 있는 것 같이 최소한으로 설정했고, 각 인터페이스 설정을 "https://brunch.co.kr/@bnetwork/12" 글에 연습한 netmiko로 진행하였습니다.
그럼 netmiko를 가지고 어떻게 interface를 설정했는지 알아 보겠습니다.
각 장비 loopback 설정
각 인터페이스 설정
red-r1 <> red-s1 연결 설정
blue-r1 <> bule-s1 연결 설정
from netmiko import ConnectHandler
# defined by service type
blue = ["192.168.37.101", "192.168.37.102"]
red = ["192.168.37.111","192.168.37.112"]
as1299 = "192.168.37.201"
as7922 = "192.168.37.202"
as16509 = "192.168.37.203"
as3356 = "192.168.37.204"
jr1 = "192.168.37.10"
# deviced by vendor & role
cisco_routers = ["192.168.37.201", "192.168.37.202","192.168.37.203"]
cisco_switches = ["192.168.37.102","192.168.37.112"]
arista_routers = ["192.168.37.101", "192.168.37.111","192.168.37.204"]
juniper_routers = ["192.168.37.10"]
# as1299 config
as1299 = {
'device_type':'cisco_ios',
'ip':'192.168.37.201',
'username':'devnet',
'password':'dn1001',
}
print(" *** as1299 : Cisco Interface Configuration ***")
commands = [
'int lo0','desc as1299.lo0','ip add 12.12.12.12 255.255.255.255','no shut',
'int g0/0','desc to_server','no shut',
'int g0/1','desc to_as3356.e2','ip add 1.12.33.1 255.255.255.252','no shut',
'int g0/2','desc to_as16509.g0/3','ip add 1.12.16.1 255.255.255.252','no shut',
'int g0/3','desc to_blue_r1.e1','ip add 1.12.200.1 255.255.255.252','no shut',
]
net_connect = ConnectHandler(**as1299)
net_connect.send_config_set(commands)
output = net_connect.send_command("show ip int brief")
print(output)
print()
net_connect.disconnect()
# as7922 config
as7922 = {
'device_type':'cisco_ios',
'ip':'192.168.37.202',
'username':'devnet',
'password':'dn1001',
}
print(" *** as7922 : Cisco Interface Configuration ***")
commands = [
'int lo0','desc as7922.lo0','ip add 79.79.79.79 255.255.255.255','no shut',
'int g0/0','desc to_server','no shut',
'int g0/1','desc to_as3356.e1','ip add 1.33.79.2 255.255.255.252','no shut',
'int g0/2','desc to_as16509.g0/2','ip add 1.16.79.2 255.255.255.252','no shut',
'int g0/3','desc to_red_r1.e1','ip add 1.79.100.1 255.255.255.252','no shut',
]
net_connect = ConnectHandler(**as7922)
net_connect.send_config_set(commands)
output = net_connect.send_command("show ip int brief")
print(output)
print()
net_connect.disconnect()
# as16509 config
as16509 = {
'device_type':'cisco_ios',
'ip':'192.168.37.203',
'username':'devnet',
'password':'dn1001',
}
print(" *** as16509 : Cisco Interface Configuration ***")
commands = [
'int lo0','desc as16509.lo0','ip add 16.16.16.16 255.255.255.255','no shut',
'int g0/0','desc to_server','no shut',
'int g0/1','desc to_none','shut',
'int g0/2','desc to_as7922.g0/2','ip add 1.16.79.1 255.255.255.252','no shut',
'int g0/3','desc to_as1299.g0/2','ip add 1.12.16.2 255.255.255.252','no shut',
]
net_connect = ConnectHandler(**as16509)
net_connect.send_config_set(commands)
output = net_connect.send_command("show ip int brief")
print(output)
print()
net_connect.disconnect()
# as3356 Configuration
as3356 = {
'device_type':'arista_eos',
'ip':'192.168.37.204',
'username':'devnet',
'password':'dn1001',
}
print(" *** as3356 Interface Configuration ***")
net_connect = ConnectHandler(**as3356)
commands = ['int lo0','desc as3356.lo0','ip add 33.33.33.33/32',
'int et1','desc to_as7922.g0/1','no switchport','ip add 1.33.79.1/30',
'int et2','desc to_as1299.g0/1','no switchport','ip add 1.12.33.2/30',
'int et11','desc to_blue_r1.e2','no switchport','ip add 1.33.200.1/30',
'int et12','desc to_red_r1.e2','no switchport','ip add 1.33.100.1/30'
]
net_connect.enable()
net_connect.config_mode()
net_connect.send_config_set(commands,exit_config_mode=False)
output = net_connect.send_command('show ip int brief')
print(output)
print()
net_connect.disconnect()
# red_r1 Configuration
red_r1 = {
'device_type':'arista_eos',
'ip':'192.168.37.111',
'username':'devnet',
'password':'dn1001',
}
print(" *** red_r1 Interface Configuration ***")
net_connect = ConnectHandler(**red_r1)
commands = ['int lo0','desc red_r1.lo0','ip add 100.100.100.100/32',
'int et1','desc to_as7922.g0/3','no switchport','ip add 1.79.100.2/30',
'int et2','desc to_as3356.e12','no switchport','ip add 1.33.100.2/30',
'int et12','desc to_red-s1.g0/1','no switchport','ip add 192.168.100.1/24',
]
net_connect.enable()
net_connect.config_mode()
net_connect.send_config_set(commands,exit_config_mode=False)
output = net_connect.send_command('show ip int brief')
print(output)
print()
net_connect.disconnect()
# blue_r1 Configuration
blue_r1 = {
'device_type':'arista_eos',
'ip':'192.168.37.101',
'username':'devnet',
'password':'dn1001',
}
print(" *** blue_r1 Interface Configuration ***")
net_connect = ConnectHandler(**blue_r1)
commands = ['int lo0','desc blue_r1.lo0','ip add 200.200.200.200/32',
'int et1','desc to_as1299.g0/3','no switchport','ip add 1.12.200.2/30',
'int et2','desc to_as3356.e11','no switchport','ip add 1.33.200.2/30',
'int et12','desc to_blue-s1.g0/1','no switchport','ip add 192.168.200.1/24',
]
net_connect.enable()
net_connect.config_mode()
net_connect.send_config_set(commands,exit_config_mode=False)
output = net_connect.send_command('show ip int brief')
print(output)
print()
net_connect.disconnect()
# red_s1 config
red_s1 = {
'device_type':'cisco_ios',
'ip':'192.168.37.112',
'username':'devnet',
'password':'dn1001',
}
print(" *** red_s1 : Cisco Interface Configuration ***")
commands = [
'int lo0','desc red_s1.lo0',
'int g0/0','desc to_server','no shut',
'vlan 100','name mgmt-network','int vlan 100','ip add 192.168.100.2 255.255.255.0','no shut',
'int g0/1','switch mode acc','sw acc vlan 100','no shut'
]
net_connect = ConnectHandler(**red_s1)
net_connect.send_config_set(commands)
output = net_connect.send_command("show ip int brief")
print(output)
print()
net_connect.disconnect()
# blue_s1 config
blue_s1 = {
'device_type':'cisco_ios',
'ip':'192.168.37.102',
'username':'devnet',
'password':'dn1001',
}
print(" *** blue_s1 : Cisco Interface Configuration ***")
commands = [
'int lo0','desc blue_s1.lo0',
'int g0/0','desc to_server','no shut',
'vlan 100','name mgmt-network','int vlan 200','ip add 192.168.200.2 255.255.255.0','no shut',
'int g0/1','switch mode acc','sw acc vlan 200','no shut'
]
net_connect = ConnectHandler(**blue_s1)
net_connect.send_config_set(commands)
output = net_connect.send_command("show ip int brief")
print(output)
print()
net_connect.disconnect()
무식하게 동일한 내용을 반복하여 8대 장비의 interface 설정을 했지만, 글을 보시는 분들께서 시간이 있다면 for or while을 이용, 또는 함수를 이용해서 위 설정을 좀더 간단하게 만들어 보시는 것이 어떨까 생각 듭니다. 앞으로 변경된 랩을 이용하여 여러 가지 자동화 스크립트를 좀 더 만들 수 있도록 하겠습니다.