NAPALM - 네트워크 추상화 라이브러리

23 조회 2025-11-17 오픈소스 도구
GitHub 문서

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/