NAPALM - 네트워크 추상화 및 프로그래밍 레이어
개요
NAPALM(Network Automation and Programmability Abstraction Layer with Multivendor support)은 서로 다른 네트워크 장비 벤더의 API를 통일된 방식으로 사용할 수 있게 해주는 Python 라이브러리입니다.
핵심 개념
벤더 중립적 API
from napalm import get_network_driver
# Cisco IOS
driver_ios = get_network_driver('ios')
device_ios = driver_ios('192.168.1.1', 'admin', 'password')
# Juniper Junos
driver_junos = get_network_driver('junos')
device_junos = driver_junos('192.168.1.2', 'admin', 'password')
# 동일한 메서드로 정보 조회
device_ios.open()
facts_ios = device_ios.get_facts()
device_junos.open()
facts_junos = device_junos.get_facts()
# 결과 형식이 동일함!
지원 플랫폼
Core Drivers
- IOS - Cisco IOS
- NXOS - Cisco Nexus
- IOS-XR - Cisco IOS-XR
- EOS - Arista EOS
- JunOS - Juniper Junos
Community Drivers
- Huawei VRP
- Nokia SR OS
- Fortinet FortiOS
- Palo Alto PAN-OS
- Dell OS10
- MikroTik RouterOS
주요 기능 (Getters)
1. get_facts()
device.open()
facts = device.get_facts()
# 출력 예시 (모든 벤더 동일)
{
'hostname': 'router1',
'fqdn': 'router1.example.com',
'vendor': 'Cisco',
'model': 'ISR4451',
'serial_number': 'FDO1234A5B6',
'os_version': '16.9.5',
'uptime': 8924820,
'interface_list': ['Gi0/0/0', 'Gi0/0/1', 'Gi0/0/2']
}
2. get_interfaces()
interfaces = device.get_interfaces()
# 출력
{
'GigabitEthernet0/0/0': {
'is_up': True,
'is_enabled': True,
'description': 'To Core Switch',
'last_flapped': 1609459200.0,
'speed': 1000,
'mtu': 1500,
'mac_address': '00:50:56:12:34:56'
},
...
}
3. get_bgp_neighbors()
bgp = device.get_bgp_neighbors()
{
'global': {
'router_id': '10.0.0.1',
'peers': {
'10.0.0.2': {
'local_as': 65001,
'remote_as': 65002,
'remote_id': '10.0.0.2',
'is_up': True,
'is_enabled': True,
'description': 'PEER-AS65002',
'uptime': 86400,
'address_family': {
'ipv4': {
'received_prefixes': 150,
'accepted_prefixes': 150,
'sent_prefixes': 100
}
}
}
}
}
}
4. 기타 Getters
get_arp_table()- ARP 테이블get_lldp_neighbors()- LLDP 정보get_mac_address_table()- MAC 주소 테이블get_route_to()- 라우팅 정보get_snmp_information()- SNMP 설정get_users()- 사용자 계정get_vlans()- VLAN 정보get_config()- 설정 파일
설정 관리
1. 설정 비교
device.load_merge_candidate(filename='new_config.txt')
# 변경 사항 미리보기
diff = device.compare_config()
print(diff)
# 적용 또는 롤백
if user_confirms:
device.commit_config()
else:
device.discard_config()
2. Replace vs Merge
# Merge: 기존 설정에 추가
device.load_merge_candidate(config='interface Gi0/0
description New Description')
# Replace: 전체 설정 교체
device.load_replace_candidate(filename='full_config.txt')
device.commit_config()
3. 롤백
# 변경사항 롤백
device.rollback()
실전 예제
멀티 벤더 설정 백업
from napalm import get_network_driver
import json
devices = [
{'driver': 'ios', 'host': '192.168.1.1', 'vendor': 'cisco'},
{'driver': 'junos', 'host': '192.168.1.2', 'vendor': 'juniper'},
{'driver': 'eos', 'host': '192.168.1.3', 'vendor': 'arista'},
]
for dev_info in devices:
driver = get_network_driver(dev_info['driver'])
device = driver(
hostname=dev_info['host'],
username='admin',
password='password'
)
device.open()
# Facts 백업
facts = device.get_facts()
with open(f"{dev_info['vendor']}_facts.json", 'w') as f:
json.dump(facts, f, indent=2)
# Config 백업
config = device.get_config()
with open(f"{dev_info['vendor']}_config.txt", 'w') as f:
f.write(config['running'])
device.close()
print(f"✓ {dev_info['vendor']} 백업 완료")
컴플라이언스 체크
def check_compliance(device):
"""보안 설정 점검"""
issues = []
# 인터페이스 체크
interfaces = device.get_interfaces()
for intf, data in interfaces.items():
if data['is_enabled'] and not data['description']:
issues.append(f"{intf} has no description")
# SNMP 체크
snmp = device.get_snmp_information()
if 'public' in snmp.get('community', {}):
issues.append("Default SNMP community 'public' in use")
# 사용자 체크
users = device.get_users()
if 'admin' in users and users['admin']['level'] == 15:
issues.append("Default admin account exists")
return issues
# 모든 장비 점검
for device in all_devices:
device.open()
issues = check_compliance(device)
if issues:
print(f"
{device.hostname} - Issues found:")
for issue in issues:
print(f" ⚠ {issue}")
device.close()
자동화된 설정 변경 (Dry-Run 포함)
from napalm import get_network_driver
config_template = """
interface {interface}
description {description}
ip address {ip_address} {netmask}
no shutdown
"""
devices_to_configure = [
{
'host': '192.168.1.1',
'interface': 'GigabitEthernet0/1',
'description': 'Link to Core',
'ip_address': '10.1.1.1',
'netmask': '255.255.255.0'
},
# ... more devices
]
for dev in devices_to_configure:
driver = get_network_driver('ios')
device = driver(dev['host'], 'admin', 'password')
device.open()
# 설정 생성
config = config_template.format(**dev)
# 설정 로드 (아직 적용 안됨)
device.load_merge_candidate(config=config)
# Diff 확인
diff = device.compare_config()
print(f"
{'='*60}")
print(f"Device: {dev['host']}")
print(f"{'='*60}")
print(diff)
# 사용자 승인
response = input("
Apply this configuration? (yes/no): ")
if response.lower() == 'yes':
device.commit_config()
print("✓ Configuration applied")
else:
device.discard_config()
print("✗ Configuration discarded")
device.close()
Ansible 통합
- name: Get device facts using NAPALM
napalm_get_facts:
hostname: "{{ inventory_hostname }}"
username: "{{ username }}"
password: "{{ password }}"
dev_os: "{{ os }}"
filter:
- facts
- interfaces
register: result
- name: Display hostname
debug:
msg: "Hostname: {{ result.ansible_facts.napalm_facts.hostname }}"
설치
pip install napalm
장점
✓ 통일된 API로 멀티 벤더 관리 ✓ 구조화된 데이터 반환 (dict, list) ✓ 설정 변경 전 Diff 확인 가능 ✓ 롤백 기능 내장 ✓ Ansible, Salt, StackStorm 통합
단점
✗ 일부 벤더별 고유 기능 미지원 ✗ 드라이버마다 지원 기능 차이 ✗ 학습 곡선 존재
라이센스
Apache License 2.0
링크
- GitHub: https://github.com/napalm-automation/napalm
- 문서: https://napalm.readthedocs.io/
- PyPI: https://pypi.org/project/napalm/