you are better than you think

一份自动登录脚本

· by thur · Read in about 2 min · (392 Words)
自动登录 expect脚本 tcl语法

背景:登录到relay需要输入token+密码, 然后选择中控机。

需求:k8s机房大概有X个了,master ip 记不住,这次要给自动登录脚本加一个展示机器列表的功能,选择ip 或hostname 的序号进行登录,登录其他node机器时 只需要直接gg hostname 即可。 gg prod 会展示 master 列表,输入 master对应的序号,回车即可登录到master.

花时间学习了tcl的语法 完成了这个脚本。

先设置线上机器的ssh 会话复用 ,这样每天只需要输入一次token ,其他时间不需要再输入token了

host *
    Protocol 2
    ServerAliveInterval 30
    ServerAliveCountMax 3
host xxxx.xxx.efg
    ControlMaster auto
    ControlPath ~/.ssh/master-%r@%h
host xxx.xxx.abc
    ControlMaster auto
    ControlPath ~/.ssh/master-%r@%h

登录脚本 masters是机器列表 给机器取个别名,transform会对alias进行字典排序,并给列表加上序号,选择时只需要输入序号即可。

#!/usr/bin/expect -f
if {$argc<1 || $argc >2} {
        send_user "usage: gg \[relay \$code/prod \$code \]\n"
        exit
}

# 配置1 第一列:给机器取个别名 ,第二列:常用机器的ip或hostname
# 输出的菜单, 按照 alias 进行字典排序
global masters
array set masters {
    m1 10.1.2.3
    m2 10.1.2.4
    m3 10.1.2.5
}

proc relayLogin {user host pass code} {
    set relay relay.xxxx.com
    spawn -noecho ssh -p 35000 -o StrictHostKeyChecking=no -o ServerAliveInterval=30 $user@$relay
    expect {
        "*yes/no*"
        {send "yes\r";exp_continue}
        "token:"
        {send "$code\r";exp_continue}
        "Password*"
        {send "$pass\r";exp_continue}
        "Option*"
        {send "2\r";exp_continue}
        "*relay.xxx.host*"
        {if {$host!=""} {send "dssh $user@$host\r"}}
    }
    interact
}
proc productLogin {user host pass code} {
    global masters
    set newList(ID) 0
    transform masters newList
    showList newList
    send_user "\n"
    send_user "please enter a host:  \n"
    flush stdout
    set key [gets stdin]
    switch $key {
        q -
        quit {exit}
        relay {relayLogin $user "" $pass $code}
        default {
            if { [info exists newList($key,host)] } {
                send_user "$key, $newList($key,host)\n"
                relayLogin $user $newList($key,host) $pass $code
            } else {
                send_user "$key does not exist\n"
                exit
            }
        }
    }
}
proc passLogin {user host pass} {
    spawn -noecho ssh -p22 $user@$host
    expect "*assword:"
    send "$pass\r"
    interact
}
proc authLogin {user host pem} {
    spawn -noecho ssh -i "$pem" -p22 $user@$host
    interact
}

proc addMaster {db alias host} {
    upvar $db name
    incr name(ID)
    set id $name(ID)
    set name($id,alias) $alias;
    set name($id,host)  $host;
}
proc showList {db} {
    upvar $db name
    foreach n [array names name "*,alias"] {
        regexp {^[^,]+} $n id
        set last       $name($n)
        set tmp($id) $id ;# sort by id
    }
    foreach last [lsort -integer [array names tmp]] {
        set id $tmp($last)
        puts "$id $name($id,alias) $name($id,host)"
    }
}

proc transform {arr arr2} {
    upvar $arr hostList
    upvar $arr2 newList
    foreach name [lsort [array names hostList]] {
        addMaster newList $name $hostList($name)
    }
}
# 配置2 设置登录用户名
set user xiaoming
set HOME /home/xiaoming
# 配置3 设置登录密码
set password "123456"
set code [lindex $argv 1 ]
set hostName [lindex $argv 0 ]
switch $hostName {
    "relay" {relayLogin $user "" $password $code}
    "prod" {productLogin $user "" $password $code}
    default {relayLogin $user $hostName $password $code}
}

将上面脚本保存在系统path路径下 ,加上执行权限chmod u+x /path/gg. 这样使用 gg hostname 123456gg prod 123456 (第一次登录输入token) ,其他时间只需要执行 gg hostnamegg prod

Comments