tfwrapper 0.3.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f11f99f25e1c0f38ce5c79928b9b6434aee3445
4
- data.tar.gz: b00feb3297fb625886ce712a76300b2251560e34
3
+ metadata.gz: f64138baa8e32b2b73782f96ed7170e8a0371296
4
+ data.tar.gz: 6ec9aa09e58490cd647815ae47b7461b1256edea
5
5
  SHA512:
6
- metadata.gz: 2516206493b0e019dfeada871fef5e0f444c1eb128c7297daa73afea55ae261a1db4e28c9d213ba18e0d651c777d7ce35a481a8c3e9461a18a7a98de113e0863
7
- data.tar.gz: f7e976dc8d51f1f0a68d9300d450626f424a6aa6a12c6af40229e8f187db1ccded5ebeb5f7884d4e7693eaf6f31446a5b0b31cec4c05c7e09b311b428e7e508b
6
+ metadata.gz: 9bbccee24517fe1bd91acd1cb32e0dd1a45da75d73b5eec356a227721af4a29842cdd07d37248754becc791a0778d5dd21cdc373ed6b1e26189ced595dc9ce22
7
+ data.tar.gz: 5d3fc8354620ae60100133a2cc01358edb9b562e36b8b0f31ceca9b6422da95df25906ae7f02856e7f4e50bcd2aa58a0faf3f31a3bf18e5d9f2773caa850bd3e
data/.rubocop.yml CHANGED
@@ -1,8 +1,8 @@
1
1
  Metrics/AbcSize:
2
- Max: 22
2
+ Max: 40
3
3
 
4
4
  Metrics/BlockLength:
5
- Max: 1000
5
+ Max: 1300
6
6
 
7
7
  Metrics/ClassLength:
8
8
  Max: 500
@@ -10,6 +10,12 @@ Metrics/ClassLength:
10
10
  Metrics/MethodLength:
11
11
  Max: 100
12
12
 
13
+ Metrics/PerceivedComplexity:
14
+ Max: 8
15
+
16
+ Metrics/CyclomaticComplexity:
17
+ Max: 8
18
+
13
19
  # These are to compensate for some warnings that differ by
14
20
  # rubocop/ruby version
15
21
  Lint/UnneededDisable:
@@ -21,6 +27,11 @@ Style/MutableConstant:
21
27
  - 'lib/tfwrapper/version.rb'
22
28
  - 'spec/acceptance/acceptance_spec.rb'
23
29
 
24
- Layout/MultilineMethodCallIndentation:
30
+ Style/MultilineMethodCallIndentation:
25
31
  Exclude:
26
32
  - 'spec/unit/raketasks_spec.rb'
33
+
34
+ # Offense count: 28
35
+ # Cop supports --auto-correct.
36
+ Style/Proc:
37
+ Enabled: false
data/ChangeLog.md CHANGED
@@ -1,3 +1,8 @@
1
+ Version 0.4.0
2
+
3
+ - Add support for calling Procs at the beginning and end of each task.
4
+ - Documentation cleanup.
5
+
1
6
  Version 0.3.0
2
7
 
3
8
  - Add `tf:output` and `tf:output_json` Rake tasks
data/README.md CHANGED
@@ -31,6 +31,8 @@ This Gem provides the following Rake tasks:
31
31
  ``bundle exec rake tf:destroy[aws_instance.foo[1],aws_instance.bar[2]]``; see the
