読者です 読者をやめる 読者になる 読者になる

SDN開発エンジニアを目指した活動ブログ

〜SDNなオープンソース製品を実際に使って試してみる〜

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ログイン自動スクリプト

そして、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とも連携して、スケジュール&ログ管理を含めたオペレーションのフル自動化に着手していきたいと考えております。