haproxy_manager 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Readme.md +45 -1
- data/haproxy_manager.gemspec +1 -1
- data/lib/haproxy_manager/constants.rb +4 -0
- data/lib/haproxy_manager/instance.rb +28 -2
- data/lib/haproxy_manager/version.rb +1 -1
- data/spec/instance_spec.rb +44 -2
- metadata +6 -4
data/Readme.md
CHANGED
@@ -16,6 +16,50 @@ For this to work haproxy
|
|
16
16
|
|
17
17
|
`stats socket /home/ubuntu/haproxysock level admin`
|
18
18
|
|
19
|
-
It means that haproxy will open a socket at /home/ubuntu/haproxysock. You can specify the level. We use `admin`.
|
19
|
+
It means that haproxy will open a socket at /home/ubuntu/haproxysock. You can specify the level to use. We use `admin`. But I believe operator/admin is needed for the enable/disable/setting weights to work correctly.
|
20
20
|
|
21
|
+
Installation
|
22
|
+
==============
|
23
|
+
Install the latest version of the gem with the following command...
|
21
24
|
|
25
|
+
$ gem install haproxy_manager
|
26
|
+
|
27
|
+
require "haproxy_manager"
|
28
|
+
|
29
|
+
# Gemfile in Rails app
|
30
|
+
gem "haproxy_manger", :require => false
|
31
|
+
|
32
|
+
Add the following where approporiate(eg. deploy.rb)
|
33
|
+
require "haproxy_manager"
|
34
|
+
|
35
|
+
API
|
36
|
+
======
|
37
|
+
```Ruby
|
38
|
+
|
39
|
+
haproxy = HAProxyManager.new ('path to haproxy socket')
|
40
|
+
|
41
|
+
haproxy.backends # Lists all the backends available
|
42
|
+
haproxy.servers("foo-farm") # List all the servers available in the given backend
|
43
|
+
|
44
|
+
haproxy.disable("preprod-app", "foo-farm") # Disables a server in a specific farm
|
45
|
+
haproxy.disable("preprod-app") # Disables a server with a given name in all the available backends
|
46
|
+
|
47
|
+
|
48
|
+
haproxy.enable("preprod-app", "foo-farm") # Enables a server in a specific farm
|
49
|
+
haproxy.enable("preprod-app") # Enables a server with a given name in all the available backends
|
50
|
+
|
51
|
+
haproxy.weight("preprod-app", "foo-farm", "10") # Sets the weight to 10. The value can be between 0 - 255
|
52
|
+
haproxy.weight("preprod-app", "foo-farm", "10%") # Reduces the weight of the server by 10%(of the value specified in the config)
|
53
|
+
haproxy.weight("preprod-app", "foo-farm", "0%") # Reduces the weight of the server to 0. Useful for disabling the server.
|
54
|
+
haproxy.weight("preprod-app", "foo-farm", "100%") # Increases the weight to the original configuration value. useful to bring the server back up after reducing the weight to 0%
|
55
|
+
|
56
|
+
haproxy.weight("preprod-app", "foo-farm") # Returns the current weights setting. The response is something like this.
|
57
|
+
{current => 10, initial=> 12}
|
58
|
+
|
59
|
+
|
60
|
+
haproxy.info # provides information about the haproxy setup. The following is how it looks like. Most fields are self describing.
|
61
|
+
{"Name" => "HAProxy", "Version" => "1.5-dev11", "Release_date" => "2012/06/04", "Nbproc" => "1", "Process_num" => "1", "Pid" => "4084", "Uptime" => "58d 3h50m53s", "Uptime_sec" => "5025053", "Memmax_MB" => "0", "Ulimit-n" => "40029", "Maxsock" => "40029", "Maxconn" => "20000", "Hard_maxconn => "20000", "Maxpipes" => "0", "CurrConns" => "0", "PipesUsed" => "0", "PipesFree" => " 0", "ConnRate" => " 0", "ConnRateLimit" => " 0", "MaxConnRate" => " 69", "Tasks" => " 10", "Run_queue" => " 1", "Idle_pct" => "100", "node" => " The server name", "description" => "Our Awesome Load balancer"}
|
62
|
+
|
63
|
+
haproxy.reset_counters # Clears HAProxy counters. Except Global counters
|
64
|
+
haproxy.reset_counters(:all) # Clears All HAProxy counters. This is the equivalent of a restart
|
65
|
+
```
|
data/haproxy_manager.gemspec
CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |s|
|
|
5
5
|
s.version = HAProxyManager::VERSION
|
6
6
|
s.platform = Gem::Platform::RUBY
|
7
7
|
s.authors = ["Sreekanth(sreeix)", "Smita Bhat(sbhat)"]
|
8
|
-
s.email = ["gabbar@activesphere.com"]
|
8
|
+
s.email = ["gabbar@activesphere.com", "sbhat@altheasystems.com"]
|
9
9
|
s.homepage = "https://github.com/althea/haproxy-manager"
|
10
10
|
s.summary = 'HAproxy manager for controlling haproxy'
|
11
11
|
s.description = 'Manages haproxy farms and servers'
|
@@ -33,13 +33,39 @@ module HAProxyManager
|
|
33
33
|
@socket.execute( "show info").inject({}){|hash, item| x = item.split(":"); hash.merge(x[0].strip => x[1].strip)}
|
34
34
|
end
|
35
35
|
|
36
|
+
# Sets weight for the server. If a numeric value is provider, that will become the absolute weight. It can be between 0 -256
|
37
|
+
# If a weight has been provided ending with % then the weight is reduced by that percentage. It has to be between 0% - 100%
|
38
|
+
# Weight of a server defines, how many requests are passed to it.
|
39
|
+
def weights(server, backend, weight=nil)
|
40
|
+
if(weight.nil?)
|
41
|
+
weight = @socket.execute "get weight #{backend}/#{server}"
|
42
|
+
/(\d*)\s\(initial\s(\d*)\)/.match( weight[0])
|
43
|
+
{:current => $1.to_i, :initial => $2.to_i}
|
44
|
+
else
|
45
|
+
@socket.execute "set weight #{backend}/#{server} #{weight}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def stats
|
50
|
+
stats = @socket.execute( "show stat -1 -1 -1" )
|
51
|
+
headers = stats[0].split(",")
|
52
|
+
stats[1..-1].inject({}) do |hash, line|
|
53
|
+
data = line.split(","); backend = data[0]; server = data[1]; rest = data[2..-1]
|
54
|
+
hash[backend] = {} if( hash[backend].nil?)
|
55
|
+
hash[backend][server] = {}.tap do |server_hash|
|
56
|
+
headers[2..-1].each_with_index{|x, i| server_hash[x]= rest[i]}
|
57
|
+
end
|
58
|
+
hash
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
36
62
|
def servers(backend = nil)
|
37
63
|
backend.nil? ? @backends.values.flatten : @backends[backend]
|
38
64
|
end
|
39
|
-
|
65
|
+
|
40
66
|
# resets Haproxy counters. If no option is specified backend and frontend counters are cleared, but
|
41
67
|
# cumulative counters are not cleared. The cumulative counters can be cleared by passing the option of
|
42
|
-
# all to the method, in that case all the counters are cleared. This is similar to a restart.
|
68
|
+
# :all to the method, in that case all the counters are cleared. This is similar to a restart.
|
43
69
|
# This is useful to reset stats after for example an incident.
|
44
70
|
def reset_counters(option = "")
|
45
71
|
@socket.execute "clear counters {option}", &@print_response
|
data/spec/instance_spec.rb
CHANGED
@@ -10,7 +10,19 @@ module HAProxyManager
|
|
10
10
|
"foo-https-farm,preprod-bg,0,0,0,0,30,0,0,0,,0,,0,0,0,0,DOWN,5,1,0,4,4,2453494,4518368,,1,2,2,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0,",
|
11
11
|
"foo-https-farm,preprod-test,0,0,0,0,30,0,0,0,,0,,0,0,0,0,DOWN,5,1,0,0,1,5017532,5017532,,1,2,3,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0,"]
|
12
12
|
@info_response = ["Name: HAProxy", "Version: 1.5-dev11", "Release_date: 2012/06/04", "Nbproc: 1", "Process_num: 1", "Pid: 4084", "Uptime: 58d 3h50m53s", "Uptime_sec: 5025053", "Memmax_MB: 0", "Ulimit-n: 40029", "Maxsock: 40029", "Maxconn: 20000", "Hard_maxconn: 20000", "Maxpipes: 0", "CurrConns: 0", "PipesUsed: 0", "PipesFree: 0", "ConnRate: 0", "ConnRateLimit: 0", "MaxConnRate: 69", "Tasks: 10", "Run_queue: 1", "Idle_pct: 100", "node: some machine on ec3", "description: Our awesome load balancer"]
|
13
|
+
@allstats = ["# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,",
|
14
|
+
"foo-farm,FRONTEND,,,0,150,2000,165893,38619996,3233457381,0,0,6504,,,,,OPEN,,,,,,,,,1,1,0,,,,0,0,0,69,,,,0,136147,2128,6654,20955,9,,0,144,165893,,,",
|
15
|
+
"foo-farm,preprod-app,0,9,0,60,60,139066,34839081,3222850212,,0,,3,725,0,0,UP,10,1,0,583,148,10893,257935,,1,1,1,,114847,,2,0,,88,L7OK,200,150,0,135827,2128,147,230,0,0,,,,20,11,",
|
16
|
+
"foo-farm,preprod-bg,0,0,0,3,30,31,14333,380028,,0,,0,9,4,2,DOWN,5,1,0,4,10,2538799,4603702,,1,1,2,,6,,2,0,,2,L4CON,,0,0,16,0,0,0,0,0,,,,1,0,",
|
17
|
+
"foo-farm,preprod-test,0,0,0,0,30,0,0,0,,0,,0,0,0,0,DOWN,5,1,0,0,1,5102839,5102839,,1,1,3,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0,",
|
18
|
+
"foo-farm,BACKEND,0,84,0,150,200,159082,38619996,3233457381,0,0,,19991,734,4,2,UP,10,1,0,,148,10893,300268,,1,1,0,,114853,,1,0,,144,,,,0,135843,2128,147,20955,9,,,,,21,11,",
|
19
|
+
"foo-https-farm,FRONTEND,,,0,3,2000,6545,2675933,71871179,0,0,76,,,,,OPEN,,,,,,,,,1,2,0,,,,0,0,0,3,,,,0,5912,181,82,313,57,,0,3,6545,,,",
|
20
|
+
"foo-https-farm,preprod-app,0,0,0,3,60,6219,2577996,71804141,,0,,1,30,3,0,UP,12,1,0,580,142,10893,257923,,1,2,1,,1948,,2,0,,2,L7OK,200,70,0,5912,181,11,29,0,0,,,,501,0,",
|
21
|
+
"foo-https-farm,preprod-bg,0,0,0,0,30,0,0,0,,0,,0,0,0,0,DOWN,5,1,0,4,4,2538799,4603673,,1,2,2,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0,",
|
22
|
+
"foo-https-farm,preprod-test,0,0,0,0,30,0,0,0,,0,,0,0,0,0,DOWN,5,1,0,0,1,5102837,5102837,,1,2,3,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0,",
|
23
|
+
"foo-https-farm,BACKEND,0,0,0,3,200,6469,2675933,71871179,0,0,,254,30,3,0,UP,12,1,0,,142,10893,300288,,1,2,0,,1948,,1,0,,2,,,,0,5912,181,11,313,52,,,,,501,0,"]
|
13
24
|
end
|
25
|
+
|
14
26
|
before(:each) do
|
15
27
|
HAPSocket.any_instance.expects(:execute).once.returns(@stat_response)
|
16
28
|
@instance = Instance.new("foo")
|
@@ -32,7 +44,7 @@ module HAProxyManager
|
|
32
44
|
@instance.servers.should include "preprod-test"
|
33
45
|
end
|
34
46
|
end
|
35
|
-
|
47
|
+
|
36
48
|
describe "enables/disables servers" do
|
37
49
|
it "enables a server" do
|
38
50
|
HAPSocket.any_instance.expects(:execute).with('enable server foo-farm/preprod-bg')
|
@@ -56,11 +68,41 @@ module HAProxyManager
|
|
56
68
|
@instance.disable("preprod-bg")
|
57
69
|
end
|
58
70
|
end
|
71
|
+
describe "weights" do
|
72
|
+
it "gets current weight" do
|
73
|
+
HAPSocket.any_instance.expects(:execute).with('get weight foo-farm/preprod-bg').returns(["10 (initial 12)"])
|
74
|
+
weights = @instance.weights("preprod-bg","foo-farm" )
|
75
|
+
weights[:current].should == 10
|
76
|
+
weights[:initial].should == 12
|
77
|
+
end
|
78
|
+
|
79
|
+
it "sets weight if weight is specified" do
|
80
|
+
HAPSocket.any_instance.expects(:execute).with('set weight foo-farm/preprod-bg 20')
|
81
|
+
weights = @instance.weights "preprod-bg","foo-farm", 20
|
82
|
+
end
|
83
|
+
end
|
84
|
+
describe "stats" do
|
85
|
+
it "show for all servers" do
|
86
|
+
HAPSocket.any_instance.expects(:execute).with('show stat -1 -1 -1').returns(@allstats)
|
87
|
+
stats = @instance.stats
|
88
|
+
stats.keys.size.should == 2
|
89
|
+
stats.keys.should include "foo-farm"
|
90
|
+
stats.keys.should include "foo-https-farm"
|
91
|
+
stats["foo-farm"].keys.size.should == 5
|
92
|
+
["BACKEND", "FRONTEND", "preprod-app", "preprod-bg"].each do |item|
|
93
|
+
stats["foo-farm"].keys.should include item
|
94
|
+
stats["foo-https-farm"].keys.should include item
|
95
|
+
end
|
96
|
+
stats["foo-https-farm"]["preprod-app"]["status"].should == "UP"
|
97
|
+
stats["foo-https-farm"]["preprod-app"]["weight"].should == "12"
|
98
|
+
stats["foo-https-farm"]["preprod-bg"]["status"].should == "DOWN"
|
99
|
+
stats["foo-https-farm"]["preprod-bg"]["weight"].should == "5"
|
100
|
+
end
|
101
|
+
end
|
59
102
|
|
60
103
|
describe "info about haproxy" do
|
61
104
|
it "has description/version and uptime" do
|
62
105
|
HAPSocket.any_instance.expects(:execute).with("show info").returns(@info_response)
|
63
|
-
|
64
106
|
info = @instance.info
|
65
107
|
info["description"].should == 'Our awesome load balancer'
|
66
108
|
info["Version"].should == '1.5-dev11'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haproxy_manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-09-
|
13
|
+
date: 2012-09-22 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: couchrest
|
@@ -95,6 +95,7 @@ dependencies:
|
|
95
95
|
description: Manages haproxy farms and servers
|
96
96
|
email:
|
97
97
|
- gabbar@activesphere.com
|
98
|
+
- sbhat@altheasystems.com
|
98
99
|
executables: []
|
99
100
|
extensions: []
|
100
101
|
extra_rdoc_files: []
|
@@ -106,6 +107,7 @@ files:
|
|
106
107
|
- Readme.md
|
107
108
|
- haproxy_manager.gemspec
|
108
109
|
- lib/haproxy_manager.rb
|
110
|
+
- lib/haproxy_manager/constants.rb
|
109
111
|
- lib/haproxy_manager/instance.rb
|
110
112
|
- lib/haproxy_manager/version.rb
|
111
113
|
- spec/instance_spec.rb
|
@@ -124,7 +126,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
124
126
|
version: '0'
|
125
127
|
segments:
|
126
128
|
- 0
|
127
|
-
hash: -
|
129
|
+
hash: -845805154420122450
|
128
130
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
131
|
none: false
|
130
132
|
requirements:
|
@@ -133,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
135
|
version: '0'
|
134
136
|
segments:
|
135
137
|
- 0
|
136
|
-
hash: -
|
138
|
+
hash: -845805154420122450
|
137
139
|
requirements: []
|
138
140
|
rubyforge_project: haproxy_manager
|
139
141
|
rubygems_version: 1.8.24
|