32
32
  [destroy documentation](https://www.terraform.io/docs/commands/destroy.html) for more information.
33
33
  * __tf:write_tf_vars__ - used as a prerequisite for other tasks; write Terraform variables to file on disk
34
+ * __tf:output__ - run ``terraform output``
35
+ * __tf:output_json__ - run ``terraform output -json``
34
36
 
35
37
  ## Installation
36
38
 
@@ -236,6 +238,33 @@ TFWrapper::RakeTasks.install_tasks(
236
238
  )
237
239
  ```
238
240
 
241
+ ### Calling Procs At Beginning and End of Tasks
242
+
243
+ Version 0.4.0 of tfwrapper introduced the ability to call arbitrary Ruby Procs from within the Rake tasks,
244
+ at the beginning and end of the task (i.e. before and after the terraform-handling code within the task).
245
+ This is accomplished via the ``:before_proc`` and ``:after_proc`` options, each taking a Proc instance.
246
+
247
+ The Procs take two positional arguments; a ``String`` containing the full, namespaced name of the Rake task
248
+ it was called from, and the ``String`` ``tf_dir`` argument passed to the TFWrapper::RakeTasks class (exactly as specified).
249
+
250
+ This could be used for things such as showing the output of state after a terraform run,
251
+ triggering a [tfenv](https://github.com/kamatama41/tfenv) installation, etc.
252
+
253
+ ```ruby
254
+ require 'tfwrapper/raketasks'
255
+
256
+ TFWrapper::RakeTasks.install_tasks(
257
+ '.',
258
+ before_proc: Proc.new do |taskname, tfdir|
259
+ next unless taskname == 'tf:apply' # example of only executing for apply task in default namespace
260
+ puts "Executing #{taskname} task with tfdir=#{tfdir}"
261
+ end,
262
+ after_proc: Proc.new do |taskname, tfdir|
263
+ puts "Executed #{taskname} task with tfdir=#{tfdir}"
264
+ end
265
+ )
266
+ ```
267
+
239
268
  ### Environment Variables to Consul
240
269
 
241
270
  tfwrapper also includes functionality to push environment variables to Consul
@@ -7,11 +7,7 @@ require 'rubygems'
7
7
  require 'tfwrapper/version'
8
8
 
9
9
  module TFWrapper
10
- # Generates Rake tasks for working with Terraform at Manheim.
11
- #
12
- # Before using this, the ``CONSUL_HOST`` environment variable must be set.
13
- #
14
- # __NOTE:__ Be sure to document all tasks in README.md
10
+ # Generates Rake tasks for working with Terraform.
15
11
  class RakeTasks
16
12
  include Rake::DSL if defined? Rake::DSL
17
13
 
@@ -19,7 +15,8 @@ module TFWrapper
19
15
  # set when installed
20
16
  attr_accessor :instance
21
17
 
22
- # Install the Rake tasks for working with Terraform at Manheim.
18
+ # Install the Rake tasks for working with Terraform. For full parameter
19
+ # documentation, see {TFWrapper::RakeTasks#initialize}
23
20
  #
24
21
  # @param (see #initialize)
25
22
  def install_tasks(tf_dir, opts = {})
@@ -33,12 +30,11 @@ module TFWrapper
33
30
 
34
31
  attr_reader :tf_version
35
32
 
36
- # Generate Rake tasks for working with Terraform at Manheim.
33
+ # Generate Rake tasks for working with Terraform.
37
34
  #
38
35
  # @param tf_dir [String] Terraform config directory, relative to Rakefile.
39
36
  # Set to '.' if the Rakefile is in the same directory as the ``.tf``
40
37
  # configuration files.
41
- # @param [Hash] options to use when adding tasks
42
38
  # @option opts [Hash] :backend_config hash of Terraform remote state
43
39
  # backend configuration options, to override or supplement those in
44
40
  # the terraform configuration. See the
@@ -58,6 +54,15 @@ module TFWrapper
58
54
  # write the environment variables used from ``tf_vars_from_env``
59
55
  # and their values to JSON at this path in Consul. This should have
60
56
  # the same naming constraints as ``consul_prefix``.
57
+ # @option opts [Proc] :before_proc Proc instance to call before executing
58
+ # the body of each task. Called with two arguments, the String full
59
+ # (namespaced) name of the task being executed, and ``tf_dir``. Returning
60
+ # or breaking from this Proc will cause the task to not execute; to exit
61
+ # the Proc early, use ``next``.
62
+ # @option opts [Proc] :after_proc Proc instance to call after executing
63
+ # the body of each task. Called with two arguments, the String full
64
+ # (namespaced) name of the task being executed, and ``tf_dir``. This will
65
+ # not execute if the body of the task fails.
61
66
  def initialize(tf_dir, opts = {})
62
67
  # find the directory that contains the Rakefile
63
68
  rakedir = File.realpath(Rake.application.rakefile)
@@ -69,6 +74,22 @@ module TFWrapper
69
74
  @tf_extra_vars = opts.fetch(:tf_extra_vars, {})
70
75
  @backend_config = opts.fetch(:backend_config, {})
71
76
  @consul_url = opts.fetch(:consul_url, nil)
77
+ @before_proc = opts.fetch(:before_proc, nil)
78
+ if !@before_proc.nil? && !@before_proc.is_a?(Proc)
79
+ raise(
80
+ TypeError,
81
+ 'TFWrapper::RakeTasks.initialize option :before_proc must be a ' \
82
+ 'Proc instance, not a ' + @before_proc.class.name
83
+ )
84
+ end
85
+ @after_proc = opts.fetch(:after_proc, nil)
86
+ if !@after_proc.nil? && !@after_proc.is_a?(Proc)
87
+ raise(
88
+ TypeError,
89
+ 'TFWrapper::RakeTasks.initialize option :after_proc must be a Proc ' \
90
+ 'instance, not a ' + @after_proc.class.name
91
+ )
92
+ end
72
93
  # default to lowest possible version; this is set in the 'init' task
73
94
  @tf_version = Gem::Version.new('0.0.0')
74
95
  # rubocop:disable Style/GuardClause
@@ -105,7 +126,8 @@ module TFWrapper
105
126
  def install_init
106
127
  namespace nsprefix do
107
128
  desc 'Run terraform init with appropriate arguments'
108
- task :init do
129
+ task :init do |t|
130
+ @before_proc.call(t.name, @tf_dir) unless @before_proc.nil?
109
131
  TFWrapper::Helpers.check_env_vars(@tf_vars_from_env.values)
110
132
  @tf_version = check_tf_version
111
133
  cmd = [
@@ -117,6 +139,7 @@ module TFWrapper
117
139
  cmd = cmd + ' ' + "-backend-config='#{k}=#{v}'"
118
140
  end
119
141
  terraform_runner(cmd)
142
+ @after_proc.call(t.name, @tf_dir) unless @after_proc.nil?
120
143
  end
121
144
  end
122
145
  end
@@ -129,7 +152,8 @@ module TFWrapper
129
152
  task :plan, [:target] => [
130
153
  :"#{nsprefix}:init",
131
154
  :"#{nsprefix}:write_tf_vars"
132
- ] do |_t, args|
155
+ ] do |t, args|
156
+ @before_proc.call(t.name, @tf_dir) unless @before_proc.nil?
133
157
  cmd = cmd_with_targets(
134
158
  ['terraform', 'plan', "-var-file #{var_file_path}"],
135
159
  args[:target],
@@ -137,6 +161,7 @@ module TFWrapper
137
161
  )
138
162
 
139
163
  terraform_runner(cmd)
164
+ @after_proc.call(t.name, @tf_dir) unless @after_proc.nil?
140
165
  end
141
166
  end
142
167
  end
@@ -150,7 +175,8 @@ module TFWrapper
150
175
  :"#{nsprefix}:init",
151
176
  :"#{nsprefix}:write_tf_vars",
152
177
  :"#{nsprefix}:plan"
153
- ] do |_t, args|
178
+ ] do |t, args|
179
+ @before_proc.call(t.name, @tf_dir) unless @before_proc.nil?
154
180
  cmd_arr = %w[terraform apply]
155
181
  cmd_arr << '-auto-approve' if tf_version >= Gem::Version.new('0.10.0')
156
182
  cmd_arr << "-var-file #{var_file_path}"
@@ -162,6 +188,7 @@ module TFWrapper
162
188
  terraform_runner(cmd)
163
189
 
164
190
  update_consul_stack_env_vars unless @consul_env_vars_prefix.nil?
191
+ @after_proc.call(t.name, @tf_dir) unless @after_proc.nil?
165
192
  end
166
193
  end
167
194
  end
@@ -172,7 +199,8 @@ module TFWrapper
172
199
  task refresh: [
173
200
  :"#{nsprefix}:init",
174
201
  :"#{nsprefix}:write_tf_vars"
175
- ] do
202
+ ] do |t|
203
+ @before_proc.call(t.name, @tf_dir) unless @before_proc.nil?
176
204
  cmd = [
177
205
  'terraform',
178
206
  'refresh',
@@ -180,6 +208,7 @@ module TFWrapper
180
208
  ].join(' ')
181
209
 
182
210
  terraform_runner(cmd)
211
+ @after_proc.call(t.name, @tf_dir) unless @after_proc.nil?
183
212
  end
184
213
  end
185
214
  end
@@ -190,14 +219,18 @@ module TFWrapper
190
219
  task output: [
191
220
  :"#{nsprefix}:init",
192
221
  :"#{nsprefix}:refresh"
193
- ] do
222
+ ] do |t|
223
+ @before_proc.call(t.name, @tf_dir) unless @before_proc.nil?
194
224
  terraform_runner('terraform output')
225
+ @after_proc.call(t.name, @tf_dir) unless @after_proc.nil?
195
226
  end
196
227
  task output_json: [
197
228
  :"#{nsprefix}:init",
198
229
  :"#{nsprefix}:refresh"
199
- ] do
230
+ ] do |t|
231
+ @before_proc.call(t.name, @tf_dir) unless @before_proc.nil?
200
232
  terraform_runner('terraform output -json')
233
+ @after_proc.call(t.name, @tf_dir) unless @after_proc.nil?
201
234
  end
202
235
  end
203
236
  end
@@ -210,7 +243,8 @@ module TFWrapper
210
243
  task :destroy, [:target] => [
211
244
  :"#{nsprefix}:init",
212
245
  :"#{nsprefix}:write_tf_vars"
213
- ] do |_t, args|
246
+ ] do |t, args|
247
+ @before_proc.call(t.name, @tf_dir) unless @before_proc.nil?
214
248
  cmd = cmd_with_targets(
215
249
  ['terraform', 'destroy', '-force', "-var-file #{var_file_path}"],
216
250
  args[:target],
@@ -218,6 +252,7 @@ module TFWrapper
218
252
  )
219
253
 
220
254
  terraform_runner(cmd)
255
+ @after_proc.call(t.name, @tf_dir) unless @after_proc.nil?
221
256
  end
222
257
  end
223
258
  end
@@ -234,7 +269,8 @@ module TFWrapper
234
269
  def install_write_tf_vars
235
270
  namespace nsprefix do
236
271
  desc "Write #{var_file_path}"
237
- task :write_tf_vars do
272
+ task :write_tf_vars do |t|
273
+ @before_proc.call(t.name, @tf_dir) unless @before_proc.nil?
238
274
  tf_vars = terraform_vars
239
275
  puts 'Terraform vars:'
240
276
  tf_vars.sort.map do |k, v|
@@ -248,6 +284,7 @@ module TFWrapper
248
284
  f.write(tf_vars.to_json)
249
285
  end
250
286
  STDERR.puts "Terraform vars written to: #{var_file_path}"
287
+ @after_proc.call(t.name, @tf_dir) unless @after_proc.nil?
251
288
  end
252
289
  end
253
290
  end
@@ -4,5 +4,5 @@ module TFWrapper
4
4
  # version of the Gem/module; used in the gemspec and in messages.
5
5
  # NOTE: When updating this, also update the version in the "Installation"
6
6
  # section of README.md
7
- VERSION = '0.3.0'
7
+ VERSION = '0.4.0'
8
8
  end
@@ -4,10 +4,13 @@ require 'ffi'
4
4
  require 'faraday'
5
5
  require 'json'
6
6
 
7
- def cleanup_tf
8
- fixture_dir = File.absolute_path(
7
+ def fixture_dir
8
+ File.absolute_path(
9
9
  File.join(File.dirname(__FILE__), '..', 'fixtures')
10
10
  )
11
+ end
12
+
13
+ def cleanup_tf
11
14
  Dir.glob("#{fixture_dir}/**/.terraform").each do |d|
12
15
  FileUtils.rmtree(d) if File.directory?(d)
13
16
  end
@@ -73,7 +76,6 @@ class HashicorpFetcher
73
76
  true
74
77
  end
75
78
 
76
- # rubocop:disable Metrics/AbcSize
77
79
  def fetch
78
80
  return File.realpath(bin_path) unless vendored_required?
79
81
  require 'open-uri'
@@ -102,7 +104,6 @@ class HashicorpFetcher
102
104
  raise StandardErrro, 'Error: wrong version' unless is_correct_version?
103
105
  File.realpath(bin_path)
104
106
  end
105
- # rubocop:enable Metrics/AbcSize
106
107
 
107
108
  def is_correct_version?
108
109
  ver = `#{bin_path} version`.strip
@@ -237,6 +237,26 @@ describe 'tfwrapper' do
237
237
  "Outputs:\n\nbar_variable = barval\nfoo_variable = fooval"
238
238
  )
