tiller 0.6.5 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 84545c02ddcde99810a6d2ee136b5e4adbee3e78
4
- data.tar.gz: 5e020f6ed206820dac9a6ebc7d18e1c8b4664bcc
3
+ metadata.gz: 12faf0d88c087dc054ed45bd12efa2bfa00d2855
4
+ data.tar.gz: d6090c27d9b79d5e81d8ab28caa6813e63353b4d
5
5
  SHA512:
6
- metadata.gz: f9995b6f18d95eb664fcc0ff5be3a2c0e877d596271e8123edbde3111c9975b773f800236fcc7fc1e98e3fcc50f5d1c1f3d56bbc22de9155bb9e406bb4ecfa50
7
- data.tar.gz: e0bad75d72c44062d342aff43c2576faa154f645d85038a9127c00e1f07e8bb8aebd28ea7a74aaf63105a10752be2bea447fe562ac7875c6825538b4feb0e422
6
+ metadata.gz: be7556477a6d78f0aa09802039c3a3fba01b10b1cb5a94569ac25dd459d9e8ebdaf0bca6b14752f0f162f4265a598b0d76d988b38cffb62a4e27874fa180e624
7
+ data.tar.gz: 818392cdf2ceb0b306bad4acdf22790e06fd8d3e7c0c208142bcd9e89441ea67e96f6a714b2372886a16a3eb7427d52e0102c11978ef01c0d412b60e3a8ae70a
data/bin/tiller CHANGED
@@ -8,7 +8,7 @@
8
8
  #
9
9
  # Mark Dastmalchi-Round <github@markround.com>
10
10
 
11
- VERSION = '0.6.5'
11
+ VERSION = '0.7.0'
12
12
 
13
13
  require 'erb'
14
14
  require 'ostruct'
@@ -25,6 +25,7 @@ require 'tiller/options'
25
25
  require 'tiller/util'
26
26
  require 'tiller/templatesource'
27
27
  require 'tiller/datasource'
28
+ require 'tiller/logger'
28
29
 
29
30
  # And we're on our way...
30
31
  module Tiller
@@ -32,30 +33,43 @@ module Tiller
32
33
  puts "tiller v#{VERSION} (https://github.com/markround/tiller) <github@markround.com>"
33
34
 
34
35
  config = parse_options(Tiller::Defaults)
36
+ log = Tiller::Logger.new(config)
37
+
38
+ log.debug("Executable: #{__FILE__}")
39
+
35
40
 
36
41
  # Add tiller_lib to the LOAD PATH so we can pull in user-defined plugins
37
42
  $LOAD_PATH.unshift(config[:tiller_lib]) unless $LOAD_PATH.include?(config[:tiller_lib])
38
43
 
39
44
  # Load the common YAML configuration file
40
- config.merge!(YAML.load(open(File.join(config[:tiller_base], 'common.yaml'))))
45
+ begin
46
+ common_file = File.join(config[:tiller_base], 'common.yaml')
47
+ config.merge!(YAML.load(open(common_file)))
48
+ rescue Exception => e
49
+ abort "Error : Could not open common configuration file!\n#{e}"
50
+ end
51
+
52
+ # Check for keys only present in v2 format (everything in one common.yaml)
53
+ if [ 'environments' , 'defaults'].any? { |k| config.has_key?(k) }
54
+ log.info("Using common.yaml v2 format configuration file")
55
+ config[:config_version] = 2
56
+ else
57
+ config[:config_version] = 1
58
+ end
41
59
 
42
60
  # Set the environment if not already done through ENV or -e flag
43
61
  config[:environment] = config['default_environment'] if config[:environment].nil?
44
62
 
45
- if config[:verbose]
46
- puts "Using configuration from #{config[:tiller_base]}"
47
- puts "Using plugins from #{config[:tiller_lib]}/tiller"
48
- puts "Using environment #{config[:environment]}"
49
- end
63
+ log.info("Using configuration from #{config[:tiller_base]}")
64
+ log.info("Using plugins from #{config[:tiller_lib]}/tiller")
65
+ log.info("Using environment #{config[:environment]}")
50
66
 
51
67
  # Now load all our plugins
52
68
  data_classes = loader(DataSource, config['data_sources'])
53
69
  template_classes = loader(TemplateSource, config['template_sources'])
