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
129
130
|
#!/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 << "(systemctl daemon-reload || true ) && \n"
commands << "service openvpn restart && \n" if restart.size > 0 or stop.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
}
|