239
239
  end
240
+ it 'calls the before proc with the proper arguments before terraform' do
241
+ expect(@out_err).to match(
242
+ Regexp.new(
243
+ '.*Executing tf:apply task with tfdir=' \
244
+ "#{Regexp.escape(fixture_dir)}\/testTwo\/foo\/bar.*" \
245
+ 'terraform_runner command: \'terraform apply.*',
246
+ Regexp::MULTILINE
247
+ )
248
+ )
249
+ end
250
+ it 'calls the after proc with the proper arguments after terraform' do
251
+ expect(@out_err).to match(
252
+ Regexp.new(
253
+ '.*terraform_runner command: \'terraform apply.*Executed ' \
254
+ "tf:apply task with tfdir=#{Regexp.escape(fixture_dir)}" \
255
+ '\/testTwo\/foo\/bar.*',
256
+ Regexp::MULTILINE
257
+ )
258
+ )
259
+ end
240
260
  it 'writes the vars file' do
241
261
  expect(File.file?(@varpath)).to be(true)
242
262
  c = File.open(@varpath, 'r').read
@@ -341,6 +361,19 @@ describe 'tfwrapper' do
341
361
  expect(@out_err).to include('foo_variable = fooval')
342
362
  expect(@out_err).to include('bar_variable = barval')
