PythonによるSSHログイン自動スクリプトを作成してみる
◆SSHログイン自動スクリプトを試してみる
最近、クラウドコンピューティング基盤技術の世界では、オープンソースを活用した業務オペレーションのフル自動化に注目が集まっております。従来であれば、サーバ/ネットワーク稼働状態を把握するために、オペレータ自らが、各々の機器にログインして、機器の管理コマンドを実行しておりましたが、管理台数が増大するに伴い、サーバ/ネットワーク管理作業を軽減する手法が必要になりますね。そこで、今回は、サーバ/ネットワーク管理作業を軽減する手法を目的とした「SSHログイン自動スクリプト」を作成してみました。
◆SSHログイン自動スクリプトの設定パラメータ管理
機器の稼働状態を確認する上で必要となるログイン情報などを設定ファイルとして保存する方法を実現する必要があります。
今回、"Ryu SDN Framework"のコア部分で活用されている"oslo.config"を使ってみました。まだ、なじみが少ない実装技術ですが、ConfigParserよりも豊富な機能が気に入ってます。
ちなみに、こちらの技術ブログで、わかりやすくoslo.configが解説されております。
oslo.config で Python アプリケーションの設定を管理する | CUBE SUGAR STORAGE
◆実際のSSHログイン自動スクリプトで、やってみたこと
いままで、OpenFlowコントローラが設定したフローエントリを確認する際には、その都度、OpenFlowスイッチにログインしてフローエントリ設定状態を確認するコマンドを投入していました。この作業が、結構、めんどくさいので、これらの一連の作業を自動化してみました。
◆oslo.configのインストール
まずは、oslo.configをインストールします。
pip install oslo.config
◆設定ファイルのサンプル
つぎに、SSHログイン自動スクリプトの設定ファイルです。ファイル名は、"ssh_conf.ini"とします。
[USER] username = root password = xxxxx [HOST] ipaddress = 192.168.100.1 port = 22 command = "ovs-ofctl dump-flows br0 --protocols=OpenFlow13" #command = "ping -c 10 192.168.100.100"
◆SSHログイン自動スクリプト
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import getpass import paramiko from oslo.config import cfg user_opts = [] host_opts = [] user_opts.append(cfg.StrOpt('username', default=[], help='Login username')) user_opts.append(cfg.StrOpt('password', default=[], help='Login password')) host_opts.append(cfg.StrOpt('ipaddress', default='localhost', help='Ipaddress')) host_opts.append(cfg.IntOpt('port', default=22, help='Port number')) host_opts.append(cfg.StrOpt('command', default='ps -ef', help='Command')) CONF = cfg.CONF CONF.register_cli_opts(user_opts, 'USER') CONF.register_cli_opts(host_opts, 'HOST') def main(): try: CONF(default_config_files=['ssh_conf.ini']) username = CONF.USER.username password = CONF.USER.password ipaddress = CONF.HOST.ipaddress port = CONF.HOST.port command = CONF.HOST.command except cfg.ConfigFilesNotFoundError: print "Error: Not Found <conf.ini> " u = getpass.getuser() username = raw_input("Username: (Default=%s) " % (u,)) if not username: username = u password = getpass.getpass() connect_host(username, password, ipaddress, port, command) def connect_host(username, password, ipaddress, port, command): tp = paramiko.Transport((ipaddress, int(port))) try: tp.connect(username=username, password=password, hostkey=None) except: tp.close() raise SystemExit("Bad username or password.") ch = tp.open_channel("session") ch.exec_command(command) while not ch.closed: if ch.recv_stderr_ready: sys.stdout.write(ch.recv_stderr(1024)) if ch.recv_ready: sys.stdout.write(ch.recv(1024)) if __name__ == "__main__": main()
◆実際に動かしてみた
OpenFlowコントローラ機器のターミナル画面から、SSHログイン自動スクリプトを動かしてみました。
$ python ssh_login.sh OFPST_FLOW reply (OF1.3) (xid=0x2): cookie=0x0, duration=7.201s, table=0, n_packets=8, n_bytes=448, send_flow_rem priority=0 actions=CONTROLLER:65535 cookie=0x0, duration=6.897s, table=0, n_packets=6, n_bytes=588, send_flow_rem priority=255,ip,in_port=1,dl_src=a6:59:07:87:56:0e,dl_dst=00:00:00:00:00:01,nw_dst=192.168.1.1 actions=set_field:00:00:00:00:00:02->eth_src,set_field:7e:3a:79:81:4e:b8->eth_dst,output:2 cookie=0x0, duration=6.936s, table=0, n_packets=6, n_bytes=588, send_flow_rem priority=255,ip,in_port=2,dl_src=7e:3a:79:81:4e:b8,dl_dst=00:00:00:00:00:02,nw_dst=192.168.0.1 actions=set_field:00:00:00:00:00:01->eth_src,set_field:a6:59:07:87:56:0e->eth_dst,output:1
ちょっと、わかりにくいですが、OpenFlowスイッチ機器のフローエントリが表示できました。さらには、設定ファイルのcommandパラメータに、"ping"コマンドを設定すれば、疎通確認の結果が表示できました。
$ python ssh_login.sh PING 192.168.100.100 (192.168.100.100) 56(84) bytes of data. 64 bytes from 192.168.100.100: icmp_req=1 ttl=64 time=2.03 ms 64 bytes from 192.168.100.100: icmp_req=2 ttl=64 time=2.63 ms 64 bytes from 192.168.100.100: icmp_req=3 ttl=64 time=0.437 ms 64 bytes from 192.168.100.100: icmp_req=4 ttl=64 time=0.469 ms 64 bytes from 192.168.100.100: icmp_req=5 ttl=64 time=0.585 ms 64 bytes from 192.168.100.100: icmp_req=6 ttl=64 time=0.421 ms 64 bytes from 192.168.100.100: icmp_req=7 ttl=64 time=0.480 ms 64 bytes from 192.168.100.100: icmp_req=8 ttl=64 time=0.650 ms 64 bytes from 192.168.100.100: icmp_req=9 ttl=64 time=0.425 ms 64 bytes from 192.168.100.100: icmp_req=10 ttl=64 time=0.436 ms --- 192.168.100.100 ping statistics --- 10 packets transmitted, 10 received, 0% packet loss, time 9009ms rtt min/avg/max/mdev = 0.421/0.856/2.630/0.753 ms
commandパラメータの設定次第で監視項目の活用事例は、いろいろと豊富に考えられそうですので、将来は、Jenkinsとも連携して、スケジュール&ログ管理を含めたオペレーションのフル自動化に着手していきたいと考えております。