marathon-template 0.0.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 +7 -0
- data/bin/marathon-template +3 -0
- data/lib/marathon-template/cron.rb +25 -0
- data/lib/marathon-template/deploy.rb +164 -0
- data/lib/marathon-template/options.rb +44 -0
- data/lib/marathon_template.rb +45 -0
- metadata +50 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4a954fce7f07212d71bd14434522528cebc77ed3
|
4
|
+
data.tar.gz: 749566187f8ae78e6e85abff6f566c7225b14e98
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3c11836e9bcaa8b0e15d9bf62456624c54e9dccc052de27859b12a81dab16da827d241d5c58c4acfed27dc44299cd8ae8c0e29b9c9f62a6b6ff6395e61daedbc
|
7
|
+
data.tar.gz: 1de8144eeac23b09f4cd5c2d18db3f431413267a2f7dd5f4afd04f42bc0cc556d2a4955fb33e2e04a41accaf160e94da6811cec819df1f87bf2e65cc183f4a4c
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Marathon_template
|
2
|
+
class Cron
|
3
|
+
def self.add
|
4
|
+
if CONFIG[:cron_splay]
|
5
|
+
LOG.info "Setting up cron job..."
|
6
|
+
if File.exists? '/etc/crontab'
|
7
|
+
if File.open('/etc/crontab').each_line.any? { |line| line.chomp == "#{CONFIG[:cron_splay]}" }
|
8
|
+
LOG.info "Cron already configured."
|
9
|
+
return
|
10
|
+
else
|
11
|
+
File.open('/etc/crontab', 'a') do |w|
|
12
|
+
LOG.info "Appending #{CONFIG[:cron_splay]} to /etc/crontab"
|
13
|
+
w.write CONFIG[:cron_splay]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
else
|
17
|
+
LOG.info "No crontab found, creating and adding #{CONFIG[:cron_splay]}"
|
18
|
+
File.open('/etc/crontab', 'wb') do |w|
|
19
|
+
w.write CONFIG[:cron_splay]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
module Marathon_template
|
2
|
+
class Deploy
|
3
|
+
def self.haproxy
|
4
|
+
test_haproxy_dir
|
5
|
+
write_haproxy_cfg
|
6
|
+
reload_haproxy_service
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.write_haproxy_cfg
|
10
|
+
File.open("#{CONFIG[:haproxy_path]}/haproxy.cfg", 'wb') do |f|
|
11
|
+
# Write out the global section
|
12
|
+
if CONFIG[:haproxy_global]
|
13
|
+
f.write "global\n"
|
14
|
+
CONFIG[:haproxy_global].each do |directive,values|
|
15
|
+
if values.kind_of?(Array)
|
16
|
+
values.each do |value|
|
17
|
+
f.write "\t#{directive} #{value}\n"
|
18
|
+
end
|
19
|
+
elsif values.kind_of?(Hash)
|
20
|
+
values.each do |k,v|
|
21
|
+
f.write "\t#{k} #{v}\n"
|
22
|
+
end
|
23
|
+
else
|
24
|
+
f.write "\t#{directive} #{values}\n"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
else
|
28
|
+
abort "Must pass global parameters in haproxy.yaml"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Write out the defaults section
|
32
|
+
if CONFIG[:haproxy_defaults]
|
33
|
+
f.write "defaults\n"
|
34
|
+
CONFIG[:haproxy_defaults].each do |directive,values|
|
35
|
+
if values.kind_of?(Array)
|
36
|
+
values.each do |value|
|
37
|
+
f.write "\t#{directive} #{value}\n"
|
38
|
+
end
|
39
|
+
elsif values.kind_of?(Hash)
|
40
|
+
values.each do |k,v|
|
41
|
+
f.write "\t#{k} #{v}\n"
|
42
|
+
end
|
43
|
+
else
|
44
|
+
f.write "\t#{directive} #{values}\n"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
else
|
48
|
+
abort "Must pass default parameters in haproxy.yaml"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Write out the listners sections
|
52
|
+
if CONFIG[:haproxy_listen]
|
53
|
+
CONFIG[:haproxy_listen].each do |listener, configuration|
|
54
|
+
f.write "listen #{listener}\n"
|
55
|
+
configuration.each do |setting, values|
|
56
|
+
if setting == 'server'
|
57
|
+
app_name = values['app_name']
|
58
|
+
options = values['options']
|
59
|
+
servers = get_servers(app_name)
|
60
|
+
LOG.info "#{app_name}: #{servers}"
|
61
|
+
servers.each do |host, port|
|
62
|
+
f.write "\t#{app_name} #{host}:#{port.first} #{options}\n"
|
63
|
+
end
|
64
|
+
elsif values.kind_of?(Array)
|
65
|
+
values.each do |value|
|
66
|
+
f.write "\t#{setting} #{value}\n"
|
67
|
+
end
|
68
|
+
elsif values.kind_of?(Hash)
|
69
|
+
values.each do |k,v|
|
70
|
+
f.write "\t#{k} #{v}\n"
|
71
|
+
end
|
72
|
+
else
|
73
|
+
f.write "\t#{setting} #{values}\n"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
# TODO include calling class to build servers
|
78
|
+
end
|
79
|
+
|
80
|
+
# Write out the frontends sections
|
81
|
+
if CONFIG[:haproxy_frontends]
|
82
|
+
CONFIG[:haproxy_frontends].each do |frontend, configuration|
|
83
|
+
f.write "frontend #{frontend}\n"
|
84
|
+
configuration.each do |setting, values|
|
85
|
+
if values.kind_of?(Array)
|
86
|
+
values.each do |value|
|
87
|
+
f.write "\t#{setting} #{value}\n"
|
88
|
+
end
|
89
|
+
elsif values.kind_of?(Hash)
|
90
|
+
values.each do |k,v|
|
91
|
+
f.write "\t#{k} #{v}\n"
|
92
|
+
end
|
93
|
+
else
|
94
|
+
f.write "\t#{setting} #{values}\n"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Write out the backends sections
|
101
|
+
if CONFIG[:haproxy_backends]
|
102
|
+
CONFIG[:haproxy_backends].each do |backend, configuration|
|
103
|
+
f.write "backend #{backend}\n"
|
104
|
+
configuration.each do |setting, values|
|
105
|
+
if setting == 'server'
|
106
|
+
app_name = values['app_name']
|
107
|
+
options = values['options']
|
108
|
+
servers = get_servers(app_name)
|
109
|
+
LOG.info "#{app_name}: #{servers}"
|
110
|
+
servers.each do |host, port|
|
111
|
+
f.write "\t#{app_name} #{host}:#{port.first} #{options}\n"
|
112
|
+
end
|
113
|
+
elsif values.kind_of?(Array)
|
114
|
+
values.each do |value|
|
115
|
+
f.write "\t#{setting} #{value}\n"
|
116
|
+
end
|
117
|
+
elsif values.kind_of?(Hash)
|
118
|
+
values.each do |k,v|
|
119
|
+
f.write "\t#{k} #{v}\n"
|
120
|
+
end
|
121
|
+
else
|
122
|
+
f.write "\t#{setting} #{values}\n"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.get_servers(app_name)
|
131
|
+
LOG.info "Getting host and port assignments for #{app_name}..."
|
132
|
+
marathon_app = "#{CONFIG[:marathon]}/v2/apps/#{app_name}"
|
133
|
+
encoded_uri = URI.encode(marathon_app.to_s)
|
134
|
+
uri = URI.parse(encoded_uri)
|
135
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
136
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
137
|
+
response = http.request(request)
|
138
|
+
|
139
|
+
if response.code == '200'
|
140
|
+
return_hash = Hash.new
|
141
|
+
json = JSON.parse(response.body)
|
142
|
+
tasks = json['app']['tasks']
|
143
|
+
tasks.each_with_index do |task, i|
|
144
|
+
return_hash[task['host']] = task['ports']
|
145
|
+
end
|
146
|
+
else
|
147
|
+
abort LOG.error "Failed connecting to #{@uri}, response code: #{response.code}"
|
148
|
+
end
|
149
|
+
return_hash
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.test_haproxy_dir
|
153
|
+
unless Dir.exists? CONFIG[:haproxy_path]
|
154
|
+
LOG.info "#{CONFIG[:haproxy_path]} not found, creating..."
|
155
|
+
Dir.mkdir CONFIG[:haproxy_path]
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.reload_haproxy_service
|
160
|
+
system("service haproxy reload")
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Marathon_template
|
2
|
+
class Options
|
3
|
+
def self.initialize(config_path)
|
4
|
+
|
5
|
+
# Env variable prefix
|
6
|
+
prefix = 'MARATHON_TEMPLATE_'
|
7
|
+
|
8
|
+
# Temp and instance vars for config
|
9
|
+
config_file = Hash.new
|
10
|
+
@config = Hash.new
|
11
|
+
|
12
|
+
unless File.exists? config_path
|
13
|
+
abort LOG.error "Config file not found! Please make sure #{config_path} exists."
|
14
|
+
end
|
15
|
+
|
16
|
+
file = YAML.load(File.open(config_path, 'r'))
|
17
|
+
file.each do |k,v|
|
18
|
+
config_file[k] = v
|
19
|
+
end
|
20
|
+
|
21
|
+
# Configuration
|
22
|
+
@config[:marathon] = config_file['marathon'] || 'localhost:8080'
|
23
|
+
@config[:haproxy_global] = config_file['haproxy']['global'] #|| abort "Must pass global options in haproxy.yaml"
|
24
|
+
@config[:haproxy_defaults] = config_file['haproxy']['defaults'] #|| abort "Must pass default options in haproxy.yaml"
|
25
|
+
@config[:haproxy_listen] = config_file['haproxy']['listens'] || nil
|
26
|
+
@config[:haproxy_frontends] = config_file['haproxy']['frontends'] || nil
|
27
|
+
@config[:haproxy_backends] = config_file['haproxy']['backends'] || nil
|
28
|
+
@config[:haproxy_path] = config_file['haproxy_path'] || '/etc/haproxy'
|
29
|
+
@config[:cron_splay] = config_file['cron_splay_time'] || '* * * * * marathon_template'
|
30
|
+
# Determine where HaProxy lives
|
31
|
+
# distro = IO.popen('uname').readlines
|
32
|
+
# if distro == 'Linux'
|
33
|
+
# @config[:distro] = distro
|
34
|
+
# else
|
35
|
+
# abort "Sorry, #{distro} is not supported."
|
36
|
+
# end
|
37
|
+
|
38
|
+
# @config.each do |k,v|
|
39
|
+
# LOG.info("#{k}: #{v}")
|
40
|
+
# end
|
41
|
+
@config
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/bin/env ruby
|
2
|
+
#$LOAD_PATH << '.'
|
3
|
+
begin
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'logger'
|
7
|
+
require 'json'
|
8
|
+
require 'yaml'
|
9
|
+
require 'net/http'
|
10
|
+
require_relative 'marathon-template/deploy'
|
11
|
+
require_relative 'marathon-template/cron'
|
12
|
+
require_relative 'marathon-template/options'
|
13
|
+
|
14
|
+
rescue Exception => e
|
15
|
+
|
16
|
+
puts "Failure during requires..."
|
17
|
+
puts e.message
|
18
|
+
puts e.backtrace
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
module Marathon_template
|
23
|
+
begin
|
24
|
+
# Set up logging to STDOUT
|
25
|
+
LOG = Logger.new(STDOUT)
|
26
|
+
|
27
|
+
# Get our config file
|
28
|
+
config_path = ENV['MARATHON_TEMPLATE_CONFIG_PATH'] || '/etc/haproxy.yaml'
|
29
|
+
|
30
|
+
# Create a usable hash of configuration
|
31
|
+
CONFIG = Marathon_template::Options.initialize(config_path)
|
32
|
+
|
33
|
+
# TODO Marathon_template::Install.haproxy
|
34
|
+
|
35
|
+
# Deploy haproxy.cfg
|
36
|
+
Marathon_template::Deploy.haproxy
|
37
|
+
|
38
|
+
# Configure Cron Job
|
39
|
+
Marathon_template::Cron.add
|
40
|
+
|
41
|
+
rescue Exception => e
|
42
|
+
puts e.backtrace
|
43
|
+
puts e.message
|
44
|
+
end
|
45
|
+
end
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: marathon-template
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeff Malnick
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-06 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
- malnick@gmail.com
|
16
|
+
executables:
|
17
|
+
- marathon-template
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/marathon_template.rb
|
22
|
+
- lib/marathon-template/deploy.rb
|
23
|
+
- lib/marathon-template/cron.rb
|
24
|
+
- lib/marathon-template/options.rb
|
25
|
+
- bin/marathon-template
|
26
|
+
homepage:
|
27
|
+
licenses:
|
28
|
+
- MIT
|
29
|
+
metadata: {}
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubyforge_project:
|
46
|
+
rubygems_version: 2.0.14
|
47
|
+
signing_key:
|
48
|
+
specification_version: 4
|
49
|
+
summary: Create dynamic haproxy configs from marathon resources
|
50
|
+
test_files: []
|