343
363
  end
364
+ it 'calls the procs with the proper arguments in proper order' do
365
+ expect(@out_err).to match(
366
+ Regexp.new(
367
+ '.*Executing tf:output task with tfdir=' \
368
+ "#{Regexp.escape(fixture_dir)}\/testTwo\/foo\/bar\n" \
369
+ 'bar_variable = barval' + "\n" \
370
+ 'foo_variable = fooval' + "\n" \
371
+ 'Executed tf:output task with tfdir=' \
372
+ "#{Regexp.escape(fixture_dir)}\/testTwo\/foo\/bar\n",
373
+ Regexp::MULTILINE
374
+ )
375
+ )
376
+ end
344
377
  end
345
378
  end
346
379
  context 'testThree - TF with namespaces', order: :defined do
@@ -471,6 +504,26 @@ describe 'tfwrapper' do
471
504
  .to include('consul_keys.testThreeFoo')
472
505
  expect(state['modules'][0]['resources'].length).to eq(1)
473
506
  end
507
+ it 'calls the before proc with the proper arguments before terraform' do
508
+ expect(@out_err).to match(
509
+ Regexp.new(
510
+ '.*Executing tf:apply task with tfdir=' \
511
+ "#{Regexp.escape(fixture_dir)}\/testThree\/foo.*" \
512
+ 'terraform_runner command: \'terraform apply.*',
513
+ Regexp::MULTILINE
514
+ )
515
+ )
516
+ end
517
+ it 'calls the after proc with the proper arguments after terraform' do
518
+ expect(@out_err).to match(
519
+ Regexp.new(
520
+ '.*terraform_runner command: \'terraform apply.*Executed ' \
521
+ "tf:apply task with tfdir=#{Regexp.escape(fixture_dir)}" \
522
+ '\/testThree\/foo.*',
523
+ Regexp::MULTILINE
524
+ )
525
+ )
526
+ end
474
527
  end
475
528
  describe 'tf:output' do
476
529
  before(:all) do
@@ -551,6 +604,26 @@ describe 'tfwrapper' do
551
604
  .to include('consul_keys.testThreeBar')
552
605
  expect(state['modules'][0]['resources'].length).to eq(1)
553
606
  end
607
+ it 'calls the before proc with the proper arguments before terraform' do
608
+ expect(@out_err).to match(
609
+ Regexp.new(
610
+ '.*Executing bar_tf:apply task with tfdir=' \
611
+ "#{Regexp.escape(fixture_dir)}\/testThree\/bar.*" \
612
+ 'terraform_runner command: \'terraform apply.*',
613
+ Regexp::MULTILINE
614
+ )
615
+ )
616
+ end
617
+ it 'calls the after proc with the proper arguments after terraform' do
618
+ expect(@out_err).to match(
619
+ Regexp.new(
620
+ '.*terraform_runner command: \'terraform apply.*Executed ' \
621
+ "bar_tf:apply task with tfdir=#{Regexp.escape(fixture_dir)}" \
622
+ '\/testThree\/bar.*',
623
+ Regexp::MULTILINE
624
+ )
625
+ )
626
+ end
554
627
  end
555
628
  describe 'bar_tf:output' do
556
629
  before(:all) do
@@ -2,25 +2,34 @@
2
2
 
3
3
  require 'tfwrapper/raketasks'
4
4
 
5
- # @option opts [String] :consul_url URL to access Consul at, for the
6
- # ``:consul_env_vars_prefix`` option.
7
- # @option opts [String] :consul_env_vars_prefix if specified and not nil,
8
- # write the environment variables used from ``tf_vars_from_env``
9
- # and their values to JSON at this path in Consul. This should have
10
- # the same naming constraints as ``consul_prefix``.
5
+ # we want to get real streaming output
6
+ STDOUT.sync = true
7
+ STDERR.sync = true
11
8
 
12
9
  TFWrapper::RakeTasks.install_tasks(
13
10
  'foo',
14
11
  backend_config: { 'path' => 'terraform/testThreeFoo' },
15
12
  tf_vars_from_env: { 'foo' => 'FOO' },
16
- tf_extra_vars: { 'bar' => 'barONEval' }
13
+ tf_extra_vars: { 'bar' => 'barONEval' },
14
+ before_proc: Proc.new do |taskname, tfdir|
15
+ puts "Executing #{taskname} task with tfdir=#{tfdir}"
16
+ end,
17
+ after_proc: Proc.new do |taskname, tfdir|
18
+ puts "Executed #{taskname} task with tfdir=#{tfdir}"
19
+ end
17
20
  )
18
21
 