54
70
 
55
- if config[:verbose]
56
- puts 'Template sources loaded ' + template_classes.to_s
57
- puts 'Data sources loaded ' + data_classes.to_s
58
- end
71
+ log.info('Template sources loaded ' + template_classes.to_s)
72
+ log.info('Data sources loaded ' + data_classes.to_s)
59
73
 
60
74
  # Now go through all our data sources and start to assemble our global_values
61
75
  # hash. As hashes are getting merged, new values will take precedence over
@@ -86,7 +100,7 @@ module Tiller
86
100
  end
87
101
  end
88
102
 
89
- puts "Templates to build #{templates.keys}" if config[:verbose]
103
+ log.info("Templates to build #{templates.keys}")
90
104
 
91
105
  # Now we go through each template we've identified, and get the
92
106
  # values for each one.
@@ -97,6 +111,8 @@ module Tiller
97
111
  tiller = global_values
98
112
  target_values = {}
99
113
 
114
+ # Todo: add in our values from common.yaml here if they exist
115
+
100
116
  # Now we add to the 'tiller' hash with values from each DataSource, warning if we
101
117
  # get duplicate values.
102
118
  data_classes.each do |data_class|
@@ -119,7 +135,7 @@ module Tiller
119
135
  next if target_values.empty?
120
136
 
121
137
  # Now, we build the template
122
- puts "Building template #{template}" if config[:verbose]
138
+ log.info("Building template #{template}")
123
139
 
124
140
  # Use an OpenStruct namespace, as it's way easier than faffing around with
125
141
  # manual binding, and also non-existing values just get replaced by <nil>
@@ -143,7 +159,7 @@ module Tiller
143
159
 
144
160
  # Set permissions if we are running as root
145
161
  if Process::Sys.geteuid == 0
146
- puts "Setting ownership/permissions on #{target_values['target']}" if config[:verbose]
162
+ log.info("Setting ownership/permissions on #{target_values['target']}")
147
163
  if target_values.key?('perms')
148
164
  FileUtils.chmod(target_values['perms'], target_values['target'])
149
165
  end
@@ -152,8 +168,8 @@ module Tiller
152
168
  FileUtils.chown(target_values['user'], target_values['group'],
153
169
  target_values['target'])
154
170
  else
155
- puts 'Not running as root, so not setting ownership/permissions on ' \
156
- "#{target_values['target']}" if config[:verbose]
171
+ log.info('Not running as root, so not setting ownership/permissions on ' \
172
+ "#{target_values['target']}")
157
173
  end
158
174
 
159
175
  end
@@ -169,7 +185,7 @@ module Tiller
169
185
 
170
186
  # Override the exec if run with -x (see options.rb)
171
187
  if config.has_key?(:alt_exec)
172
- puts "Overriding exec parameter [#{config['exec']}] with [#{config[:alt_exec]}]" if config[:verbose]
188
+ log.info("Overriding exec parameter [#{config['exec']}] with [#{config[:alt_exec]}]")
173
189
  config['exec'] = config[:alt_exec]
174
190
  end
175
191
 
@@ -180,7 +196,7 @@ module Tiller
180
196
  # Spawn and wait so API can continue to run
181
197
  child_pid = launch(config['exec'], :verbose => config[:verbose])
182
198
 
183
- puts "Child process forked with PID #{child_pid}." if config[:verbose]
199
+ log.info("Child process forked with PID #{child_pid}.")
184
200
 
185
201
  # Catch signals and send them on to the child process
186
202
  [ :INT, :TERM, :HUP ].each do |sig|
@@ -189,7 +205,7 @@ module Tiller
189
205
 
190
206
  Process.wait(child_pid)
191
207
 
192
- puts 'Child process finished, Tiller is stopping.' if config[:verbose]
208
+ log.info('Child process finished, Tiller is stopping.')
193
209
  end
194
210
 
195
211
  end
@@ -16,17 +16,25 @@ class DefaultsDataSource < Tiller::DataSource
16
16
  defaults_dir = File.join(@config[:tiller_base], 'defaults.d')
17
17
  @defaults_hash = Hash.new
18
18
 
