consul-template-generator 0.1.0
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/.gitignore +8 -0
- data/.rspec +2 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +70 -0
- data/bin/consul-template-generator +81 -0
- data/consul-template-generator.gemspec +30 -0
- data/lib/consul/template/generator.rb +69 -0
- data/lib/consul/template/generator/cmd.rb +71 -0
- data/lib/consul/template/generator/configuration.rb +65 -0
- data/lib/consul/template/generator/ct.rb +23 -0
- data/lib/consul/template/generator/error.rb +7 -0
- data/lib/consul/template/generator/init.rb +17 -0
- data/lib/consul/template/generator/key_value.rb +42 -0
- data/lib/consul/template/generator/run.rb +38 -0
- data/lib/consul/template/generator/version.rb +7 -0
- data/spec/ct_spec.rb +44 -0
- data/spec/init_spec.rb +24 -0
- data/spec/key_value_spec.rb +103 -0
- data/spec/run_spec.rb +49 -0
- data/spec/spec_helper.rb +112 -0
- metadata +202 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ba8f1717006ac33f420edd8b83719bdb68aae412
|
4
|
+
data.tar.gz: c0069022ebf8e26f26565428d15d7d553b791169
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 63b020316a8f3291225f0ecc82e95e9ecd60b0a99205ecad5c5e8089c6c19c457422a292959fb724ee38dc60a9e1aea4e4b6b21924fe3fd2cb41fa1495ac29ae
|
7
|
+
data.tar.gz: 05eec4beb3cd09c1135ae92c59ded085fb678adec808ce483ff38f0fe35ead70510f439713c64a6e5bf0ebce7856ad205b2f7ed4e751cb17ba313b657bc0e6b4
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
consul-template-generator (0.1.0)
|
5
|
+
diplomat (~> 0.12.0)
|
6
|
+
popen4 (~> 0.1.2)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
Platform (0.4.0)
|
12
|
+
addressable (2.3.8)
|
13
|
+
colorize (0.7.7)
|
14
|
+
crack (0.4.2)
|
15
|
+
safe_yaml (~> 1.0.0)
|
16
|
+
diff-lcs (1.2.5)
|
17
|
+
diplomat (0.12.0)
|
18
|
+
faraday (~> 0.9)
|
19
|
+
json (~> 1.8)
|
20
|
+
docile (1.1.5)
|
21
|
+
faraday (0.9.1)
|
22
|
+
multipart-post (>= 1.2, < 3)
|
23
|
+
hirb (0.7.3)
|
24
|
+
json (1.8.3)
|
25
|
+
multipart-post (2.0.0)
|
26
|
+
open4 (1.3.4)
|
27
|
+
popen4 (0.1.2)
|
28
|
+
Platform (>= 0.4.0)
|
29
|
+
open4 (>= 0.4.0)
|
30
|
+
rack (1.6.1)
|
31
|
+
rake (10.4.2)
|
32
|
+
rspec (3.3.0)
|
33
|
+
rspec-core (~> 3.3.0)
|
34
|
+
rspec-expectations (~> 3.3.0)
|
35
|
+
rspec-mocks (~> 3.3.0)
|
36
|
+
rspec-core (3.3.0)
|
37
|
+
rspec-support (~> 3.3.0)
|
38
|
+
rspec-expectations (3.3.0)
|
39
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
40
|
+
rspec-support (~> 3.3.0)
|
41
|
+
rspec-mocks (3.3.0)
|
42
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
43
|
+
rspec-support (~> 3.3.0)
|
44
|
+
rspec-support (3.3.0)
|
45
|
+
safe_yaml (1.0.4)
|
46
|
+
simplecov (0.10.0)
|
47
|
+
docile (~> 1.1.0)
|
48
|
+
json (~> 1.8)
|
49
|
+
simplecov-html (~> 0.10.0)
|
50
|
+
simplecov-console (0.2.0)
|
51
|
+
colorize
|
52
|
+
hirb
|
53
|
+
simplecov
|
54
|
+
simplecov-html (0.10.0)
|
55
|
+
webmock (1.21.0)
|
56
|
+
addressable (>= 2.3.6)
|
57
|
+
crack (>= 0.3.2)
|
58
|
+
|
59
|
+
PLATFORMS
|
60
|
+
ruby
|
61
|
+
|
62
|
+
DEPENDENCIES
|
63
|
+
bundler (~> 1.7)
|
64
|
+
consul-template-generator!
|
65
|
+
rack (~> 1.6)
|
66
|
+
rake (~> 10.0)
|
67
|
+
rspec (~> 3.3)
|
68
|
+
simplecov (~> 0.10)
|
69
|
+
simplecov-console (~> 0.2)
|
70
|
+
webmock (~> 1.21)
|
@@ -0,0 +1,81 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
require 'consul/template/generator/cmd'
|
4
|
+
|
5
|
+
include Consul::Template::Generator
|
6
|
+
|
7
|
+
def verify_opts(opts)
|
8
|
+
!opts[:key].nil? && !opts[:template].nil?
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
options = {}
|
13
|
+
opt_parser = OptionParser.new do |opts|
|
14
|
+
opts.banner = <<EOC
|
15
|
+
consul-template-generator [options] <command>
|
16
|
+
|
17
|
+
Available commands:
|
18
|
+
once -- Run once and exit. On success, the rendered template will be inserted into the KV store whether or not it has changed.
|
19
|
+
run -- Run continually, uploading the rendered template when a change is detected.
|
20
|
+
|
21
|
+
Options:
|
22
|
+
EOC
|
23
|
+
|
24
|
+
options[:consul] = '127.0.0.1:8500'
|
25
|
+
opts.on('-c HOSTNAME', '--consul HOSTNAME', 'Hostname/port used to connect to consul [default: 127.0.0.1:8500]') do |h|
|
26
|
+
options[:consul] = h
|
27
|
+
end
|
28
|
+
|
29
|
+
options[:template] = nil
|
30
|
+
opts.on('-t TEMPLATE', '--template TEMPLATE', 'Consul-Template ctmpl file to monitor (required)') do |t|
|
31
|
+
options[:template] = t
|
32
|
+
end
|
33
|
+
|
34
|
+
options[:key] = nil
|
35
|
+
opts.on('-k KEY', '--key KEY', 'Key to store rendered template in (required)') do |k|
|
36
|
+
options[:key] = k
|
37
|
+
end
|
38
|
+
|
39
|
+
options[:proxy] = nil
|
40
|
+
opts.on('-p PROXY_URL', '--proxy PROXY_URL', 'Proxy URL if required (e.g. http://proxy.example.com:3128)') do |p|
|
41
|
+
options[:proxy] = p
|
42
|
+
end
|
43
|
+
|
44
|
+
options[:unset_proxy] = false
|
45
|
+
opts.on(nil, '--unset-proxy', "Use if 'http_proxy' is set in your environment, but you don't want to use it...") do |u|
|
46
|
+
options[:unset_proxy] = true
|
47
|
+
end
|
48
|
+
|
49
|
+
options[:log_level] = :info
|
50
|
+
opts.on('-l LOG_LEVEL', '--log-level LOG_LEVEL', "Log level, options are 'debug', 'info', 'error' [default: info]") do |l|
|
51
|
+
options[:log_level] = l.to_sym
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
opt_parser.parse!
|
56
|
+
|
57
|
+
unless verify_opts(options)
|
58
|
+
STDOUT.puts "Both '--key' and '--template' must be provided"
|
59
|
+
puts opt_parser
|
60
|
+
exit(1)
|
61
|
+
end
|
62
|
+
|
63
|
+
if options[:unset_proxy]
|
64
|
+
ENV['http_proxy'] = nil
|
65
|
+
end
|
66
|
+
|
67
|
+
CMD.configure(options[:consul], options[:template], options[:key], options[:log_level], options[:proxy])
|
68
|
+
|
69
|
+
ec = 1
|
70
|
+
cmd = ARGV[0]
|
71
|
+
case cmd
|
72
|
+
when 'run'
|
73
|
+
ec = CMD.run
|
74
|
+
when 'once'
|
75
|
+
ec = CMD.run_once
|
76
|
+
else
|
77
|
+
puts "Unknown command: #{cmd}"
|
78
|
+
puts opt_parser
|
79
|
+
end
|
80
|
+
|
81
|
+
exit(ec)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'consul/template/generator/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'consul-template-generator'
|
8
|
+
spec.version = Consul::Template::Generator::VERSION
|
9
|
+
spec.authors = ['Brian Oldfield']
|
10
|
+
spec.email = ['brian.oldfield@socrata.com']
|
11
|
+
spec.summary = %q{Wrapper around consul template which uploads renterd templates to consul's KV store}
|
12
|
+
spec.description = %q{When using complex consul-template templates or distributing them across many hosts, you run the risk of DoSing your consul cluster. Using consul-template-generator you can instead delegate the watching/rendering of templates to a single host and have downstream clients instead use a simple consul-template KV watch to retrieve the template and write it to disk.}
|
13
|
+
spec.homepage = 'http://github.com/boldfield/consul-template-generator'
|
14
|
+
spec.license = 'Apache'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/consul-template-generator}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
23
|
+
spec.add_development_dependency 'rspec', '~> 3.3'
|
24
|
+
spec.add_development_dependency 'simplecov', '~> 0.10'
|
25
|
+
spec.add_development_dependency 'simplecov-console', '~> 0.2'
|
26
|
+
spec.add_development_dependency 'webmock', '~> 1.21'
|
27
|
+
spec.add_development_dependency 'rack', '~> 1.6'
|
28
|
+
spec.add_dependency 'diplomat', '~> 0.12.0'
|
29
|
+
spec.add_dependency 'popen4', '~> 0.1.2'
|
30
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require_relative 'generator/cmd'
|
2
|
+
require_relative 'generator/ct'
|
3
|
+
require_relative 'generator/configuration'
|
4
|
+
require_relative 'generator/error'
|
5
|
+
require_relative 'generator/init'
|
6
|
+
require_relative 'generator/key_value'
|
7
|
+
require_relative 'generator/run'
|
8
|
+
require_relative 'generator/version'
|
9
|
+
|
10
|
+
require 'diplomat'
|
11
|
+
require 'faraday'
|
12
|
+
|
13
|
+
module Consul
|
14
|
+
module Template
|
15
|
+
module Generator
|
16
|
+
class << self
|
17
|
+
attr_accessor :config
|
18
|
+
attr_accessor :create_session, :renew_session, :destroy_session
|
19
|
+
def configure
|
20
|
+
self.config ||= Consul::Template::Generator::Configuration.new
|
21
|
+
self.config.node = `hostname`.strip
|
22
|
+
self.config.consul_host = '127.0.0.1:8500'
|
23
|
+
|
24
|
+
yield self.config
|
25
|
+
|
26
|
+
if self.config.consul_template_binary.nil?
|
27
|
+
ct_binary = `which consul-template`.strip
|
28
|
+
if ct_binary.empty?
|
29
|
+
raise "consul-template must be in your $PATH or configure the location to the executable"
|
30
|
+
end
|
31
|
+
self.config.consul_template_binary = ct_binary
|
32
|
+
end
|
33
|
+
|
34
|
+
if self.config.template.nil?
|
35
|
+
raise "template must be defined in configuration"
|
36
|
+
end
|
37
|
+
|
38
|
+
if self.config.template_key.nil?
|
39
|
+
raise "template_key must be defined in configuration"
|
40
|
+
end
|
41
|
+
|
42
|
+
Diplomat.configure do |config|
|
43
|
+
config.url = "http://#{self.config.consul_host}"
|
44
|
+
config.options = self.config.client_options
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_session(name)
|
49
|
+
Diplomat::Session.create({:Node => self.config.node, :Name => name})
|
50
|
+
end
|
51
|
+
|
52
|
+
def renew_session(sess_id)
|
53
|
+
# There is an outstanding bug in Diplomat::Session.renew with a PR to fix
|
54
|
+
# https://github.com/WeAreFarmGeek/diplomat/issues/43
|
55
|
+
# Until it's merged and release, we have to skip renewing sessions...
|
56
|
+
begin
|
57
|
+
#Diplomat::Session.renew sess_id
|
58
|
+
rescue Faraday::ResourceNotFound
|
59
|
+
raise ConsulSessionExpired
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def destroy_session(sess_id)
|
64
|
+
Diplomat::Session.destroy sess_id
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'consul/template/generator'
|
2
|
+
|
3
|
+
module Consul
|
4
|
+
module Template
|
5
|
+
module Generator
|
6
|
+
module CMD
|
7
|
+
include Consul::Template::Generator
|
8
|
+
|
9
|
+
def self.configure(consul_host, template, template_key, log_level, proxy = nil)
|
10
|
+
Consul::Template::Generator.configure do |config|
|
11
|
+
config.log_level = log_level
|
12
|
+
config.template = template
|
13
|
+
config.template_key = template_key
|
14
|
+
config.consul_host = consul_host
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.run
|
19
|
+
config = Consul::Template::Generator.config
|
20
|
+
uploaded_hash = nil
|
21
|
+
begin
|
22
|
+
runner = CTRunner.new
|
23
|
+
runner.acquire_session_lock do
|
24
|
+
config.logger.info "Session lock acquired..."
|
25
|
+
begin
|
26
|
+
uploaded_hash = runner.run(uploaded_hash) || uploaded_hash
|
27
|
+
sleep 5
|
28
|
+
rescue Interrupt
|
29
|
+
raise # Re-raise to break this rescue block
|
30
|
+
rescue ConsulSessionExpired
|
31
|
+
config.logger.error "The current consul session has expired."
|
32
|
+
break
|
33
|
+
rescue Exception => e
|
34
|
+
config.logger.error "An error occurred while updating template: #{e.message}"
|
35
|
+
config.logger.debug "Sleeping before attempting to update again..."
|
36
|
+
sleep 5
|
37
|
+
break
|
38
|
+
end until false
|
39
|
+
end
|
40
|
+
rescue Interrupt
|
41
|
+
config.logger.error "Recieved interrupt signal, exiting..."
|
42
|
+
break
|
43
|
+
rescue Exception => e
|
44
|
+
config.logger.info "Unable to obtain session lock: #{e.message}"
|
45
|
+
config.logger.debug "Sleeping before attempting lock session again..."
|
46
|
+
begin
|
47
|
+
sleep 5
|
48
|
+
rescue Interrupt
|
49
|
+
config.logger.error "Recieved interrupt signal, exiting..."
|
50
|
+
break
|
51
|
+
end
|
52
|
+
end until false
|
53
|
+
0
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.run_once
|
57
|
+
config = Consul::Template::Generator.config
|
58
|
+
begin
|
59
|
+
runner = CTRunner.new
|
60
|
+
result = runner.run
|
61
|
+
rescue Exception => e
|
62
|
+
config.logger.error "An unexpected error occurred, unable to process template: #{e.message}"
|
63
|
+
1
|
64
|
+
else
|
65
|
+
0
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Consul
|
2
|
+
module Template
|
3
|
+
module Generator
|
4
|
+
module STDLogLvl
|
5
|
+
class << self
|
6
|
+
def debug() 1 end
|
7
|
+
def info() 2 end
|
8
|
+
def error() 3 end
|
9
|
+
def off() 4 end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module STDLogger
|
14
|
+
class << self
|
15
|
+
def do_log?(requested_lvl, curr_lvl)
|
16
|
+
curr_lvl = Consul::Template::Generator::STDLogLvl.send(curr_lvl.to_sym)
|
17
|
+
requested_lvl = Consul::Template::Generator::STDLogLvl.send(requested_lvl.to_sym)
|
18
|
+
requested_lvl >= curr_lvl
|
19
|
+
end
|
20
|
+
|
21
|
+
def debug(msg)
|
22
|
+
if do_log?(:debug, Consul::Template::Generator.config.log_level)
|
23
|
+
STDOUT.puts "[DEBUG] #{msg}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def info(msg)
|
28
|
+
if do_log?(:info, Consul::Template::Generator.config.log_level)
|
29
|
+
STDOUT.puts "[INFO] #{msg}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def error(msg)
|
34
|
+
if do_log?(:error, Consul::Template::Generator.config.log_level)
|
35
|
+
STDERR.puts "[ERROR] #{msg}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Configuration
|
42
|
+
attr_accessor :template, :template_key, :consul_template_binary, :logger, :log_level
|
43
|
+
attr_accessor :consul_host, :node, :client_options
|
44
|
+
|
45
|
+
def initialize
|
46
|
+
@log_level = :debug
|
47
|
+
@node = nil
|
48
|
+
@consul_host = nil
|
49
|
+
@template = nil
|
50
|
+
@template_key = nil
|
51
|
+
@client_options = {}
|
52
|
+
@logger = Consul::Template::Generator::STDLogger
|
53
|
+
end
|
54
|
+
|
55
|
+
def lock_key
|
56
|
+
"/lock/#{@template_key.sub(/^\//, '')}"
|
57
|
+
end
|
58
|
+
|
59
|
+
def session_lock_key
|
60
|
+
"/lock/session/#{@template_key.sub(/^\//, '')}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'open4'
|
2
|
+
require 'digest'
|
3
|
+
|
4
|
+
module Consul
|
5
|
+
module Template
|
6
|
+
module Generator
|
7
|
+
class CTRunner
|
8
|
+
def render_template
|
9
|
+
body = nil
|
10
|
+
cmd = %{#{@config.consul_template_binary} -dry -once -template #{@config.template}}
|
11
|
+
procs = ::Open4.popen4(*cmd) do |pid, stdin, stdout, stderr|
|
12
|
+
body = stdout.read.strip
|
13
|
+
# consul-template -dry inserts '> \n' at the top of stdout, remove it
|
14
|
+
body.sub!(/^>\s+\n/, '')
|
15
|
+
end
|
16
|
+
status = procs.to_i
|
17
|
+
hash = ::Digest::MD5.hexdigest(body)
|
18
|
+
return status, body, hash
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Consul
|
2
|
+
module Template
|
3
|
+
module Generator
|
4
|
+
class CTRunner
|
5
|
+
attr_accessor :session
|
6
|
+
|
7
|
+
def initialize(consul_session_id = nil)
|
8
|
+
if consul_session_id.nil?
|
9
|
+
consul_session_id = Consul::Template::Generator.create_session 'consul-template-generator'
|
10
|
+
end
|
11
|
+
@session = consul_session_id
|
12
|
+
@config = Consul::Template::Generator.config
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'diplomat'
|
2
|
+
|
3
|
+
module Consul
|
4
|
+
module Template
|
5
|
+
module Generator
|
6
|
+
class CTRunner
|
7
|
+
|
8
|
+
def acquire_lock(lock_key = nil)
|
9
|
+
lock_key ||= @config.lock_key
|
10
|
+
@config.logger.debug "Attempting to acquire lock on key: #{lock_key}"
|
11
|
+
Consul::Template::Generator.renew_session @session
|
12
|
+
unless Diplomat::Lock.acquire(lock_key, @session)
|
13
|
+
raise KeyNotLockedError, "Unable to acquire lock on key: #{lock_key}"
|
14
|
+
end
|
15
|
+
@config.logger.debug "Lock acquired on key: #{lock_key}"
|
16
|
+
|
17
|
+
begin
|
18
|
+
yield
|
19
|
+
ensure
|
20
|
+
Diplomat::Lock.release(lock_key, @session)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def acquire_session_lock
|
25
|
+
acquire_lock(@config.session_lock_key) do
|
26
|
+
yield
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def upload_template(raw_template)
|
31
|
+
@config.logger.info "Uploading key: #{@config.template_key}"
|
32
|
+
begin
|
33
|
+
Diplomat::Kv.put(@config.template_key, raw_template)
|
34
|
+
rescue Exception => e
|
35
|
+
raise TemplateUploadError, "Encountered an unexpected error while uploading template: #{e.message}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'consul/template/generator/ct'
|
2
|
+
|
3
|
+
module Consul
|
4
|
+
module Template
|
5
|
+
module Generator
|
6
|
+
class CTRunner
|
7
|
+
def run(comp_hash = nil)
|
8
|
+
status, body, hash, uploaded_hash = nil, nil, nil, nil
|
9
|
+
acquire_lock do
|
10
|
+
@config.logger.debug "Attempting to render template: #{@config.template}"
|
11
|
+
status, body, hash = render_template
|
12
|
+
unless status == 0
|
13
|
+
raise TemplateRenderError, "consul-template exited with on-zero exit status"
|
14
|
+
end
|
15
|
+
if body.nil? || body.empty?
|
16
|
+
raise TemplateRenderError, "rendered template is nil or empty!"
|
17
|
+
end
|
18
|
+
@config.logger.debug "Template rendered..."
|
19
|
+
if comp_hash.nil? || comp_hash != hash
|
20
|
+
@config.logger.info "Change in template discovered, attempting to upload to key #{@config.template_key}"
|
21
|
+
@config.logger.debug "Existing hash: #{comp_hash || 'nil'}, new hash: #{hash}"
|
22
|
+
uploaded = upload_template(body)
|
23
|
+
if uploaded
|
24
|
+
@config.logger.info "New template uploaded..."
|
25
|
+
uploaded_hash = hash
|
26
|
+
else
|
27
|
+
raise TemplateUploadError, "Template not uploaded!"
|
28
|
+
end
|
29
|
+
else
|
30
|
+
@config.logger.info "No change in template, skipping upload..."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
return uploaded_hash
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/spec/ct_spec.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
require 'open4'
|
5
|
+
require 'consul/template/generator'
|
6
|
+
|
7
|
+
include Consul::Template::Generator
|
8
|
+
|
9
|
+
def setup_open4(stdout, exit_code, pid)
|
10
|
+
@pid = pid
|
11
|
+
@status = exit_code
|
12
|
+
@stdin = StringIO.new
|
13
|
+
@stdout = StringIO.new
|
14
|
+
@stderr = StringIO.new
|
15
|
+
|
16
|
+
@stdout_string = "> \n#{stdout}"
|
17
|
+
|
18
|
+
@stdout << stdout
|
19
|
+
@stdout.rewind
|
20
|
+
|
21
|
+
allow(Open4).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'Consul::Template::Generator::CTRunner' '#render_template' do
|
25
|
+
before do
|
26
|
+
Consul::Template::Generator.configure do |config|
|
27
|
+
config.template = '/etc/test-template.ctmpl'
|
28
|
+
config.template_key = '/test-template'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'render template' do
|
33
|
+
it 'runs successfully' do
|
34
|
+
exp_out = 'this is a test'
|
35
|
+
exp_hash = '54b0c58c7ce9f2a8b551351102ee0938'
|
36
|
+
setup_open4(exp_out, 0, 101)
|
37
|
+
runner = CTRunner.new('test-session')
|
38
|
+
exit_code, body, hash = runner.render_template
|
39
|
+
expect(body).to eql(exp_out)
|
40
|
+
expect(hash).to eql(exp_hash)
|
41
|
+
expect(exit_code).to eql(@status)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/spec/init_spec.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'webmock'
|
3
|
+
|
4
|
+
require 'consul/template/generator'
|
5
|
+
|
6
|
+
include Consul::Template::Generator
|
7
|
+
|
8
|
+
describe 'Consul::Template::Generator::CTRunner' '#initialize' do
|
9
|
+
before do
|
10
|
+
Consul::Template::Generator.configure do |config|
|
11
|
+
config.template = 'test-session-template.ctmpl'
|
12
|
+
config.template_key = 'test-session-template'
|
13
|
+
config.node = 'test-node'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'initialization of Consul::Template::Generator::CTRunner' do
|
18
|
+
it "creates session if token isn't passed" do
|
19
|
+
@runner = Consul::Template::Generator::CTRunner.new
|
20
|
+
expect(WebMock).to_not have_requested(:put, 'http://127.0.0.1:8500/v1/kv/session/create').with(:body => "{\"Node\": \"test-node\", \"Name\": \"consul-template-generator\"}")
|
21
|
+
expect(@runner.session).to eql('test-session-id')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stringio'
|
3
|
+
require 'webmock'
|
4
|
+
|
5
|
+
require 'open4'
|
6
|
+
require 'consul/template/generator'
|
7
|
+
|
8
|
+
include Consul::Template::Generator
|
9
|
+
|
10
|
+
describe 'Consul::Template::Generator::CTRunner' '#acquire_lock' do
|
11
|
+
before do
|
12
|
+
Consul::Template::Generator.configure do |config|
|
13
|
+
config.template = 'test-template.ctmpl'
|
14
|
+
config.template_key = '/test-template'
|
15
|
+
config.consul_host = '127.0.0.1:8500'
|
16
|
+
config.log_level = :off
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'aquires lock' do
|
21
|
+
it 'clean lock acquisision' do
|
22
|
+
runner = CTRunner.new('test-session')
|
23
|
+
runner.acquire_lock do
|
24
|
+
expect(true).to be_truthy ## This is simply to assert we are able to execute code in the block
|
25
|
+
end
|
26
|
+
expect(WebMock).to have_requested(:put, 'http://127.0.0.1:8500/v1/kv/lock/test-template').with(:query => {:acquire => 'test-session'})
|
27
|
+
expect(WebMock).to have_requested(:put, 'http://127.0.0.1:8500/v1/kv/lock/test-template').with(:query => {:release => 'test-session'})
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'handles being unable to acquire lock' do
|
31
|
+
runner = CTRunner.new('test-session-lock-fail')
|
32
|
+
expect { runner.acquire_lock { puts 'hi' } }.to raise_error(KeyNotLockedError)
|
33
|
+
expect(WebMock).to have_requested(:put, 'http://127.0.0.1:8500/v1/kv/lock/test-template').with(:query => {:acquire => 'test-session-lock-fail'})
|
34
|
+
expect(WebMock).to_not have_requested(:put, 'http://127.0.0.1:8500/v1/kv/lock/test-template').with(:query => {:release => 'test-session-lock-fail'})
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'Consul::Template::Generator::CTRunner' '#acquire_session_lock' do
|
40
|
+
before do
|
41
|
+
Consul::Template::Generator.configure do |config|
|
42
|
+
config.template = 'test-template.ctmpl'
|
43
|
+
config.template_key = '/test-template'
|
44
|
+
config.consul_host = '127.0.0.1:8500'
|
45
|
+
config.log_level = :off
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'aquires session lock' do
|
50
|
+
it 'clean lock acquisision' do
|
51
|
+
runner = CTRunner.new('test-session')
|
52
|
+
runner.acquire_session_lock do
|
53
|
+
expect(true).to be_truthy ## This is simply to assert we are able to execute code in the block
|
54
|
+
end
|
55
|
+
expect(WebMock).to have_requested(:put, 'http://127.0.0.1:8500/v1/kv/lock/session/test-template').with(:query => {:acquire => 'test-session'})
|
56
|
+
expect(WebMock).to have_requested(:put, 'http://127.0.0.1:8500/v1/kv/lock/session/test-template').with(:query => {:release => 'test-session'})
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'handles being unable to acquire session lock' do
|
60
|
+
runner = CTRunner.new('test-session-lock-fail')
|
61
|
+
expect { runner.acquire_session_lock { puts 'hi' } }.to raise_error(KeyNotLockedError)
|
62
|
+
expect(WebMock).to have_requested(:put, 'http://127.0.0.1:8500/v1/kv/lock/session/test-template').with(:query => {:acquire => 'test-session-lock-fail'})
|
63
|
+
expect(WebMock).to_not have_requested(:put, 'http://127.0.0.1:8500/v1/kv/session/lock/test-template').with(:query => {:release => 'test-session-lock-fail'})
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'Consul::Template::Generator::CTRunner' '#upload_template' do
|
69
|
+
context 'uploads template' do
|
70
|
+
before do
|
71
|
+
Consul::Template::Generator.configure do |config|
|
72
|
+
config.template = 'test-template.ctmpl'
|
73
|
+
config.template_key = '/test-template'
|
74
|
+
config.consul_host = '127.0.0.1:8500'
|
75
|
+
config.log_level = :off
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'does a clean upload' do
|
80
|
+
runner = CTRunner.new('test-session')
|
81
|
+
success = runner.upload_template('this is a test')
|
82
|
+
expect(success).to be_truthy
|
83
|
+
expect(WebMock).to have_requested(:put, 'http://127.0.0.1:8500/v1/kv/test-template').with(:body => 'this is a test')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'handles template upload failure' do
|
88
|
+
before do
|
89
|
+
Consul::Template::Generator.configure do |config|
|
90
|
+
config.template = 'test-template.ctmpl'
|
91
|
+
config.template_key = '/test-template-failure'
|
92
|
+
config.consul_host = '127.0.0.1:8500'
|
93
|
+
config.log_level = :off
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'does a clean upload' do
|
98
|
+
runner = CTRunner.new('test-session')
|
99
|
+
expect { runner.upload_template('this is a fail test') }.to raise_error(TemplateUploadError)
|
100
|
+
expect(WebMock).to have_requested(:put, 'http://127.0.0.1:8500/v1/kv/test-template-failure').with(:body => 'this is a fail test')
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/spec/run_spec.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'consul/template/generator'
|
4
|
+
|
5
|
+
include Consul::Template::Generator
|
6
|
+
|
7
|
+
describe 'Consul::Template::Generator::CTRunner' '#run' do
|
8
|
+
before do
|
9
|
+
@runner = Consul::Template::Generator::CTRunner.new 'test-session'
|
10
|
+
allow(@runner).to receive(:acquire_lock).and_yield
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'run' do
|
14
|
+
it 'handles a clean run' do
|
15
|
+
exp_hash = 'bbf9afe7431caf5f89a608bc31e8d822'
|
16
|
+
expect(@runner).to receive(:render_template).with(no_args).and_return([0, 'test body', exp_hash])
|
17
|
+
expect(@runner).to receive(:upload_template).with('test body').and_return(true)
|
18
|
+
hash = @runner.run
|
19
|
+
expect(hash).to eql(exp_hash)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "does't upload unchanged template" do
|
23
|
+
exp_hash = 'bbf9afe7431caf5f89a608bc31e8d822'
|
24
|
+
expect(@runner).to receive(:render_template).with(no_args).and_return([0, 'test body', exp_hash])
|
25
|
+
expect(@runner).not_to receive(:upload_template)
|
26
|
+
hash = @runner.run exp_hash
|
27
|
+
expect(hash).to be_nil
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'handles non-zero exit status' do
|
31
|
+
expect(@runner).to receive(:render_template).with(no_args).and_return([1, 'not used', 'not used'])
|
32
|
+
expect(@runner).not_to receive(:upload_template)
|
33
|
+
expect { @runner.run }.to raise_exception(TemplateRenderError)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'handles empty rendered template' do
|
37
|
+
expect(@runner).to receive(:render_template).with(no_args).and_return([0, '', 'not used'])
|
38
|
+
expect(@runner).not_to receive(:upload_template)
|
39
|
+
expect { @runner.run }.to raise_exception(TemplateRenderError)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'handles bad return from upload_template' do
|
43
|
+
exp_hash = 'bbf9afe7431caf5f89a608bc31e8d822'
|
44
|
+
expect(@runner).to receive(:render_template).with(no_args).and_return([0, 'test body', exp_hash])
|
45
|
+
expect(@runner).to receive(:upload_template).with('test body').and_return(false)
|
46
|
+
expect { @runner.run }.to raise_exception(TemplateUploadError)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
4
|
+
# this file to always be loaded, without a need to explicitly require it in any
|
5
|
+
# files.
|
6
|
+
#
|
7
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
8
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
9
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
10
|
+
# individual file that may not need all of that loaded. Instead, consider making
|
11
|
+
# a separate helper file that requires the additional dependencies and performs
|
12
|
+
# the additional setup, and require it from the spec files that actually need
|
13
|
+
# it.
|
14
|
+
#
|
15
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
16
|
+
# users commonly want.
|
17
|
+
#
|
18
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
19
|
+
require 'webmock/rspec'
|
20
|
+
require 'rack'
|
21
|
+
require 'simplecov'
|
22
|
+
require 'simplecov-console'
|
23
|
+
|
24
|
+
WebMock.disable_net_connect!(allow_localhost: false)
|
25
|
+
DIR = File.expand_path(File.dirname(__FILE__))
|
26
|
+
|
27
|
+
class ConsulApiRack
|
28
|
+
def call(env)
|
29
|
+
code, ret = 500, 'The tests have changed, fix the rack'
|
30
|
+
case env['PATH_INFO']
|
31
|
+
when /\/v1\/session\/create/
|
32
|
+
code, ret = 200, "{\"ID\": \"test-session-id\"}"
|
33
|
+
when /\/v1\/kv\/lock\//
|
34
|
+
code, ret = process_lock(env['QUERY_STRING'])
|
35
|
+
when /\/v1\/kv\//
|
36
|
+
code, ret = process_upload(env['PATH_INFO'])
|
37
|
+
end
|
38
|
+
[code, { 'Content-Type' => 'application/json' }, [ret]]
|
39
|
+
end
|
40
|
+
|
41
|
+
def process_upload(path)
|
42
|
+
code, ret = 500, 'The tests have changed, fix the rack'
|
43
|
+
case path
|
44
|
+
when /^\/v1\/kv\/test-template$/
|
45
|
+
code, ret = 200, 'true'
|
46
|
+
when /^\/v1\/kv\/test-template-failure$/
|
47
|
+
code, ret = 500, 'false'
|
48
|
+
end
|
49
|
+
return code, ret
|
50
|
+
end
|
51
|
+
|
52
|
+
def process_lock(qs)
|
53
|
+
code, ret = 500, 'The tests have changed, fix the rack'
|
54
|
+
case qs
|
55
|
+
when /^acquire=test-session$/
|
56
|
+
code, ret = 200, 'true'
|
57
|
+
when /^acquire=test-session-lock-fail$/
|
58
|
+
code, ret = 200, 'false'
|
59
|
+
when /release=test-session/
|
60
|
+
code, ret = 200, 'true'
|
61
|
+
end
|
62
|
+
return code, ret
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
RSpec.configure do |config|
|
67
|
+
# rspec-expectations config goes here. You can use an alternate
|
68
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
69
|
+
# assertions if you prefer.
|
70
|
+
config.expect_with :rspec do |expectations|
|
71
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
72
|
+
# and `failure_message` of custom matchers include text for helper methods
|
73
|
+
# defined using `chain`, e.g.:
|
74
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
75
|
+
# # => "be bigger than 2 and smaller than 4"
|
76
|
+
# ...rather than:
|
77
|
+
# # => "be bigger than 2"
|
78
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
79
|
+
end
|
80
|
+
|
81
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
82
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
83
|
+
config.mock_with :rspec do |mocks|
|
84
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
85
|
+
# a real object. This is generally recommended, and will default to
|
86
|
+
# `true` in RSpec 4.
|
87
|
+
mocks.verify_partial_doubles = true
|
88
|
+
end
|
89
|
+
config.before(:each) do
|
90
|
+
stub_request(:any, /127.0.0.1:8500\//).
|
91
|
+
to_rack(ConsulApiRack.new)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
97
|
+
SimpleCov::Formatter::HTMLFormatter,
|
98
|
+
SimpleCov::Formatter::Console
|
99
|
+
]
|
100
|
+
SimpleCov.minimum_coverage(85)
|
101
|
+
SimpleCov.start
|
102
|
+
|
103
|
+
def capture_stdout(&block)
|
104
|
+
original_stdout = $stdout
|
105
|
+
$stdout = fake = StringIO.new
|
106
|
+
begin
|
107
|
+
yield
|
108
|
+
ensure
|
109
|
+
$stdout = original_stdout
|
110
|
+
end
|
111
|
+
#fake.string
|
112
|
+
end
|
metadata
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: consul-template-generator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brian Oldfield
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.10'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.10'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov-console
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.2'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.2'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: webmock
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.21'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.21'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rack
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.6'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.6'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: diplomat
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.12.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ~>
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.12.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: popen4
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ~>
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 0.1.2
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ~>
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 0.1.2
|
139
|
+
description: When using complex consul-template templates or distributing them across
|
140
|
+
many hosts, you run the risk of DoSing your consul cluster. Using consul-template-generator
|
141
|
+
you can instead delegate the watching/rendering of templates to a single host and
|
142
|
+
have downstream clients instead use a simple consul-template KV watch to retrieve
|
143
|
+
the template and write it to disk.
|
144
|
+
email:
|
145
|
+
- brian.oldfield@socrata.com
|
146
|
+
executables:
|
147
|
+
- consul-template-generator
|
148
|
+
extensions: []
|
149
|
+
extra_rdoc_files: []
|
150
|
+
files:
|
151
|
+
- .gitignore
|
152
|
+
- .rspec
|
153
|
+
- Gemfile
|
154
|
+
- Gemfile.lock
|
155
|
+
- bin/consul-template-generator
|
156
|
+
- consul-template-generator.gemspec
|
157
|
+
- lib/consul/template/generator.rb
|
158
|
+
- lib/consul/template/generator/cmd.rb
|
159
|
+
- lib/consul/template/generator/configuration.rb
|
160
|
+
- lib/consul/template/generator/ct.rb
|
161
|
+
- lib/consul/template/generator/error.rb
|
162
|
+
- lib/consul/template/generator/init.rb
|
163
|
+
- lib/consul/template/generator/key_value.rb
|
164
|
+
- lib/consul/template/generator/run.rb
|
165
|
+
- lib/consul/template/generator/version.rb
|
166
|
+
- spec/ct_spec.rb
|
167
|
+
- spec/init_spec.rb
|
168
|
+
- spec/key_value_spec.rb
|
169
|
+
- spec/run_spec.rb
|
170
|
+
- spec/spec_helper.rb
|
171
|
+
homepage: http://github.com/boldfield/consul-template-generator
|
172
|
+
licenses:
|
173
|
+
- Apache
|
174
|
+
metadata: {}
|
175
|
+
post_install_message:
|
176
|
+
rdoc_options: []
|
177
|
+
require_paths:
|
178
|
+
- lib
|
179
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
180
|
+
requirements:
|
181
|
+
- - '>='
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: '0'
|
184
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
|
+
requirements:
|
186
|
+
- - '>='
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '0'
|
189
|
+
requirements: []
|
190
|
+
rubyforge_project:
|
191
|
+
rubygems_version: 2.4.6
|
192
|
+
signing_key:
|
193
|
+
specification_version: 4
|
194
|
+
summary: Wrapper around consul template which uploads renterd templates to consul's
|
195
|
+
KV store
|
196
|
+
test_files:
|
197
|
+
- spec/ct_spec.rb
|
198
|
+
- spec/init_spec.rb
|
199
|
+
- spec/key_value_spec.rb
|
200
|
+
- spec/run_spec.rb
|
201
|
+
- spec/spec_helper.rb
|
202
|
+
has_rdoc:
|