19
22
  TFWrapper::RakeTasks.install_tasks(
20
23
  'bar',
21
24
  namespace_prefix: 'bar',
22
25
  tf_vars_from_env: { 'foo' => 'FOO' },
23
- tf_extra_vars: { 'bar' => 'barTWOval' }
26
+ tf_extra_vars: { 'bar' => 'barTWOval' },
27
+ before_proc: Proc.new do |taskname, tfdir|
28
+ puts "Executing #{taskname} task with tfdir=#{tfdir}"
29
+ end,
30
+ after_proc: Proc.new do |taskname, tfdir|
31
+ puts "Executed #{taskname} task with tfdir=#{tfdir}"
32
+ end
24
33
  )
25
34
 
26
35
  TFWrapper::RakeTasks.install_tasks(
@@ -28,5 +37,11 @@ TFWrapper::RakeTasks.install_tasks(
28
37
  namespace_prefix: 'baz',
29
38
  tf_vars_from_env: { 'foo' => 'FOO' },
30
39
  consul_url: 'http://127.0.0.1:8500',
31
- consul_env_vars_prefix: 'vars/testThreeBaz'
40
+ consul_env_vars_prefix: 'vars/testThreeBaz',
41
+ before_proc: Proc.new do |taskname, tfdir|
42
+ puts "Executing #{taskname} task with tfdir=#{tfdir}"
43
+ end,
44
+ after_proc: Proc.new do |taskname, tfdir|
45
+ puts "Executed #{taskname} task with tfdir=#{tfdir}"
46
+ end
32
47
  )
@@ -2,11 +2,21 @@
2
2
 
3
3
  require 'tfwrapper/raketasks'
4
4
 
5
+ # we want to get real streaming output
6
+ STDOUT.sync = true
7
+ STDERR.sync = true
8
+
5
9
  TFWrapper::RakeTasks.install_tasks(
6
10
  'foo/bar',
7
11
  backend_config: {
8
12
  'path' => "terraform/testTwo/#{ENV['TFSUFFIX']}"
9
13
  },
10
14
  tf_vars_from_env: { 'foo' => 'FOO' },
11
- tf_extra_vars: { 'bar' => 'barval' }
15
+ tf_extra_vars: { 'bar' => 'barval' },
16
+ before_proc: Proc.new do |taskname, tfdir|
17
+ puts "Executing #{taskname} task with tfdir=#{tfdir}"
18
+ end,
19
+ after_proc: Proc.new do |taskname, tfdir|
20
+ puts "Executed #{taskname} task with tfdir=#{tfdir}"
21
+ end
12
22
  )
@@ -12,6 +12,8 @@ require 'rubygems'
12
12
  describe TFWrapper::RakeTasks do
13
13
  subject do
14
14
  allow(Rake.application).to receive(:rakefile).and_return('Rakefile')
15
+ allow(Rake.application).to receive(:original_dir)
16
+ .and_return('/path/to/rakedir')
15
17
  allow(File).to receive(:realpath) { |p| p }
16
18
  subj = TFWrapper::RakeTasks.new('tfdir')
17
19
  subj.instance_variable_set('@tf_dir', 'tfdir')
@@ -62,6 +64,8 @@ describe TFWrapper::RakeTasks do
62
64
  expect(cls.instance_variable_get('@consul_url')).to eq(nil)
63
65
  expect(cls.instance_variable_get('@tf_version'))
64
66
  .to eq(Gem::Version.new('0.0.0'))
67
+ expect(cls.instance_variable_get('@before_proc')).to eq(nil)
68
+ expect(cls.instance_variable_get('@after_proc')).to eq(nil)
65
69
  end
66
70
  it 'sets options' do
67
71
  allow(ENV).to receive(:[])
@@ -69,12 +73,22 @@ describe TFWrapper::RakeTasks do
69
73
  allow(Rake.application).to receive(:rakefile)
70
74
  .and_return('/path/to')
71
75
  allow(File).to receive(:realpath) { |p| p.sub('../', '') }
76
+ before_dbl = double
77
+ allow(before_dbl).to receive(:foo)
78
+ expect(before_dbl).to_not receive(:foo)
79
+ after_dbl = double
80
+ allow(after_dbl).to receive(:foo)
81
+ expect(after_dbl).to_not receive(:foo)
82
+ bproc = Proc.new { |a, b| before_dbl.foo(a, b) }
83
+ aproc = Proc.new { |a, b| after_dbl.foo(a, b) }
72
84
  cls = TFWrapper::RakeTasks.new(
73
85
  'tf/dir',
74
86
  consul_env_vars_prefix: 'cvprefix',
75
87
  tf_vars_from_env: { 'foo' => 'bar' },
76
88
  tf_extra_vars: { 'baz' => 'blam' },
77
- consul_url: 'foobar'
89
+ consul_url: 'foobar',
90
+ before_proc: bproc,
91
+ after_proc: aproc
78
92
  )
79
93
  expect(cls.instance_variable_get('@tf_dir'))
80
94
  .to eq('/path/to/tf/dir')
@@ -86,6 +100,38 @@ describe TFWrapper::RakeTasks do
86
100
  .to eq('baz' => 'blam')
87
101
  expect(cls.instance_variable_get('@backend_config')).to eq({})
88
102
  expect(cls.instance_variable_get('@consul_url')).to eq('foobar')
103
+ expect(cls.instance_variable_get('@before_proc')).to eq(bproc)
104
+ expect(cls.instance_variable_get('@after_proc')).to eq(aproc)
105
+ end
106
+ context 'when before_proc is not a proc or nil' do
107
+ it 'raises an error' do
108
+ allow(ENV).to receive(:[])
109
+ allow(ENV).to receive(:[]).with('CONSUL_HOST').and_return('chost')
110
+ allow(ENV).to receive(:[]).with('ENVIRONMENT').and_return('myenv')
111
+ allow(ENV).to receive(:[]).with('PROJECT').and_return('myproj')
112
+ allow(Rake.application).to receive(:rakefile)
113
+ .and_return('/rake/dir/Rakefile')
114
+ allow(File).to receive(:realpath) { |p| p.sub('../', '') }
115
+ allow(File).to receive(:file?).and_return(true)
116
+ expect { TFWrapper::RakeTasks.new('tfdir', before_proc: 'foo') }
117
+ .to raise_error(
118
+ TypeError,
119
+ /before_proc must be a Proc instance, not a String/
120
+ )
121
+ end
122
+ end
123
+ context 'when after_proc is not a proc or nil' do
124
+ it 'raises an error' do
125
+ allow(Rake.application).to receive(:original_dir)
126
+ .and_return('/rake/dir')
127
+ allow(Rake.application).to receive(:rakefile).and_return('Rakefile')
128
+ allow(File).to receive(:realpath) { |p| p }
129
+ expect { TFWrapper::RakeTasks.new('tfdir', after_proc: 'foo') }
130
+ .to raise_error(
131
+ TypeError,
132
+ /after_proc must be a Proc instance, not a String/
133
+ )
134
+ end
89
135
  end
90
136
  context 'when consul_url is nil but consul_env_vars_prefix is not' do
91
137
  it 'raises an error' do
@@ -290,6 +336,40 @@ describe TFWrapper::RakeTasks do
290
336
  expect(subject.instance_variable_get(:@tf_version))
291
337
  .to eq(Gem::Version.new('0.10.2'))
292
338
  end
339
+ it 'calls before_proc if not nil' do
340
+ Rake.application['tf:init'].clear_prerequisites
341
+
342
+ before_dbl = double
343
+ allow(before_dbl).to receive(:foo)
344
+ expect(before_dbl).to receive(:foo).once.with('tf:init', 'tfdir')
345
+ bproc = Proc.new { |a, b| before_dbl.foo(a, b) }
346
+ subject.instance_variable_set('@before_proc', bproc)
347
+
348
+ allow(TFWrapper::Helpers).to receive(:check_env_vars)
349
+ allow(ENV).to receive(:[])
350
+ subject.instance_variable_set('@backend_config', {})
351
+ allow(subject).to receive(:terraform_runner)
352
+ allow(subject).to receive(:check_tf_version)
353
+ .and_return(Gem::Version.new('0.10.2'))
354
+ Rake.application['tf:init'].invoke
355
+ end
356
+ it 'calls after_proc if not nil' do
357
+ Rake.application['tf:init'].clear_prerequisites
358
+
359
+ after_dbl = double
360
+ allow(after_dbl).to receive(:foo)
361
+ expect(after_dbl).to receive(:foo).once.with('tf:init', 'tfdir')
362
+ aproc = Proc.new { |a, b| after_dbl.foo(a, b) }
363
+ subject.instance_variable_set('@after_proc', aproc)
364
+
365
+ allow(TFWrapper::Helpers).to receive(:check_env_vars)
366
+ allow(ENV).to receive(:[])
367
+ subject.instance_variable_set('@backend_config', {})
368
+ allow(subject).to receive(:terraform_runner)
369
+ allow(subject).to receive(:check_tf_version)
370
+ .and_return(Gem::Version.new('0.10.2'))
371
+ Rake.application['tf:init'].invoke
372
+ end
293
373
  end
294
374
  describe '#install_plan' do
295
375
  # these let/before/after come from bundler's gem_helper_spec.rb
@@ -339,6 +419,32 @@ describe TFWrapper::RakeTasks do
339
419
  'tar.get[1]', 't.gt[2]', 'my.target[3]'
340
420
  )
