haproxy_manager 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|