본문 바로가기

IT 이야기/네트워크(Network)

다수의 Cisco Switch Configuration Backup 을 위한 Python Script

728x90
반응형
import paramiko
from datetime import datetime
import os
import getpass
import sys
import time
import subprocess
from concurrent.futures import ThreadPoolExecutor

# 경로 설정
current_directory = (
    os.path.dirname(sys.executable) if getattr(sys, "frozen", False) else os.path.dirname(__file__)
)
BACKUP_DIR = os.path.join(current_directory, "backup", "switch_configs")
LOG_FILE = os.path.join(current_directory, "backup", f"switch_backup_{datetime.now().strftime('%Y%m%d')}.log")
SWITCH_LIST = "switch_list.txt"

# 사용자 입력
print("Enter credentials for accessing switches:")
username = input("Username: ")
password = getpass.getpass("Password: ")
enable_password = getpass.getpass("Enable Password (leave blank if not needed): ")

# 성공 및 실패 목록
success_list = []
failure_list = []

# 로그 기록 함수
def write_log(message):
    with open(LOG_FILE, "a", encoding="utf-8") as log_file:
        log_file.write(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - {message}\n")

# 백업 디렉토리 생성
os.makedirs(BACKUP_DIR, exist_ok=True)

# 초기화된 로그 파일 생성
with open(LOG_FILE, "w", encoding="utf-8") as log_file:
    log_file.write("Switch Backup Log\n==================\n")

# Ping 함수
def ping(ip):
    try:
        result = subprocess.run(["ping", "-n", "3", ip], capture_output=True, text=True, timeout=10)
        return result.returncode == 0
    except subprocess.TimeoutExpired:
        return False

# 긴 출력 데이터를 가져오는 함수
def get_full_output(shell, timeout=180):
    buffer_size = 65535
    output = b""
    start_time = time.time()
    while time.time() - start_time < timeout:
        if shell.recv_ready():
            recv = shell.recv(buffer_size)
            output += recv
            if b"--More--" in recv:
                shell.send(" ")  # 다음 페이지 요청
                time.sleep(0.5)
            elif recv.strip().endswith(b"#") or recv.strip().endswith(b">"):
                break  # 출력 종료 조건
        else:
            time.sleep(0.5)
    return output.decode("utf-8", errors="ignore")

# NX-OS 여부 확인 함수
def is_nxos_device(shell):
    shell.send("show version\n")
    output = get_full_output(shell, timeout=10)
    return "NX-OS" in output or "Cisco Nexus" in output

# 백업 처리 함수
def backup_switch(ip):
    try:
        if not ping(ip):
            write_log(f"Ping failed for {ip}. Skipping backup.")
            failure_list.append(ip)
            return

        write_log(f"Connecting to {ip}...")
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(ip, username=username, password=password, timeout=10)

        shell = ssh.invoke_shell()
        time.sleep(3)  # 초기 배너 대기
        get_full_output(shell, timeout=10)  # 초기 배너 제거

        is_nxos = is_nxos_device(shell)
        device_type = "NX-OS" if is_nxos else "Non-NX-OS"
        write_log(f"{device_type} device detected: {ip}")

        shell.send("terminal length 0\n")
        time.sleep(2)
        get_full_output(shell, timeout=10)  # 적용 결과 제거

        shell.send("show running-config\n")
        output = get_full_output(shell, timeout=180)

        if ">" in output:  # Enable 모드 확인
            write_log(f"Entering enable mode for {ip}...")
            shell.send("enable\n")
            shell.send(f"{enable_password}\n")
            time.sleep(3)
            shell.send("terminal length 0\n")
            time.sleep(2)
            get_full_output(shell, timeout=10)  # 적용 결과 제거
            shell.send("show running-config\n")
            output = get_full_output(shell, timeout=180)

        backup_file = os.path.join(BACKUP_DIR, f"config_{ip}_{datetime.now().strftime('%Y%m%d')}.txt")
        with open(backup_file, "w", encoding="utf-8") as f:
            f.write(output)

        write_log(f"Backup completed for {ip}: {backup_file}")
        success_list.append(ip)
    except Exception as e:
        write_log(f"Failed to backup {ip}: {e}")
        failure_list.append(ip)
    finally:
        try:
            ssh.close()
        except:
            pass

# 병렬 백업 수행
with open(SWITCH_LIST, "r") as file:
    ips = [line.strip() for line in file]

with ThreadPoolExecutor(max_workers=10) as executor:
    executor.map(backup_switch, ips)

# 백업 결과 요약
write_log("\nBackup Summary:")
write_log(f"Successful backups: {len(success_list)}")
for ip in success_list:
    write_log(f"  - {ip}")

write_log(f"Failed backups: {len(failure_list)}")
for ip in failure_list:
    write_log(f"  - {ip}")

print("All backups completed. Check the log file for details.")

 

스크립트 설명 및 사용방법

1. 주요 기능

이 스크립트는 네트워크 장치(특히 Cisco 스위치 및 라우터)의 실시간 설정(런닝-컨피그) 백업을 자동으로 수행하는 Python 프로그램입니다. 주요 기능은 다음과 같습니다:
• 병렬 백업: 여러 장치를 동시에 백업하여 작업 시간을 단축합니다.
• NX-OS와 Non-NX-OS 장치 지원: Cisco NX-OS 및 기타 장치에서 설정을 가져올 수 있습니다.
• Ping 체크: 장치에 접속하기 전에 네트워크 연결 상태를 확인합니다.
• 긴 출력 자동 처리: --More--로 나뉜 긴 출력도 문제없이 처리합니다.
• 로그 기록: 백업 성공 및 실패 결과를 파일에 기록합니다.
• 자동 백업 파일 저장: 장치별로 백업 파일을 생성하고 날짜를 포함하여 저장합니다.

2. 스크립트 파일 구성

• 백업 파일 저장 경로:
• backup/switch_configs 디렉토리에 장치별 백업 파일이 저장됩니다.
• 파일 이름 형식은 config_<IP>_<날짜>.txt입니다.
• 로그 파일 경로:
• backup/switch_backup_<날짜>.log 파일에 실행 기록 및 백업 결과가 저장됩니다.
• 장치 목록 파일:
• switch_list.txt 파일에 백업할 장치 IP를 한 줄씩 작성합니다.

3. 사용방법

1. 필요 파일 준비:
• 스크립트와 같은 디렉토리에 switch_list.txt 파일을 생성하고, 백업하려는 장치의 IP 주소를 한 줄씩 작성합니다.

192.168.1.1
192.168.1.2
192.168.1.3


2. Python 실행 환경 확인:
• 이 스크립트는 Python 3.x 환경에서 실행됩니다.
• paramiko와 같은 필수 패키지를 설치해야 합니다.

pip install paramiko


3. 스크립트 실행:
• 스크립트를 실행합니다.

python switch_backup.py


• 실행 시 사용자 계정 정보를 입력해야 합니다:

Enter credentials for accessing switches:
Username: <사용자 이름>
Password: <비밀번호>
Enable Password (leave blank if not needed): <Enable 비밀번호>


4. 결과 확인:
• 백업된 설정은 backup/switch_configs 폴더에 저장됩니다.
• 실행 로그 및 성공/실패 목록은 backup/switch_backup_<날짜>.log 파일에서 확인 가능합니다.

4. 스크립트의 주요 처리 흐름

1. 사용자 입력:
• Username, Password, Enable Password를 입력받아 스크립트가 장치에 접속하는 데 사용합니다.
2. 장치 연결 전 Ping 확인:
• 장치 IP가 ping 응답을 반환하는지 확인하여 네트워크 연결 상태를 점검합니다.
3. SSH 연결 및 설정 백업:
• paramiko를 사용하여 장치에 SSH로 연결합니다.
• NX-OS 여부를 확인하고 show running-config 명령어를 실행하여 결과를 가져옵니다.
• 긴 출력(--More--)은 자동으로 처리됩니다.
4. 백업 파일 저장:
• 장치 IP와 날짜를 포함하여 백업 파일을 생성하고 설정 데이터를 저장합니다.
5. 로그 기록:
• 실행 과정에서 발생한 모든 로그(성공/실패)를 기록합니다.
• 최종적으로 성공 및 실패한 IP 목록을 요약하여 출력합니다.

5. 예제 로그

로그 파일(switch_backup_<날짜>.log)의 예제는 아래와 같습니다:

2024-11-27 14:30:45 - Connecting to 192.168.1.1...
2024-11-27 14:30:50 - NX-OS device detected: 192.168.1.1
2024-11-27 14:31:05 - Backup completed for 192.168.1.1: backup/switch_configs/config_192.168.1.1_20241127.txt
2024-11-27 14:31:06 - Connecting to 192.168.1.2...
2024-11-27 14:31:11 - Ping failed for 192.168.1.2. Skipping backup.

Backup Summary:
Successful backups: 1
  - 192.168.1.1
Failed backups: 1
  - 192.168.1.2

6. 요구사항 및 주의사항

• 필수 패키지:
• Python 패키지 paramiko와 concurrent.futures를 사용합니다.
• 필요 시 pip install paramiko로 설치하십시오.
• NX-OS 및 기타 Cisco 장치 확인:
• NX-OS 장치와 그렇지 않은 장치를 자동으로 감지하고 필요한 작업을 수행합니다.
• Enable 모드 처리:
• 설정 백업 시 Enable 모드가 필요한 경우 비밀번호를 입력받아 처리합니다.
• 병렬 처리:
• 기본적으로 최대 10개의 장치를 동시에 처리하며, 네트워크 상황에 따라 적절히 조정할 수 있습니다.

결론

이 스크립트는 네트워크 엔지니어가 여러 장치의 설정을 쉽고 효율적으로 백업하도록 설계되었습니다.
자동화와 병렬 처리 덕분에 시간을 절약하고, 모든 과정을 로그로 기록하여 작업 상태를 투명하게 관리할 수 있습니다.

728x90
반응형