tfwrapper 0.3.0 → 0.4.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: 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