haproxy_manager 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.rvmrc +1 -0
- data/Gemfile +3 -0
- data/Rakefile +10 -0
- data/Readme.md +21 -0
- data/haproxy_manager.gemspec +27 -0
- data/lib/haproxy_manager.rb +1 -0
- data/lib/haproxy_manager/instance.rb +64 -0
- data/lib/haproxy_manager/version.rb +3 -0
- data/spec/instance_spec.rb +59 -0
- data/spec/spec_helper.rb +7 -0
- metadata +145 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm ruby-1.9.2@haproxy_man --create
|
data/Gemfile
ADDED
data/Rakefile
ADDED
data/Readme.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
HaProxy Manager
|
2
|
+
===============
|
3
|
+
|
4
|
+
Haproxy provides ways to add and remove servers on the fly and a lot of other things. This gem lets you use that via a nice ruby API, so that it can be used in applications for deployments testing and gathering statistics.
|
5
|
+
|
6
|
+
This was extracted out of our rolling deployment scheme.
|
7
|
+
|
8
|
+
Prerequsites
|
9
|
+
=============
|
10
|
+
|
11
|
+
For this to work haproxy
|
12
|
+
|
13
|
+
* Version 1.4 and above
|
14
|
+
|
15
|
+
* Should be running with the following configuration.
|
16
|
+
|
17
|
+
`stats socket /home/ubuntu/haproxysock level admin`
|
18
|
+
|
19
|
+
It means that haproxy will open a socket at /home/ubuntu/haproxysock. You can specify the level. We use `admin`.
|
20
|
+
|
21
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path("../lib/haproxy_manager/version.rb", __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "haproxy_manager"
|
5
|
+
s.version = HAProxyManager::VERSION
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.authors = ["Sreekanth(sreeix)", "Smita Bhat(sbhat)"]
|
8
|
+
s.email = ["gabbar@activesphere.com"]
|
9
|
+
s.homepage = "https://github.com/althea/haproxy-manager"
|
10
|
+
s.summary = 'HAproxy manager for controlling haproxy'
|
11
|
+
s.description = 'Manages haproxy farms and servers'
|
12
|
+
|
13
|
+
s.rubyforge_project = "haproxy_manager"
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.default_executable = "couchup"
|
18
|
+
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency 'couchrest'
|
22
|
+
|
23
|
+
s.add_development_dependency 'rspec'
|
24
|
+
s.add_development_dependency 'rake'
|
25
|
+
s.add_development_dependency 'mocha'
|
26
|
+
s.add_development_dependency 'bundler'
|
27
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'haproxy_manager/instance'
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'socket'
|
2
|
+
module HAProxyManager
|
3
|
+
class Instance
|
4
|
+
def initialize(socket)
|
5
|
+
@socket = HAPSocket.new(socket)
|
6
|
+
@print_response = Proc.new {|response| puts response}
|
7
|
+
backends = @socket.execute( "show stat -1 4 -1" )[1..-1].collect{|item| item.split(",")[0..1]}
|
8
|
+
@backends = backends.inject({}){|hash, items| (hash[items[0]] ||=[]) << items[1]; hash}
|
9
|
+
end
|
10
|
+
|
11
|
+
# Diables a server in the server in a backend for maintenance.
|
12
|
+
# If backend is not specified then all the backends in which the serverid exists are disabled.
|
13
|
+
|
14
|
+
def disable(serverid, backend = nil)
|
15
|
+
all_servers(serverid, backend).each do |item|
|
16
|
+
@socket.exec "disable server #{item[0]}/#{item[1]}", &@print_response
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Enables a server in the server in a backend.
|
21
|
+
# If backend is not specified then all the backends in which the serverid exists are enabled.
|
22
|
+
def enable(serverid, backend = nil)
|
23
|
+
all_servers(serverid, backend).each do |item|
|
24
|
+
@socket.exec "enable server #{item[0]}/#{item[1]}", &@print_response
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def backends
|
29
|
+
@backends.keys
|
30
|
+
end
|
31
|
+
|
32
|
+
def servers(backend = nil)
|
33
|
+
backend.nil? ? @backends.values.flatten : @backends[backend]
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def all_servers(serverid, backend)
|
38
|
+
if(backend.nil?)
|
39
|
+
items = @backends.collect{|a, b| [a, serverid] if b.include?(serverid)}.compact
|
40
|
+
else
|
41
|
+
items = [[backend, serverid]]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class HAPSocket
|
47
|
+
def initialize(file)
|
48
|
+
@file = file
|
49
|
+
end
|
50
|
+
|
51
|
+
def execute(cmd, &block)
|
52
|
+
socket = UNIXSocket.new(@file)
|
53
|
+
socket.write("#{cmd};")
|
54
|
+
response = []
|
55
|
+
socket.each do |line|
|
56
|
+
data = line.strip
|
57
|
+
next if data.empty?
|
58
|
+
response << data
|
59
|
+
end
|
60
|
+
yield response if block_given?
|
61
|
+
response
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
2
|
+
module HAProxyManager
|
3
|
+
describe Instance do
|
4
|
+
before(:all) do
|
5
|
+
@stat_response = ["# 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,",
|
6
|
+
"foo-farm,preprod-app,0,9,0,60,60,137789,34510620,3221358490,,0,,3,720,0,0,UP,12,1,0,562,143,45394,255790,,1,1,1,,113890,,2,0,,88,L7OK,200,20,0,134660,2028,147,230,0,0,,,,20,6,",
|
7
|
+
"foo-farm,preprod-bg,0,0,0,3,30,31,14333,380028,,0,,0,9,4,2,DOWN,5,1,0,4,10,2453494,4518397,,1,1,2,,6,,2,0,,2,L4CON,,0,0,16,0,0,0,0,0,,,,1,0,",
|
8
|
+
"foo-farm,preprod-test,0,0,0,0,30,0,0,0,,0,,0,0,0,0,DOWN,5,1,0,0,1,5017534,5017534,,1,1,3,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0,",
|
9
|
+
"foo-https-farm,preprod-app,0,0,0,3,60,6219,2577996,71804141,,0,,1,30,3,0,UP,12,1,0,559,137,45394,255774,,1,2,1,,1948,,2,0,,2,L7OK,200,109,0,5912,181,11,29,0,0,,,,501,0,",
|
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
|
+
"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
|
+
end
|
13
|
+
before(:each) do
|
14
|
+
HAPSocket.any_instance.expects(:execute).returns(@stat_response)
|
15
|
+
@instance = Instance.new("foo")
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "creation" do
|
19
|
+
it "parses stats and lists backends" do
|
20
|
+
@instance.backends.size.should == 2
|
21
|
+
@instance.backends.should include "foo-farm"
|
22
|
+
@instance.backends.should include "foo-https-farm"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "parses stats and lists servers" do
|
26
|
+
@instance.servers('foo-farm').size.should == 3
|
27
|
+
end
|
28
|
+
it "understands servers without backend are all servers" do
|
29
|
+
@instance.servers.size.should == 6
|
30
|
+
@instance.servers.should include "preprod-bg"
|
31
|
+
@instance.servers.should include "preprod-test"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "enables servers" do
|
36
|
+
it "enables a server" do
|
37
|
+
HAPSocket.any_instance.expects(:exec).with('enable server foo-farm/preprod-bg')
|
38
|
+
@instance.enable("preprod-bg", "foo-farm")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "enables a all servers in multiple backends" do
|
42
|
+
HAPSocket.any_instance.expects(:exec).with('enable server foo-farm/preprod-bg')
|
43
|
+
HAPSocket.any_instance.expects(:exec).with('enable server foo-https-farm/preprod-bg')
|
44
|
+
@instance.enable("preprod-bg")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "disables a server" do
|
48
|
+
HAPSocket.any_instance.expects(:exec).with('disable server foo-farm/preprod-bg')
|
49
|
+
@instance.disable("preprod-bg", "foo-farm")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "disables a server in all backends" do
|
53
|
+
HAPSocket.any_instance.expects(:exec).with('disable server foo-farm/preprod-bg')
|
54
|
+
HAPSocket.any_instance.expects(:exec).with('disable server foo-https-farm/preprod-bg')
|
55
|
+
@instance.disable("preprod-bg")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: haproxy_manager
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sreekanth(sreeix)
|
9
|
+
- Smita Bhat(sbhat)
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2012-09-21 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: couchrest
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: rspec
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
type: :development
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: mocha
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
type: :development
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: bundler
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
type: :development
|
88
|
+
prerelease: false
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
description: Manages haproxy farms and servers
|
96
|
+
email:
|
97
|
+
- gabbar@activesphere.com
|
98
|
+
executables: []
|
99
|
+
extensions: []
|
100
|
+
extra_rdoc_files: []
|
101
|
+
files:
|
102
|
+
- .gitignore
|
103
|
+
- .rvmrc
|
104
|
+
- Gemfile
|
105
|
+
- Rakefile
|
106
|
+
- Readme.md
|
107
|
+
- haproxy_manager.gemspec
|
108
|
+
- lib/haproxy_manager.rb
|
109
|
+
- lib/haproxy_manager/instance.rb
|
110
|
+
- lib/haproxy_manager/version.rb
|
111
|
+
- spec/instance_spec.rb
|
112
|
+
- spec/spec_helper.rb
|
113
|
+
homepage: https://github.com/althea/haproxy-manager
|
114
|
+
licenses: []
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options: []
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ! '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
segments:
|
126
|
+
- 0
|
127
|
+
hash: 1069670280984611263
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
segments:
|
135
|
+
- 0
|
136
|
+
hash: 1069670280984611263
|
137
|
+
requirements: []
|
138
|
+
rubyforge_project: haproxy_manager
|
139
|
+
rubygems_version: 1.8.24
|
140
|
+
signing_key:
|
141
|
+
specification_version: 3
|
142
|
+
summary: HAproxy manager for controlling haproxy
|
143
|
+
test_files:
|
144
|
+
- spec/instance_spec.rb
|
145
|
+
- spec/spec_helper.rb
|