Donnerstag, 26. April 2012

Remote Shell Command for XEN usage

I do not know if you use nagios, i guess most people do. There is a very nice addition to configure nagios it is called nagiosql (http://www.nagiosql.org/).

So maybe in addition to that you sometimes have an problem like i do. We use xen servers with some virtual machines. So sometimes i have an issue which belongs to every machine on an _parent_ xen server. Normally i send an ssh command to all of them. When it comes to the point where these are some hundred once it really sucks. So i wrote a script to do so, which setsup on the nagiosql structure.

What do we need:

  • Nagiosql and host with the _parent_ variable set

  • an DB user which can do select on the db_nagiosql

  • an key login via ssh on all machines

  • ruby :-)


So here is the script
#!/usr/bin/ruby -w
# ruby mysql query ssh command to all childs of parent
#
# by Jörg Stephan <j AT xadmin DOT info>
#
# Usage:
# -p <parent> # zB xenone
# -c <command> # zB "ls -la"
#
require 'mysql'
require 'net/ssh'

begin
parent = ""
command = ""

if ARGV.length < 4
puts "Usage: rshdo.rb -p <parent> -c <command>"
exit
end
ARGV.each_with_index do |arg, index|
if arg == "-p"
parent= ARGV[index + 1]
elsif arg == "-c"
command = ARGV[index + 1]
end
end
# connect to the MySQL server
dbh = Mysql.real_connect("nagiosserver", "client", "ultrastrengthpassword", "db_nagiosql")
res = dbh.query("select host_name from tbl_host where id IN (select idMaster from tbl_lnkHostToHost where idSlave = (select id from tbl_host where host_name='" + parent + "'))")
while row = res.fetch_row do
puts row[0]
begin
Net::SSH.start(row[0], 'root' , :host_key => "ssh-rsa", :keys => ["/root/.ssh/id_dsa"] ) do |ssh|
result = ssh.exec " " + command + " "
puts result
end
rescue Net::SSH::AuthenticationFailed => e
puts row[0] + " Error while connecting " + e
end
end
rescue Mysql::Error => e
puts "Error code: #{e.errno}"
puts "Error message: #{e.error}"
puts "Error SQLSTATE: #{e.sqlstate}" if e.respond_to?("sqlstate")
ensure
# disconnect from server
dbh.close if dbh
end

now your are able to to
shell#> ruby rshdo.rb -p <parenthost> -c <shell command>

and you send the <shell command>  to every host whichs parent is <parenthost>