19
- # Read defaults in from defaults file
20
- # Handle empty files - if YAML didn't parse, it returns false so we skip them
21
- if File.file? defaults_file
22
- yaml = YAML.load(open(defaults_file))
23
- @defaults_hash.deep_merge!(yaml) if yaml != false
19
+ # First, try and load defaults from v2 config
20
+ if @config.has_key?('defaults')
21
+ @log.debug("#{self} : Using values from v2 format common.yaml")
22
+ @defaults_hash.deep_merge!(@config['defaults'])
23
+ else
24
+ # Read defaults in from defaults file if no v2 config
25
+ # Handle empty files - if YAML didn't parse, it returns false so we skip them
26
+ if File.file? defaults_file
27
+ yaml = YAML.load(open(defaults_file))
28
+ @defaults_hash.deep_merge!(yaml) if yaml != false
29
+ end
24
30
  end
25
31
 
26
32
  # If we have YAML files in defaults.d, also merge them
33
+ # We do this even if the main defaults were loaded from the v2 format config
27
34
  if File.directory? defaults_dir
28
35
  Dir.glob(File.join(defaults_dir,'*.yaml')).each do |d|
29
36
  yaml = YAML.load(open(d))
37
+ @log.debug("Loading defaults from #{d}")
30
38
  @defaults_hash.deep_merge!(yaml) if yaml != false
31
39
  end
32
40
  end
@@ -13,7 +13,7 @@ class EnvironmentJsonDataSource < Tiller::DataSource
13
13
  json_structure = JSON.parse(ENV['tiller_json'])
14
14
  json_structure if json_structure.is_a?(Hash)
15
15
  rescue JSON::ParserError
16
- puts "Warning : Error parsing tiller_json environment variable"
16
+ @log.warn('Warning : Error parsing tiller_json environment variable')
17
17
  Hash.new
18
18
  end
19
19
  else
@@ -6,11 +6,27 @@ require 'yaml'
6
6
  #
7
7
  # We also don't provide any global values, just ones specific to a template.
8
8
  class FileDataSource < Tiller::DataSource
9
- # Open and parse the environment file
9
+ # Open and parse the environment file. Tries from v2 format common.yaml first, if that
10
+ # failes, then it looks for separate environment files.
10
11
  def setup
11
- env_file = File.join(@config[:tiller_base], 'environments',
12
- "#{@config[:environment]}.yaml")
13
- @config_hash = YAML.load(open(env_file))
12
+ if @config.has_key?('environments')
13
+ # Try and load from v2 format common.yaml
14
+ if @config['environments'].has_key?(@config[:environment])
15
+ @log.debug("#{self} : Using values from v2 format common.yaml")
16
+ @config_hash = @config['environments'][@config[:environment]]
17
+ else
18
+ abort("Error : Could not load environment #{@config[:environment]} from common.yaml")
19
+ end
20
+ else
21
+ # Try and load from v1 format files
22
+ begin
23
+ env_file = File.join(@config[:tiller_base], 'environments',
24
+ "#{@config[:environment]}.yaml")
25
+ @config_hash = YAML.load(open(env_file))
26
+ rescue
27
+ abort ("Error : Could not load environment file #{env_file}")
28
+ end
29
+ end
14
30
  end
15
31
 
16
32
  def common
@@ -36,7 +36,7 @@ class ZookeeperDataSource < Tiller::DataSource
36
36
 
37
37
  def global_values
38
38
  path = @zk_config['values']['global'].gsub('%e',@config[:environment])
39
- puts "Fetching Zookeeper globals from #{path}" if @config[:verbose]
39
+ @log.info("Fetching Zookeeper globals from #{path}")
40
40
  get_values(path)
41
41
  end
42
42
 
@@ -1,3 +1,5 @@
1
+ require 'tiller/logger'
2
+
1
3
  # Tiller data source base class.
2
4
  module Tiller
3
5
  # Subclasses provide global_values and/or values (things local to a specific
@@ -10,6 +12,7 @@ module Tiller
10
12
 
11
13
  def initialize(config)
12
14
  @config = config
15
+ @log = Tiller::Logger.new(config)
13
16
  setup
14
17
  end
15
18
 
data/lib/tiller/http.rb CHANGED
@@ -23,14 +23,14 @@ module Tiller::HttpCommon
23
23
 
24
24
  # Basic auth for resource
25
25
  if @http_config.has_key?('username')
