1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#!/usr/bin/ruby
require 'yaml';
$config = YAML::load( File.open( 'Hosts' ) )
$NAMESPACE=$config['namespace']
def sys(command)
puts "} #{command}"
system(command) or throw "Command '#{command}' failed"
end
def getFilesMD5(host, ssh_hostname)
cmd = ssh_hostname ?
"ssh -4 root@#{ssh_hostname} /bin/ls -1 /etc/openvpn" :
"ls -1 #{$NAMESPACE}-#{host}"
puts "| " + cmd
f = IO.popen( cmd, aModeString="r" );
files = f.readlines.delete_if{|e| not e =~ /^#{$NAMESPACE}[.-]/ }.collect{|e| e.chomp}
f.close
md5 = {}
if (files.length > 0)
cmd = ssh_hostname ?
"ssh -4 root@#{ssh_hostname} 'cd /etc/openvpn && md5sum " + files.join(' ') + "'" :
"cd #{$NAMESPACE}-#{host} && md5sum " + files.join(' ')
puts "| " + cmd
f = IO.popen( cmd, aModeString="r" );
f.each_line{ |l|
l.chomp!
(h,file) = l.split(/\s+/,2)
unless file
STDERR.puts "Could not split '#{l}' into hash and filename - cmd was '#{cmd}'"
next
end
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 = "#{$NAMESPACE}-#{hostname}/"
sys("scp -4 "+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 -4 root@#{ssh_hostname} '#{command}'") if commands.size > 0
if (do_quagga)
sys("ssh -4 root@#{ssh_hostname} 'cp -a /etc/openvpn/#{$NAMESPACE}.quagga.bgpd /etc/quagga/bgpd.conf &&
cp -a /etc/openvpn/#{$NAMESPACE}.quagga.zebra /etc/quagga/zebra.conf &&
cp -a /etc/openvpn/#{$NAMESPACE}.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 &&
( ! [ -e /etc/ferm/ferm.conf ] || ferm /etc/ferm/ferm.conf )'")
end
}
|