341
421
  end
422
+ it 'calls before_proc if not nil' do
423
+ Rake.application['tf:plan'].clear_prerequisites
424
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
425
+ allow(subject).to receive(:terraform_runner)
426
+
427
+ before_dbl = double
428
+ allow(before_dbl).to receive(:foo)
429
+ expect(before_dbl).to receive(:foo).once.with('tf:plan', 'tfdir')
430
+ bproc = Proc.new { |a, b| before_dbl.foo(a, b) }
431
+ subject.instance_variable_set('@before_proc', bproc)
432
+
433
+ Rake.application['tf:plan'].invoke
434
+ end
435
+ it 'calls after_proc if not nil' do
436
+ Rake.application['tf:plan'].clear_prerequisites
437
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
438
+ allow(subject).to receive(:terraform_runner)
439
+
440
+ after_dbl = double
441
+ allow(after_dbl).to receive(:foo)
442
+ expect(after_dbl).to receive(:foo).once.with('tf:plan', 'tfdir')
443
+ aproc = Proc.new { |a, b| after_dbl.foo(a, b) }
444
+ subject.instance_variable_set('@after_proc', aproc)
445
+
446
+ Rake.application['tf:plan'].invoke
447
+ end
342
448
  end
343
449
  describe '#install_apply' do
344
450
  # these let/before/after come from bundler's gem_helper_spec.rb
@@ -359,6 +465,34 @@ describe TFWrapper::RakeTasks do
359
465
  .to eq(%w[tf:init tf:write_tf_vars tf:plan])
360
466
  expect(Rake.application['tf:apply'].arg_names).to eq([:target])
361
467
  end
468
+ it 'calls before_proc if not nil' do
469
+ Rake.application['tf:apply'].clear_prerequisites
470
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
471
+ allow(subject).to receive(:terraform_runner)
472
+ allow(subject).to receive(:update_consul_stack_env_vars)
473
+
474
+ before_dbl = double
475
+ allow(before_dbl).to receive(:foo)
476
+ expect(before_dbl).to receive(:foo).once.with('tf:apply', 'tfdir')
477
+ bproc = Proc.new { |a, b| before_dbl.foo(a, b) }
478
+ subject.instance_variable_set('@before_proc', bproc)
479
+
480
+ Rake.application['tf:apply'].invoke
481
+ end
482
+ it 'calls after_proc if not nil' do
483
+ Rake.application['tf:apply'].clear_prerequisites
484
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
485
+ allow(subject).to receive(:terraform_runner)
486
+ allow(subject).to receive(:update_consul_stack_env_vars)
487
+
488
+ after_dbl = double
489
+ allow(after_dbl).to receive(:foo)
490
+ expect(after_dbl).to receive(:foo).once.with('tf:apply', 'tfdir')
491
+ aproc = Proc.new { |a, b| after_dbl.foo(a, b) }
492
+ subject.instance_variable_set('@after_proc', aproc)
493
+
494
+ Rake.application['tf:apply'].invoke
495
+ end
362
496
  context 'terraform version 0.9.5' do
