본문 바로가기
Python

R&S 파이썬 자동화 개선판

by Ao1 2023. 3. 3.
script_v1.0.zip
0.00MB


#-------------------------------------------#
#                                           #
#        Network Script tool                #
#          Version 3.1.2                    #
#         Make Jo Sung Jin                  #
#                                           #
#-------------------------------------------#

import paramiko
import telnetlib
import socket
import time
import os
import pandas as pd
from io import StringIO
import threading
import argparse

parser = argparse.ArgumentParser(description='Use config auto Script')

# 입력받을 인자값 등록
parser.add_argument('-ti', metavar='[Tacas_id]', required=True, help='TACAS ID', type=str)
parser.add_argument('-tp', metavar='[Tacas_pw]', required=True, help='TACAS PW', type=str)
parser.add_argument('-id', metavar='[Local_id]', required=True, help='Local ID', type=str)
parser.add_argument('-pw', metavar='[Local_pw]', required=True, help='Local PW', type=str)
parser.add_argument('-p', metavar='[File_path]', required=True, help='File path', type=str)
parser.add_argument('-c', metavar='[Command]', required=True, help='Command', type=str)

# 입력받은 인자값을 args에 저장 (type: namespace)
args = parser.parse_args()

ID = args.ti            # TACAS ID
PASSWD = args.tp        # TACAS PASSWORD

LOCAL_ID = args.id              # LOCAL ID
LOCAL_PASSWD = args.pw          # LOCAL PASSWORD

XLSX_FILE_NAME = args.p         # xlsx file name exe) Test.xlsx

command = args.c                # Command Value

cmd = command.split(',')


# SSH 연결
def ssh_connect(HOST,Num,pid,pwd,ck):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    try:
        ssh.connect(HOST, username=pid, password=pwd,allow_agent=False,look_for_keys=False)
        shell = ssh.invoke_shell()
       
        time.sleep(1)
       
        ck0 = shell.recv(1024).decode(encoding='utf-8')
        if '>' in str(ck0):
            shell.send('en\n')
            time.sleep(1)

            ck1 = shell.recv(1024).decode(encoding='utf-8')
            if ':' in str(ck1):
                shell.send(pwd + '\n')
                time.sleep(1)

        shell.send('\n')
        time.sleep(1)
       
        ck2 = shell.recv(1024).decode(encoding='utf-8')
        if '#' in str(ck2):
            for i in range(0,len(cmd)):
                shell.send(cmd[i] + '\n')
                time.sleep(1)
           
        time.sleep(1)
       
        output = shell.recv(1024000).decode(encoding='utf-8')
        cnt = 0
             
        while True:
            time.sleep(3)
            if shell.recv_ready():
                globals()["output{}".format(cnt)] = shell.recv(1024000).decode(encoding='utf-8')
                cnt += 1
            else:
                break

        time.sleep(5)
       
        shell.close()
        ssh.close()

        ssh_log = ""
        ssh_log += str(output).replace('\r\n','\n')
        for i in range(0,cnt):
            ssh_log += str(globals()["output{}".format(i)]).replace('\r\n','\n')
           
        create_log(Num,ssh_log)

    except:
        if ck == 0:
            time.sleep(20)
            ssh_connect(HOST,Num,LOCAL_ID,LOCAL_PASSWD,ck+1)     # 실패 시 SSH Local 계정으로 연결
        elif ck == 1:
            Telnet_connect(HOST,Num,ID,PASSWD,ck+1) # ssh 실패 시 telet Tacacs 연결
        elif ck == 2:
            Telnet_connect(HOST,Num,LOCAL_ID,LOCAL_PASSWD,ck+1) # telet Tacacs 실패 시 telet Local 연결
        else:
            error_log(Num)

# TELNET 연결
def Telnet_connect(HOST,Num,pid,pwd,ck):  
    try:
        tn = telnetlib.Telnet(HOST)

        tn.read_until(b"User",timeout=20)
        tn.write(pid.encode('ascii') + b'\n')
        tn.read_until(b"assword",timeout=20)
        tn.write(pwd.encode('ascii') + b'\n')

        result = tn.read_until(b'User',timeout=20)
       
        tn.write(b' ' + b'\n')

        if ('>' in str(result)) or ('#' in str(result)):
            en_ck = tn.read_until(b'>',timeout=20)
            if '>' in str(en_ck):
                tn.write(b'en\n')
               
                en_ps = tn.read_until(b"assword",timeout=20)
                if 'assword' in str(en_ps):
                    tn.write(pwd.encode('ascii') + b'\n')

            tn.write(b'\n')      
            en_ck = tn.read_until(b'#',timeout=20)
            if '#' in str(en_ck):
                for i in range(0,len(cmd)):
                    tn.write(cmd[i].encode('ascii') + b'\n')

            time.sleep(20)

            tn.write(b'quit\n')
            tn.write(b'quit\n')
                   
            telnet_log = tn.read_all().decode('ascii')
            telnet_log0 = telnet_log.replace('\r\n','\n')
            create_log(Num,telnet_log0)

            tn.close()

        else:
            try:
                Telnet_connect(HOST,Num,LOCAL_ID,LOCAL_PASSWD,ck+1)
            except Exception:
                error_log(Num)

    except Exception:
        error_log(Num)
       
# SSH 로그 값 가공
def ssh_log_gen(*Str):
    io = StringIO()
    print(*Str, file=io, sep='\n')
    return io.getvalue()

# 성공 시 로그 생성
def create_log(num,l_log):
    f_log = open(PATH + '/' + HOSTNAME[num]+".log",mode='a',encoding='utf-8')
    f_log.write(l_log)

# 실패 시 로그 생성
def error_log(err_num):
    f_err = open(PATH + '/error.log',mode='a',encoding='utf-8')
    f_err.write(HOSTNAME[err_num] + ' ' + HOST[err_num] + '\n')

# 디렉토리 생성
def createDir(DIR):
    if not os.path.exists(DIR):
        os.makedirs(DIR)

# 메인 엔진
def xlsx_read(FILE,threadnum):

    global HOSTNAME
    global HOST
    global PATH

    f_xlsx = pd.read_excel(FILE, engine = "openpyxl", sheet_name=0)

    HOSTNAME = f_xlsx['HOSTNAME']
    HOST = f_xlsx['HOST']

    PATH = '../Log' + '(' + str(len(HOST)) + ')'
    createDir(PATH)

    try:
        count = 0
        ck = 0
        while count < len(HOST):
            for j in range(1):
                threading.Thread(target=ssh_connect, args=(str(HOST[count]),count,ID,PASSWD,ck)).start()
                time.sleep(1.5)
                count += 1
    except Exception:
        pass
           
xlsx_read(XLSX_FILE_NAME,10)