26
- puts 'HTTP: Using basic authentication' if @config[:debug]
26
+ @log.debug('HTTP: Using basic authentication')
27
27
  raise 'HTTP: Missing password for authentication' unless @http_config.has_key?('password')
28
28
  @client.set_auth(nil, @http_config['username'], @http_config['password'])
29
29
  end
30
30
 
31
31
  # Basic auth for proxy
32
32
  if @http_config.has_key?('proxy_username')
33
- puts 'HTTP: Using proxy basic authentication' if @config[:debug]
33
+ @log.debug('HTTP: Using proxy basic authentication')
34
34
  raise 'HTTP: Missing password for proxy authentication' unless @http_config.has_key?('proxy_password')
35
35
  @client.set_proxy_auth(@http_config['proxy_username'], @http_config['proxy_password'])
36
36
  end
@@ -42,7 +42,7 @@ module Tiller::HttpCommon
42
42
  uri.gsub!('%e', @config[:environment])
43
43
  uri.gsub!('%t', interpolate[:template]) if interpolate[:template]
44
44
 
45
- puts "HTTP: Fetching #{uri}" if @config[:debug]
45
+ @log.debug("HTTP: Fetching #{uri}")
46
46
  resp = @client.get(uri, :follow_redirect => true)
47
47
  raise "HTTP: Server responded with status #{resp.status} for #{uri}" if resp.status != 200
48
48
  resp.body
@@ -53,7 +53,7 @@ module Tiller::HttpCommon
53
53
  def parse(content)
54
54
  case @http_config['parser']
55
55
  when 'json'
56
- puts 'HTTP: Using JSON parser' if @config[:debug]
56
+ @log.debug("HTTP: Using JSON parser")
57
57
  JSON.parse(content)
58
58
  else
59
59
  raise "HTTP: Unsupported parser '#{@http_config['parser']}'"
@@ -0,0 +1,20 @@
1
+ require 'logger'
2
+
3
+ module Tiller
4
+
5
+ class Logger < Logger
6
+ def initialize(config)
7
+ super(STDOUT)
8
+
9
+ self.level = Logger::WARN
10
+ self.level = Logger::INFO if config[:verbose]
11
+ self.level = Logger::DEBUG if config[:debug]
12
+
13
+ self.formatter = proc do |severity, datetime, progname, msg|
14
+ "#{msg}\n"
15
+ end
16
+
17
+ end
18
+ end
19
+
20
+ end
@@ -23,7 +23,7 @@ class ZookeeperTemplateSource < Tiller::TemplateSource
23
23
 
24
24
  def templates
25
25
  path = @zk_config['templates'].gsub('%e',@config[:environment])
26
- puts "Fetching Zookeeper templates from #{path}" if @config[:verbose]
26
+ @log.info("Fetching Zookeeper templates from #{path}")
27
27
  templates = []
28
28
  if @zk.exists?(path)
29
29
  templates = @zk.children(path)
@@ -1,3 +1,5 @@
1
+ require 'tiller/logger'
2
+
1
3
  # Tiller template source base class
2
4
  module Tiller
3
5
  # Subclasses provide templates (an array), and individual template contents
@@ -9,6 +11,7 @@ module Tiller
9
11
 
10
12
  def initialize(config)
11
13
  @config = config
14
+ @log = Tiller::Logger.new(config)
12
15
  setup
13
16
  end
14
17
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tiller
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.5
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Dastmalchi-Round
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-07 00:00:00.000000000 Z
11
+ date: 2015-09-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A tool to create configuration files from a variety of sources, particularly
14
14
  useful for Docker containers. See https://github.com/markround/tiller for examples
@@ -63,6 +63,7 @@ files:
63
63
  - lib/tiller/http.rb
64
64
  - lib/tiller/json.rb
65
65
  - lib/tiller/loader.rb
66
+ - lib/tiller/logger.rb
66
67
  - lib/tiller/options.rb
67
68
  - lib/tiller/template/file.rb
68
69
  - lib/tiller/template/http.rb
@@ -90,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
91
  version: '0'
91
92
  requirements: []
92
93
  rubyforge_project:
93
- rubygems_version: 2.2.2
94
+ rubygems_version: 2.2.3
94
95
  signing_key:
95
96
  specification_version: 4
96
97
  summary: Dynamic configuration file generation