363
497
  before(:each) do
364
498
  allow(subject).to receive(:tf_version)
@@ -481,6 +615,32 @@ describe TFWrapper::RakeTasks do
481
615
  .with('terraform refresh -var-file file.tfvars.json')
482
616
  Rake.application['tf:refresh'].invoke
483
617
  end
618
+ it 'calls before_proc if not nil' do
619
+ Rake.application['tf:refresh'].clear_prerequisites
620
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
621
+ allow(subject).to receive(:terraform_runner)
622
+
623
+ before_dbl = double
624
+ allow(before_dbl).to receive(:foo)
625
+ expect(before_dbl).to receive(:foo).once.with('tf:refresh', 'tfdir')
626
+ bproc = Proc.new { |a, b| before_dbl.foo(a, b) }
627
+ subject.instance_variable_set('@before_proc', bproc)
628
+
629
+ Rake.application['tf:refresh'].invoke
630
+ end
631
+ it 'calls after_proc if not nil' do
632
+ Rake.application['tf:refresh'].clear_prerequisites
633
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
634
+ allow(subject).to receive(:terraform_runner)
635
+
636
+ after_dbl = double
637
+ allow(after_dbl).to receive(:foo)
638
+ expect(after_dbl).to receive(:foo).once.with('tf:refresh', 'tfdir')
639
+ aproc = Proc.new { |a, b| after_dbl.foo(a, b) }
640
+ subject.instance_variable_set('@after_proc', aproc)
641
+
642
+ Rake.application['tf:refresh'].invoke
643
+ end
484
644
  end
485
645
  describe '#install_destroy' do
486
646
  # these let/before/after come from bundler's gem_helper_spec.rb
@@ -530,6 +690,32 @@ describe TFWrapper::RakeTasks do
530
690
  'tar.get[1]', 't.gt[2]', 'my.target[3]'
531
691
  )
532
692
  end
693
+ it 'calls before_proc if not nil' do
694
+ Rake.application['tf:destroy'].clear_prerequisites
695
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
696
+ allow(subject).to receive(:terraform_runner)
697
+
698
+ before_dbl = double
699
+ allow(before_dbl).to receive(:foo)
700
+ expect(before_dbl).to receive(:foo).once.with('tf:destroy', 'tfdir')
701
+ bproc = Proc.new { |a, b| before_dbl.foo(a, b) }
702
+ subject.instance_variable_set('@before_proc', bproc)
703
+
704
+ Rake.application['tf:destroy'].invoke
705
+ end
706
+ it 'calls after_proc if not nil' do
707
+ Rake.application['tf:destroy'].clear_prerequisites
708
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
709
+ allow(subject).to receive(:terraform_runner)
710
+
711
+ after_dbl = double
712
+ allow(after_dbl).to receive(:foo)
713
+ expect(after_dbl).to receive(:foo).once.with('tf:destroy', 'tfdir')
714
+ aproc = Proc.new { |a, b| after_dbl.foo(a, b) }
715
+ subject.instance_variable_set('@after_proc', aproc)
716
+
717
+ Rake.application['tf:destroy'].invoke
718
+ end
533
719
  end
534
720
  describe '#install_write_tf_vars' do
535
721
  # these let/before/after come from bundler's gem_helper_spec.rb
@@ -575,6 +761,48 @@ describe TFWrapper::RakeTasks do
575
761
  .once.with('Terraform vars written to: file.tfvars.json')
576
762
  Rake.application['tf:write_tf_vars'].invoke
577
763
  end
764
+ it 'calls before_proc if not nil' do
765
+ vars = {
766
+ 'foo' => 'bar',
767
+ 'baz' => 'blam',
768
+ 'aws_access_key' => 'ak'
769
+ }
770
+ allow(subject).to receive(:terraform_vars).and_return(vars)
771
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
772
+ f_dbl = double(File)
773
+ allow(File).to receive(:open).and_yield(f_dbl)
774
+ allow(f_dbl).to receive(:write)
775
+
776
+ before_dbl = double
777
+ allow(before_dbl).to receive(:foo)
778
+ expect(before_dbl).to receive(:foo).once
779
+ .with('tf:write_tf_vars', 'tfdir')
780
+ bproc = Proc.new { |a, b| before_dbl.foo(a, b) }
781
+ subject.instance_variable_set('@before_proc', bproc)
782
+
783
+ Rake.application['tf:write_tf_vars'].invoke
784
+ end
785
+ it 'calls after_proc if not nil' do
786
+ vars = {
787
+ 'foo' => 'bar',
788
+ 'baz' => 'blam',
789
+ 'aws_access_key' => 'ak'
790
+ }
791
+ allow(subject).to receive(:terraform_vars).and_return(vars)
792
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
793
+ f_dbl = double(File)
794
+ allow(File).to receive(:open).and_yield(f_dbl)
795
+ allow(f_dbl).to receive(:write)
796
+
797
+ after_dbl = double
798
+ allow(after_dbl).to receive(:foo)
799
+ expect(after_dbl).to receive(:foo).once
800
+ .with('tf:write_tf_vars', 'tfdir')
801
+ aproc = Proc.new { |a, b| after_dbl.foo(a, b) }
802
+ subject.instance_variable_set('@after_proc', aproc)
803
+
804
+ Rake.application['tf:write_tf_vars'].invoke
805
+ end
578
806
  end
