LoginSignup
13
28

More than 3 years have passed since last update.

サーバの運用管理をPythonで自動化させてみる

Last updated at Posted at 2019-04-25

サーバの運用管理業務では定型作業も少なくないと思うが、その自動化はどうしているだろう。
本番機とかでシェルスクリプトを自由に置けない場合、ターミナルソフト(PuTTY、Tera Term、Rlogin、etc...)が備えるマクロ機能で自動運転するのも良いが、ここではPythonで実現してみようと思う。

よくあるケース

  • サーバまたはネットワーク機器(Cisco IOS)でコマンドを実行し、結果をクライアント端末(Windows PC)にダウンロード
  • クライアント端末(Windows PC)からファイルをアップロードし、サーバまたはネットワーク機器(Cisco IOS)でコマンドを実行

というケースが殆どではないだろうか。
ここでは後者のサンプルコードを示す。

必要なパッケージ

SSHv2プロトコルのPython実装である Paramikoscp をクライアント端末に導入する。
サーバの環境変更には厳しいプロジェクトであっても、クライアント端末であれば自由が利く。

pip install paramiko
pip install scp

サンプルコード

ファイルをscpで転送し、sshでコマンドを実行する必要最小限のコード。
パスワード認証方式の場合は、pkeyの代わりにpasswordを指定すること。

import paramiko
import scp

def exec_cmd(cmd, ssh):
    print('# ' + cmd)
    stdin, stdout, stderr = ssh.exec_command(cmd)
    for out_line in stdout:
        print(out_line.strip('\n'))  # 標準出力
    for err_line in stderr:
        print(err_line.strip('\n'))  # 標準エラー出力

with paramiko.SSHClient() as ssh:
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    pkey = paramiko.RSAKey.from_private_key_file('秘密鍵ファイル')  # 今回はパスフレーズ無し
    ssh.connect(hostname='192.168.10.1', port=22, username='myuser', pkey=pkey)

    with scp.SCPClient(ssh.get_transport()) as scp:
        scp.put('foo.csv', '/tmp/foo.csv')  # ファイルをアップロード

    time.sleep(1)  # 念の為、待ち時間を挿入

    exec_cmd('./bar.sh /tmp/foo.csv', ssh)  # サーバでシェルを実行

おまけ

せっかくPythonで書くのだから、実行結果もメールで自動送信してみよう。
CSVファイルをメールに添付して送信するサンプルコードを示す。

import smtplib
from email import Encoders
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart

from_addr = 'XXXXX@gmail.com'
to_addr = 'YYYYY@aaaaa.co.jp'
bcc_addr = 'ZZZZZ@aaaaa.co.jp'  # カンマ区切りで複数指定可
rcpt = bcc_addr.split(',') + [to_addr]

msg = MIMEMultipart()
msg['Subject'] = '【XXサーバ】コマンド実行結果'
msg['From'] = '名無し'
msg['To'] = to_addr

msg.attach(MIMEText('''
関係各位
お疲れさまです。
本日のコマンド実行結果を添付しますのでご確認ください。
'''.strip())

attachment = MIMEBase('application', 'csv')  # 添付ファイルの種類に応じて適宜変更すること
file = open('/tmp/results.csv', 'rb+')
attachment.set_payload(file.read())
file.close()
Encoders.encode_base64(attachment)
attachment.add_header('Content-Disposition', 'attachment', filename='results.csv')
msg.attach(attachment)

smtp = smtplib.SMTP('smtp.gmail.com', 587)  # Gmailの場合
smtp.starttls()
smtp.login(from_addr, 'password')
smtp.sendmail(from_addr, rcpt, msg.as_string())
smtp.close()
13
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
28