#!/usr/bin/ruby require 'yaml'; $config = YAML::load( File.open( 'Hosts' ) ) def sys(command) puts "} #{command}" system(command) or throw "Command '#{command}' failed" end def getFilesMD5(host, ssh_hostname) cmd = ssh_hostname ? "ssh root@#{ssh_hostname} /bin/ls -1 /etc/openvpn" : "ls -1 noreply2-#{host}" puts "| " + cmd f = IO.popen( cmd, aModeString="r" ); files = f.readlines.delete_if{|e| not e =~ /^noreply2[.-]/ }.collect{|e| e.chomp} f.close md5 = {} if (files.length > 0) cmd = ssh_hostname ? "ssh root@#{ssh_hostname} 'cd /etc/openvpn && md5sum " + files.join(' ') + "'" : "cd noreply2-#{host} && md5sum " + files.join(' ') puts "| " + cmd f = IO.popen( cmd, aModeString="r" ); f.each_line{ |l| l.chomp! (h,file) = l.split(/\s+/,2) md5[file] = h } f.close end return md5 end hosts = ARGV if hosts.size == 0 hosts = $config['hosts'].keys end hosts.each{ |hostname| puts "Pushing to #{hostname}." throw "Host #{hostname} not in config" unless $config['hosts'][hostname] ssh_hostnames = $config['hosts'][hostname]['ssh_hostname'] unless ssh_hostnames STDERR.puts "*** #{hostname} has no ssh_hostname!" next end ssh_hostname = nil ssh_hostnames.delete(' ').split(',').each{ |host| if not system("ping -W2 -c3 #{host}") STDERR.puts "*** #{host} is not reachable!" next else ssh_hostname = host break end } unless ssh_hostname STDERR.puts "*** no reachable host found for #{hostname}!" next end remote = getFilesMD5(hostname, ssh_hostname) local = getFilesMD5(hostname, nil) delete = [] copy = [] stop = [] restart = [] do_iptables = nil do_ip6tables = nil do_quagga = nil remote.each_pair{|f,h| if ! local.has_key?(f) delete << f if f =~ /\.conf$/ stop << f.gsub(/\.conf$/, '') end end } local.each_pair{|f,h| if ! remote.has_key?(f) || local[f] != remote[f] copy << f if f =~ /\.iptables\.sh$/ do_iptables = f elsif f =~ /\.ip6tables\.sh$/ do_ip6tables = f elsif f =~ /\.quagga\.(bgpd|zebra|daemons)$/ do_quagga = true elsif f =~ /\.conf$/ restart << f.gsub(/\.conf$/, '') end end } dir = "noreply2-#{hostname}/" sys("scp "+copy.collect{|f| dir+f }.join(' ')+" root@#{ssh_hostname}:/etc/openvpn/") if copy.size > 0 commands = [] commands << "sh ./#{do_iptables} &&\n" if do_iptables commands << "sh ./#{do_ip6tables} &&\n" if do_ip6tables commands << "/etc/init.d/openvpn stop "+stop.join(' ')+" &&\n" if stop.size > 0 commands << "/etc/init.d/openvpn restart "+restart.join(' ')+" && \n" if restart.size > 0 commands << "rm "+delete.join(' ')+" &&\n" if delete.size > 0 command = "cd /etc/openvpn && \n"; command << commands.join('') command << "echo 'all done'" sys("ssh root@#{ssh_hostname} '#{command}'") if commands.size > 0 if (do_quagga) sys("ssh root@#{ssh_hostname} 'cp -a /etc/openvpn/noreply2.quagga.bgpd /etc/quagga/bgpd.conf && cp -a /etc/openvpn/noreply2.quagga.zebra /etc/quagga/zebra.conf && cp -a /etc/openvpn/noreply2.quagga.daemons /etc/quagga/daemons && chmod 640 /etc/quagga/bgpd.conf /etc/quagga/zebra.conf && chgrp quagga /etc/quagga/bgpd.conf /etc/quagga/zebra.conf && /etc/init.d/quagga restart'") end }