haproxy-api 0.1.1
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.
- checksums.yaml +15 -0
- data/bin/hapi +10 -0
- data/haproxy-api.gemspec +22 -0
- data/lib/hapi/application/app.rb +201 -0
- metadata +75 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
!binary "U0hBMQ==":
|
|
3
|
+
metadata.gz: !binary |-
|
|
4
|
+
M2NlM2NhYTUzYjEyYTQyMDcyYzUzNGFmMzRjYjgwYjU4NDVlMjgxZQ==
|
|
5
|
+
data.tar.gz: !binary |-
|
|
6
|
+
MzdiMmU4MTNhNTU0NmFlMjYyMGIyYThkMTk2ZDc1N2Y2NDVkYTM5ZA==
|
|
7
|
+
SHA512:
|
|
8
|
+
metadata.gz: !binary |-
|
|
9
|
+
YTAyOTk4MjVmNDJmZWEwMTEwZDk2ODZkZDIxYTAxMmVkNTg3OWJlM2UwNDY4
|
|
10
|
+
YzlhOWIyY2I4OGYxZTFmNzU3MmJlYjk1YzFmZTYzNjUwMWNiN2E5MDA2MTBi
|
|
11
|
+
ZjVmOWMyZGFlNzFjNDk0MTRmOThlOGM4OTQwMmY0MjE5MWYzMTM=
|
|
12
|
+
data.tar.gz: !binary |-
|
|
13
|
+
MzczNTNkYmJhODc5NTlmNGE1MGZjNjNjOTIzZGQ3Njc4YmI4MzFlMDMyNTE1
|
|
14
|
+
MjI3ZTgzMWJiZTFjZTc0NmRmNTkyNmJkYzFmNDNiODdiYTMzMWI5NWZhMzAx
|
|
15
|
+
YmMyMDFlNjgwZWMzMWVkZDM1YzRiZjI3MDEwMzA4ZTk5OTI1MGI=
|
data/bin/hapi
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
begin
|
|
4
|
+
require 'hapi/application/app.rb'
|
|
5
|
+
rescue LoadError => e
|
|
6
|
+
require 'rubygems'
|
|
7
|
+
path = File.expand_path '../../lib', __FILE__
|
|
8
|
+
$:.unshift(path) if File.directory?(path) && !$:.include?(path)
|
|
9
|
+
require 'hapi/application/app.rb'
|
|
10
|
+
end
|
data/haproxy-api.gemspec
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |s|
|
|
4
|
+
s.name = 'haproxy-api'
|
|
5
|
+
s.version = '0.1.1'
|
|
6
|
+
s.license = 'Apache-2.0'
|
|
7
|
+
s.author = 'Mike Schwankl'
|
|
8
|
+
s.email = 'schwankl@gmail.com'
|
|
9
|
+
s.homepage = 'https://github.com/schwankl/haproxy-api'
|
|
10
|
+
s.description = 'Haproxy API using sinatra'
|
|
11
|
+
s.summary = 'rest API using to haproxy'
|
|
12
|
+
s.executables = %(hapi)
|
|
13
|
+
|
|
14
|
+
s.platform = Gem::Platform::RUBY
|
|
15
|
+
s.extra_rdoc_files = %w()
|
|
16
|
+
s.add_dependency('sinatra', '1.4.7')
|
|
17
|
+
s.add_dependency('webrick', '1.3.1')
|
|
18
|
+
|
|
19
|
+
s.bindir = 'bin'
|
|
20
|
+
s.require_path = 'lib'
|
|
21
|
+
s.files = %w() + ["haproxy-api.gemspec"] + Dir.glob("lib/**/*") + Dir.glob('bin/**/*')
|
|
22
|
+
end
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
require 'sinatra'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'webrick'
|
|
4
|
+
require 'webrick/https'
|
|
5
|
+
require 'openssl'
|
|
6
|
+
|
|
7
|
+
CERT_PATH = ENV['CERT_PATH']
|
|
8
|
+
|
|
9
|
+
if CERT_PATH.nil? || !File.exists?(CERT_PATH+'/hapi.crt')
|
|
10
|
+
puts "set CERT_PATH env var to where your hapi.crt and hapi.key are"
|
|
11
|
+
exit 1
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
webrick_options = {
|
|
15
|
+
:Host => "0.0.0.0",
|
|
16
|
+
:Port => 443,
|
|
17
|
+
:Logger => WEBrick::Log::new($stderr, WEBrick::Log::DEBUG),
|
|
18
|
+
:DocumentRoot => "/ruby/htdocs",
|
|
19
|
+
:SSLEnable => true,
|
|
20
|
+
:SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
|
|
21
|
+
:SSLCertificate => OpenSSL::X509::Certificate.new( File.open(File.join(CERT_PATH, "/hapi.crt")).read),
|
|
22
|
+
:SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open(File.join(CERT_PATH, "/hapi.key")).read),
|
|
23
|
+
:SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class HaproxyApi < Sinatra::Base
|
|
28
|
+
|
|
29
|
+
$haproxy_config = '/etc/haproxy/haproxy.cfg'
|
|
30
|
+
if ENV['HAPROXY_CONFIG']
|
|
31
|
+
$haproxy_config = ENV['HAPROXY_CONFIG']
|
|
32
|
+
end
|
|
33
|
+
$mutable_haproxy_config = $haproxy_config + '.haproxy-api.json'
|
|
34
|
+
|
|
35
|
+
#before do
|
|
36
|
+
# request.body.rewind
|
|
37
|
+
# if request.body.size > 0
|
|
38
|
+
# @request_payload = JSON.parse request.body.read
|
|
39
|
+
# end
|
|
40
|
+
#end
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def get_config
|
|
44
|
+
return { 'frontend' => {}, 'backend' => {} } if !File.exists?($mutable_haproxy_config)
|
|
45
|
+
return JSON.parse(File.read($mutable_haproxy_config))
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def render(config)
|
|
50
|
+
content = ""
|
|
51
|
+
f = File.open($haproxy_config, "r")
|
|
52
|
+
in_gen_section = false
|
|
53
|
+
f.each_line do |line|
|
|
54
|
+
if line =~ /HAPROXY_API_GENERATED/
|
|
55
|
+
if in_gen_section
|
|
56
|
+
in_gen_section = false
|
|
57
|
+
else
|
|
58
|
+
in_gen_section = true
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
if !in_gen_section
|
|
62
|
+
content += line
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
f.close
|
|
67
|
+
|
|
68
|
+
content += "# HAPROXY_API_GENERATED - START\n"
|
|
69
|
+
|
|
70
|
+
config['frontend'].each_pair do |name, frontend|
|
|
71
|
+
content += "frontend #{name}\n"
|
|
72
|
+
content += " bind 0.0.0.0:#{frontend['port']}\n"
|
|
73
|
+
content += " default_backend #{name}-backend\n"
|
|
74
|
+
content += "\n"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
config['backend'].each_pair do |name, backend|
|
|
78
|
+
content += "backend #{name}\n"
|
|
79
|
+
content += " balance #{backend['lbmethod']}\n"
|
|
80
|
+
|
|
81
|
+
if backend.has_key?('options')
|
|
82
|
+
backend['options'].each_pair do |k,v|
|
|
83
|
+
content += " option #{k} #{v}\n"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
port = backend['port']
|
|
88
|
+
server_options = ""
|
|
89
|
+
if backend.has_key?('server_options')
|
|
90
|
+
backend['server_options'].each_pair do |k,v|
|
|
91
|
+
server_options += "#{k} #{v} "
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
backend['servers'].each do |server|
|
|
96
|
+
content += " server #{server}:#{port} #{server}:#{port} #{server_options} \n"
|
|
97
|
+
end
|
|
98
|
+
content += "\n"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
content += "# HAPROXY_API_GENERATED - END\n"
|
|
102
|
+
|
|
103
|
+
return content
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def set_config(config)
|
|
108
|
+
ts = Time.now.to_i
|
|
109
|
+
`cp #{$haproxy_config} #{$haproxy_config}.#{ts}`
|
|
110
|
+
content = render config
|
|
111
|
+
File.open($mutable_haproxy_config, 'w') { |file| file.write(JSON.dump(config)) }
|
|
112
|
+
File.open($haproxy_config, 'w') { |file| file.write(content) }
|
|
113
|
+
|
|
114
|
+
result = `/usr/sbin/haproxy -c -f #{$haproxy_config}`
|
|
115
|
+
if $?.to_i == 0
|
|
116
|
+
puts `systemctl restart haproxy`
|
|
117
|
+
else
|
|
118
|
+
puts "rolling back config - got:"
|
|
119
|
+
puts result
|
|
120
|
+
`cp #{$haproxy_config}.#{ts} #{$haproxy_config}`
|
|
121
|
+
return status(500)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
get '/render' do
|
|
126
|
+
config = get_config
|
|
127
|
+
render config
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
get '/frontends' do
|
|
131
|
+
config = get_config
|
|
132
|
+
JSON.dump(config['frontend'])
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
get '/frontend/:id' do
|
|
136
|
+
config = get_config
|
|
137
|
+
id = params[:id]
|
|
138
|
+
return status(404) if !config['frontend'].has_key?(id)
|
|
139
|
+
JSON.dump(config['frontend'][id])
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
post '/frontend/:id' do
|
|
143
|
+
config = get_config
|
|
144
|
+
|
|
145
|
+
id = params[:id]
|
|
146
|
+
if config['frontend'].has_key?(id)
|
|
147
|
+
puts "#{id} already exists - use put"
|
|
148
|
+
return status(500)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
frontend = JSON.parse request.body.read
|
|
152
|
+
config['frontend'][id] = frontend
|
|
153
|
+
set_config config
|
|
154
|
+
JSON.dump(frontend)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
delete '/frontend/:id' do
|
|
158
|
+
config = get_config
|
|
159
|
+
config['frontend'].delete params[:id]
|
|
160
|
+
set_config config
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
get '/backends' do
|
|
165
|
+
config = get_config
|
|
166
|
+
JSON.dump(config['backend'])
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
get '/backend/:id' do
|
|
171
|
+
config = get_config
|
|
172
|
+
id = params[:id] + "-backend"
|
|
173
|
+
return status(404) if !config['backend'].has_key?(id)
|
|
174
|
+
JSON.dump(config['backend'][id])
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
post '/backend/:id' do
|
|
179
|
+
config = get_config
|
|
180
|
+
id = params[:id] + "-backend"
|
|
181
|
+
if config['backend'].has_key?(id)
|
|
182
|
+
puts "#{id} already exists - use put"
|
|
183
|
+
return status(500)
|
|
184
|
+
end
|
|
185
|
+
backend = JSON.parse request.body.read
|
|
186
|
+
config['backend'][id] = backend
|
|
187
|
+
set_config config
|
|
188
|
+
JSON.dump(backend)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
delete '/backend/:id' do
|
|
193
|
+
config = get_config
|
|
194
|
+
config['backend'].delete(params[:id] + "-backend")
|
|
195
|
+
set_config config
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
Rack::Handler::WEBrick.run HaproxyApi, webrick_options
|
|
201
|
+
|
metadata
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: haproxy-api
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Mike Schwankl
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2016-10-12 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: sinatra
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - '='
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 1.4.7
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - '='
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 1.4.7
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: webrick
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - '='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 1.3.1
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - '='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 1.3.1
|
|
41
|
+
description: Haproxy API using sinatra
|
|
42
|
+
email: schwankl@gmail.com
|
|
43
|
+
executables:
|
|
44
|
+
- hapi
|
|
45
|
+
extensions: []
|
|
46
|
+
extra_rdoc_files: []
|
|
47
|
+
files:
|
|
48
|
+
- bin/hapi
|
|
49
|
+
- haproxy-api.gemspec
|
|
50
|
+
- lib/hapi/application/app.rb
|
|
51
|
+
homepage: https://github.com/schwankl/haproxy-api
|
|
52
|
+
licenses:
|
|
53
|
+
- Apache-2.0
|
|
54
|
+
metadata: {}
|
|
55
|
+
post_install_message:
|
|
56
|
+
rdoc_options: []
|
|
57
|
+
require_paths:
|
|
58
|
+
- lib
|
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
60
|
+
requirements:
|
|
61
|
+
- - ! '>='
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: '0'
|
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ! '>='
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
requirements: []
|
|
70
|
+
rubyforge_project:
|
|
71
|
+
rubygems_version: 2.4.8
|
|
72
|
+
signing_key:
|
|
73
|
+
specification_version: 4
|
|
74
|
+
summary: rest API using to haproxy
|
|
75
|
+
test_files: []
|