/
haproxy-config.rb
executable file
·67 lines (57 loc) · 1.79 KB
/
haproxy-config.rb
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
#!/usr/local/bin/ruby
require 'json'
require 'erb'
require 'fileutils'
ETCD_ENDPOINT = ENV['ETCD_ENDPOINT']
if ETCD_ENDPOINT.nil? || ETCD_ENDPOINT.empty?
puts 'ETCD_ENDPOINT is not set... aborting'
exit -1
end
BASE_URL = "#{ETCD_ENDPOINT}/v2/keys/registered?consistent=true&recursive=true"
def leaves_of(node)
leaves = []
case node.key? 'dir'
when true
leaves += node['nodes'].flat_map { |n| leaves_of(n) } if node['nodes']
when false
leaves += JSON.parse(node['value'])
end
leaves
end
def valid_port_groups(port_groups)
valid_port_groups = {}
port_groups.each_pair do |port_number, port_group|
unless port_group.empty?
first_image = port_group[0]['image']
num_images_like_first = port_group.count { |port_info| port_info['image'] == first_image }
if num_images_like_first == port_group.size
valid_port_groups[port_number] = port_group
else
puts "Warning: port #{port_number} has been bound to different docker images - rejecting"
end
end
end
valid_port_groups
end
def get_port_groups
response = JSON.load(`curl -sL "#{BASE_URL}" -XGET`)
valid_port_groups(leaves_of(response['node']).group_by { |p| p['private_port'] }) if response && response['node']
end
def rebuild_config(port_groups)
puts "Rebuilding Haproxy config..."
puts ">> #{port_groups}"
erb = ERB.new(File.read('/etc/haproxy/haproxy.cfg.erb'))
FileUtils.copy('/etc/haproxy/haproxy.cfg', '/etc/haproxy/haproxy.cfg.bkup')
File.open('/etc/haproxy/haproxy.cfg','w') do |file|
file.puts "#{erb.result(binding)}"
end
end
$port_groups = {}
loop do
port_groups = get_port_groups
if port_groups && port_groups != $port_groups
$port_groups = port_groups
rebuild_config($port_groups)
end
JSON.load(`curl -sL -m 60 "#{BASE_URL}&wait=true" -XGET`)
end