579
807
  context 'when ns_prefix is specified' do
580
808
  let!(:rake_application) { Rake.application }
@@ -620,6 +848,50 @@ describe TFWrapper::RakeTasks do
620
848
  .once.with('Terraform vars written to: foo_file.tfvars.json')
621
849
  Rake.application['foo_tf:write_tf_vars'].invoke
622
850
  end
851
+ it 'calls before_proc if not nil' do
852
+ vars = {
853
+ 'foo' => 'bar',
854
+ 'baz' => 'blam',
855
+ 'aws_access_key' => 'ak'
856
+ }
857
+ allow(subject).to receive(:terraform_vars).and_return(vars)
858
+ allow(subject).to receive(:var_file_path)
859
+ .and_return('foo_file.tfvars.json')
860
+ f_dbl = double(File)
861
+ allow(File).to receive(:open).and_yield(f_dbl)
862
+ allow(f_dbl).to receive(:write)
863
+
864
+ before_dbl = double
865
+ allow(before_dbl).to receive(:foo)
866
+ expect(before_dbl).to receive(:foo).once
867
+ .with('foo_tf:write_tf_vars', 'tfdir')
868
+ bproc = Proc.new { |a, b| before_dbl.foo(a, b) }
869
+ subject.instance_variable_set('@before_proc', bproc)
870
+
871
+ Rake.application['foo_tf:write_tf_vars'].invoke
872
+ end
873
+ it 'calls after_proc if not nil' do
874
+ vars = {
875
+ 'foo' => 'bar',
876
+ 'baz' => 'blam',
877
+ 'aws_access_key' => 'ak'
878
+ }
879
+ allow(subject).to receive(:terraform_vars).and_return(vars)
880
+ allow(subject).to receive(:var_file_path)
881
+ .and_return('foo_file.tfvars.json')
882
+ f_dbl = double(File)
883
+ allow(File).to receive(:open).and_yield(f_dbl)
884
+ allow(f_dbl).to receive(:write)
885
+
886
+ after_dbl = double
887
+ allow(after_dbl).to receive(:foo)
888
+ expect(after_dbl).to receive(:foo).once
889
+ .with('foo_tf:write_tf_vars', 'tfdir')
890
+ aproc = Proc.new { |a, b| after_dbl.foo(a, b) }
891
+ subject.instance_variable_set('@after_proc', aproc)
892
+
893
+ Rake.application['foo_tf:write_tf_vars'].invoke
894
+ end
623
895
  end
624
896
  end
625
897
  describe '#install_output' do
@@ -649,6 +921,32 @@ describe TFWrapper::RakeTasks do
649
921
  .with('terraform output')
650
922
  Rake.application['tf:output'].invoke
651
923
  end
924
+ it 'output calls before_proc if not nil' do
925
+ Rake.application['tf:output'].clear_prerequisites
926
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
927
+ allow(subject).to receive(:terraform_runner)
928
+
929
+ before_dbl = double
930
+ allow(before_dbl).to receive(:foo)
931
+ expect(before_dbl).to receive(:foo).once.with('tf:output', 'tfdir')
932
+ bproc = Proc.new { |a, b| before_dbl.foo(a, b) }
933
+ subject.instance_variable_set('@before_proc', bproc)
934
+
935
+ Rake.application['tf:output'].invoke
936
+ end
937
+ it 'output calls after_proc if not nil' do
938
+ Rake.application['tf:output'].clear_prerequisites
939
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
940
+ allow(subject).to receive(:terraform_runner)
941
+
942
+ after_dbl = double
943
+ allow(after_dbl).to receive(:foo)
944
+ expect(after_dbl).to receive(:foo).once.with('tf:output', 'tfdir')
945
+ aproc = Proc.new { |a, b| after_dbl.foo(a, b) }
946
+ subject.instance_variable_set('@after_proc', aproc)
947
+
948
+ Rake.application['tf:output'].invoke
949
+ end
652
950
  it 'adds the output_json task' do
653
951
  expect(Rake.application['tf:output_json']).to be_instance_of(Rake::Task)
654
952
  expect(Rake.application['tf:output_json'].prerequisites)
@@ -662,6 +960,32 @@ describe TFWrapper::RakeTasks do
662
960
  .with('terraform output -json')
663
961
  Rake.application['tf:output_json'].invoke
664
962
  end
963
+ it 'output_json calls before_proc if not nil' do
964
+ Rake.application['tf:output_json'].clear_prerequisites
965
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
966
+ allow(subject).to receive(:terraform_runner)
967
+
968
+ before_dbl = double
969
+ allow(before_dbl).to receive(:foo)
970
+ expect(before_dbl).to receive(:foo).once.with('tf:output_json', 'tfdir')
971
+ bproc = Proc.new { |a, b| before_dbl.foo(a, b) }
972
+ subject.instance_variable_set('@before_proc', bproc)
973
+
974
+ Rake.application['tf:output_json'].invoke
975
+ end
976
+ it 'output_json calls after_proc if not nil' do
977
+ Rake.application['tf:output_json'].clear_prerequisites
978
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
979
+ allow(subject).to receive(:terraform_runner)
980
+
981
+ after_dbl = double
982
+ allow(after_dbl).to receive(:foo)
983
+ expect(after_dbl).to receive(:foo).once.with('tf:output_json', 'tfdir')
984
+ aproc = Proc.new { |a, b| after_dbl.foo(a, b) }
985
+ subject.instance_variable_set('@after_proc', aproc)
986
+
987
+ Rake.application['tf:output_json'].invoke
988
+ end
665
989
  end
666
990
  describe '#terraform_vars' do
667
991
  it 'builds a hash and sets overrides' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tfwrapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - jantman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-20 00:00:00.000000000 Z
11
+ date: 2017-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: retries