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 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,3 @@
1
+ #!/usr/bin/env ruby
2
+ #require File.expand_path(File.dirname(__FILE__)) + '/../lib/marathon_template'
3
+ require 'marathon_template'
@@ -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: []