Profile picture

[Python] Paramiko 라이브러리를 활용한 SSH 업무 자동화

JaehyoJJAng2023년 02월 28일

라이브러리 설치하기

필수 라이브러리

  • paramiko 2.5.0

스크립트 작동 환경

  • Ubuntu 20.04 LTS

Paramiko 라이브러리 설치

$ ~/PycharmProject/ && source ./venv/bin/activate

$  pip install --upgrade pip; pip install paramiko

파이썬 스크립트로 SSH 명령어 수행

SSH 접속하기

def connecting(self):
    """ SSH 접속 메서드 """
    try:
        # SSHClient Instance
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)
        ssh.connect(get_secrets(key='ip'),port=get_secrets(key='port'),username=get_secrets(key='username'),password=get_secrets(key='password'))
        print(f"{datetime.datetime.now().strftime('%Y-%m-%d %H:%M')} : SSH CONNECTED")

        return ssh

    except Exception as err:
        print(f'Error!\n{err}')

명령 실행하기

def execute_command(self,ssh):
    """ 명령어 실행 메서드 """
    # SSH 접속 클라이언트 루트디렉토리 경로의 파일 리스트 확인
    stdin, stdout, stderr = ssh.exec_command("ls -l /")

    lines : list = stdout.readlines()
    for line in lines:
        print(line.replace('\n',''))

파일 업로드하기

def file_upload(self,ssh):
    """ 파일 업로드 메서드 """
    try :
        # sftp 객체 생성
        sftp = ssh.open_sftp()

        # 업로드 할 파일 경로 지정
        path = os.path.dirname(os.path.abspath(__file__)) + '/secrets'
        
        # 파일 업로드
        sftp.put(f'{os.path.join(path,".conn_info.json")}','/home/user-01/conn_info.json')
        print(f'sftp upload Success!.\n')

    except Exception as err:
        print(f'File Upload Error!\n{err}')

파일 다운로드하기

def file_download(self,ssh):
    """ 파일 다운로드 메서드 """
    try:
        # sftp 객체 생성
        sftp = ssh.open_sftp()

        # 경로 없는 경우 생성
        path = './download'
        if not os.path.exists(path):
            os.mkdir(path)

        # 다운로드
        sftp.get('/home/user-01/conn_info.json',os.path.join(path,'.conn_info.json'))
        print(f'sftp Download Success!.\n')

    except Exception as err:
        print(f'File Download Error!\n{err}')

위 내용을 응용하여 리눅스 서버 용량 체크하기

마운트 용량 체크 스크립트 작성

def execute_command(self,ssh):
    """ 명령어 실행 메서드 """
    stdin, stdout, stderr = ssh.exec_command("df -h")

    lines : list = stdout.readlines()

    datas = list()
    for line in lines:
        dic = dict()

        # 맨 첫 행 continue 처리
        if re.match('[A-Z]',line):
            continue

        all_lines =  [all_line for all_line in str(line.replace('\n','')).split(' ') if all_line]

        # 사용량
        dic['used'] = all_lines[-2]

        # 마운트 위치
        dic['mountd'] = all_lines[-1]

        datas.append(dic)

    [print(data) for data in datas]

결과

$ python3 main.py
------------------------------------------------------------------
2022-12-01 14:45 : SSH CONNECTED
{'used': '0%', 'mountd': '/dev'}
{'used': '1%', 'mountd': '/run'}
{'used': '13%', 'mountd': '/'}
{'used': '0%', 'mountd': '/dev/shm'}
{'used': '1%', 'mountd': '/run/lock'}
{'used': '0%', 'mountd': '/sys/fs/cgroup'}
{'used': '100%', 'mountd': '/snap/bare/5'}
{'used': '100%', 'mountd': '/snap/gnome-3-38-2004/119'}
{'used': '100%', 'mountd': '/snap/core20/1695'}
{'used': '100%', 'mountd': '/snap/core18/1988'}
{'used': '100%', 'mountd': '/snap/core18/2632'}
{'used': '100%', 'mountd': '/snap/gnome-3-34-1804/66'}
{'used': '100%', 'mountd': '/snap/gnome-3-34-1804/77'}
{'used': '100%', 'mountd': '/snap/snap-store/638'}
{'used': '100%', 'mountd': '/snap/snap-store/599'}
{'used': '100%', 'mountd': '/snap/gtk-common-themes/1514'}
{'used': '100%', 'mountd': '/snap/gtk-common-themes/1535'}
{'used': '100%', 'mountd': '/snap/snapd/17883'}
{'used': '1%', 'mountd': '/mydata'}
{'used': '1%', 'mountd': '/boot/efi'}
{'used': '1%', 'mountd': '/run/user/125'}
{'used': '1%', 'mountd': '/run/user/1000'}
------------------------------------------------------------------

Loading script...