tfwrapper 0.5.0 → 0.6.3

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
- SHA1:
3
- metadata.gz: 73a99a40047a490174b186e5bf5c6b58dedea114
4
- data.tar.gz: f64131d4e1a68fae63dc3b86465b64480a3edae3
2
+ SHA256:
3
+ metadata.gz: d800160edbaa04ea415c64a6153496bc11ac26134f37cdec619ad79f1ac790f7
4
+ data.tar.gz: 3052aaa38b88c2faaebbbe3e924d693eb2acfed70ed5ea9f201bd1eeebbe8921
5
5
  SHA512:
6
- metadata.gz: 7e3d6202be5a238dc9a358ed190aa6debbef62e5f56cac5b365935afe407a700e46a3166e24af34640f00a21667dd34adec292bb1c7125fe82129da98eefeeed
7
- data.tar.gz: 1b4b83ca1147ae1955d3e571e087467f792db7107b76c2d9f421ff9fd37dd4512860ca719b32a7fd8b56e8861b1785ff45b439eea01faa454e4169b0dd1b040c
6
+ metadata.gz: 2927add435fcb35ff775884b748a5c1e2ab3c5ae8ab3766dd53c32cae56dcbaba33c80d7d5e39a94133bdad9bb822c32a81bc2c58627872e795fd818c5e151fa
7
+ data.tar.gz: 2510df4efa55b5f7c304c073afea722ef85a22218c8ad8b6374a4c2f8ca5d903de926be3a4218f7c49e4c6c1a51b05a5c40197f602e8b370e7a4dc4087428245
@@ -5,7 +5,7 @@ Metrics/AbcSize:
5
5
  Max: 50
6
6
 
7
7
  Metrics/BlockLength:
8
- Max: 1400
8
+ Max: 1500
9
9
 
10
10
  Metrics/ClassLength:
11
11
  Max: 500
@@ -0,0 +1,62 @@
1
+ ---
2
+ dist: xenial
3
+ language: ruby
4
+ cache: bundler
5
+ before_install:
6
+ - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
7
+ - gem install bundler -v '< 2'
8
+ install: true
9
+ matrix:
10
+ include:
11
+ - rvm: ruby
12
+ install: bundle install --without landscape
13
+ script: ["bundle exec ruby --version", "bundle exec rake spec:unit"]
14
+ name: "ruby-latest unit"
15
+ - rvm: ruby
16
+ install: bundle install --without landscape
17
+ script: bundle exec rake rubocop
18
+ name: "ruby-latest rubocop"
19
+ - rvm: ruby
20
+ install: bundle install --without landscape
21
+ script: bundle exec rake yard:generate
22
+ name: "ruby-latest yard"
23
+ - rvm: 2.0
24
+ install: bundle install --without landscape
25
+ script: bundle exec rake spec:unit
26
+ name: "ruby-2.0 unit"
27
+ - rvm: 2.1
28
+ install: bundle install --without landscape
29
+ script: bundle exec rake spec:unit
30
+ name: "ruby-2.1 unit"
31
+ - rvm: 2.2
32
+ install: bundle install --without landscape
33
+ script: bundle exec rake spec:unit
34
+ name: "ruby-2.2 unit"
35
+ - rvm: 2.3
36
+ install: bundle install --without landscape
37
+ script: bundle exec rake spec:unit
38
+ name: "ruby-2.3 unit"
39
+ - rvm: 2.3
40
+ install: bundle install
41
+ script: bundle exec rake spec:acceptance TF_VERSION=0.10.0
42
+ name: "ruby-2.3 acceptance TF 0.10.0"
43
+ - rvm: 2.3
44
+ install: bundle install
45
+ script: bundle exec rake spec:acceptance TF_VERSION=0.10.2
46
+ name: "ruby-2.3 acceptance TF 0.10.2"
47
+ - rvm: 2.3
48
+ install: bundle install
49
+ script: bundle exec rake spec:acceptance TF_VERSION=0.11.2
50
+ name: "ruby-2.3 acceptance TF 0.11.2"
51
+ - rvm: 2.3
52
+ install: bundle install
53
+ script: bundle exec rake spec:acceptance TF_VERSION=0.11.14
54
+ name: "ruby-2.3 acceptance TF 0.11.14"
55
+ - rvm: 2.4
56
+ install: bundle install
57
+ script: bundle exec rake spec:unit
58
+ name: "ruby-2.4 unit"
59
+ - rvm: 2.4
60
+ install: bundle install
61
+ script: bundle exec rake spec:acceptance TF_VERSION=0.11.14
62
+ name: "ruby-2.4 acceptance TF 0.11.14"
@@ -1,3 +1,33 @@
1
+ Version 0.6.3
2
+
3
+ - Fix bug with ``tf_sensitive_vars``. Prevent values from being printed in ``update_consul_stack_env_vars``.
4
+
5
+ Version 0.6.2
6
+
7
+ - Add ``tf_sensitive_vars`` option.
8
+
9
+ Version 0.6.1
10
+
11
+ - Add ``allowed_empty_vars`` option.
12
+ - Only support terraform up to 0.11.14.
13
+
14
+ Version 0.6.0
15
+
16
+ - Include full terraform output when a terraform run fails with output including ``hrottling``, ``status code: 403``, or ``status code: 401``. Previously terraform output was suppressed in these cases, which causes confusion with providers other than "aws" that include these strings in their failure output.
17
+ - In ``Gemfile``, for testing, pin terraform-landscape gem to 0.2.2 for Ruby 2.x compatibility.
18
+ - Pin ``rb-inotify`` dependency to 0.9.10 to allow build with Ruby < 2.2
19
+ - Switch testing from circleci.com to travis-ci.org
20
+ - Pin terraform_landscape dependency to 0.2.2 for compatibility with ruby < 2.5
21
+ - Acceptance tests:
22
+ - Use HashiCorp checkpoint API instead of GitHub Releases API to find latest terraform version, to work around query failures
23
+ - Pin consul provider versions to 1.0.0 to fix intermittent failures
24
+ - Switch Ruby versions used in tests to latest TravisCI versions
25
+ - Stop acceptance testing terraform 0.9.x, as newer versions require pinning the consul provider version but 0.9 doesn't support versioned providers.
26
+
27
+ Version 0.5.1
28
+
29
+ - Fix bug where terraform plan errors were suppressed if a plan run with landscape support enabled exited non-zero.
30
+
1
31
  Version 0.5.0
2
32
 
3
33
  - Add support for using terraform_landscape gem, if present, to reformat plan output; see README for usage.
data/Gemfile CHANGED
@@ -4,5 +4,5 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  group :landscape do
7
- gem 'terraform_landscape'
7
+ gem 'terraform_landscape', '0.2.2'
8
8
  end
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # tfwrapper
2
2
 
3
- Build of master branch: [![CircleCI](https://circleci.com/gh/manheim/tfwrapper.svg?style=svg)](https://circleci.com/gh/manheim/tfwrapper)
3
+ Build of master branch: [![TravisCI](https://api.travis-ci.org/manheim/tfwrapper.svg?branch=master)](https://travis-ci.org/manheim/tfwrapper)
4
4
 
5
5
  Documentation: [http://www.rubydoc.info/gems/tfwrapper/](http://www.rubydoc.info/gems/tfwrapper/)
6
6
 
7
- tfwrapper provides Rake tasks for working with [Hashicorp Terraform](https://www.terraform.io/) 0.9+, ensuring proper initialization and passing in variables from the environment or Ruby, as well as optionally pushing some information to Consul. tfwrapper also attempts to detect and retry
7
+ tfwrapper provides Rake tasks for working with [Hashicorp Terraform](https://www.terraform.io/) 0.9 through 0.11, ensuring proper initialization and passing in variables from the environment or Ruby, as well as optionally pushing some information to Consul. tfwrapper also attempts to detect and retry
8
8
  failed runs due to AWS throttling or access denied errors.
9
9
 
10
10
  ## Overview
@@ -44,12 +44,12 @@ with 1.9.3 is simply too high to justify.
44
44
  Add to your ``Gemfile``:
45
45
 
46
46
  ```ruby
47
- gem 'tfwrapper', '~> 0.5.0'
47
+ gem 'tfwrapper', '~> 0.6.1'
48
48
  ```
49
49
 
50
50
  ### Supported Terraform Versions
51
51
 
52
- tfwrapper only supports terraform 0.9+. It is tested against multiple versions from 0.9.2 to 0.10.2 and the current release.
52
+ tfwrapper only supports terraform 0.9-0.11. It is tested against multiple versions from 0.9.2 to 0.11.14.
53
53
 
54
54
  ### Terraform Landscape
55
55
 
@@ -147,6 +147,10 @@ TFWrapper::RakeTasks.install_tasks(
147
147
  )
148
148
  ```
149
149
 
150
+ These variables are tested to be set in the environment with a non-empty value, and will raise an error if any are
151
+ missing or empty. If some should be allowed to be missing or empty empty, pass a ``allowed_empty_vars`` list with
152
+ their environment variable names.
153
+
150
154
  ### Ruby Variables to Terraform Variables
151
155
 
152
156
  If you wish to explicitly bind values from your Ruby code to terraform variables, you can do this with
@@ -326,6 +330,26 @@ $ consul kv get terraform/inputs/foo
326
330
  {"FOO":"one", "BAR":"two"}
327
331
  ```
328
332
 
333
+ ### Sensitive Environment Variables
334
+ If you wish for certain variables to be marked as "redacted", use the ``tf_sensitive_vars`` option. This is an array of variables that will not be printed.
335
+
336
+ Note: ``aws_access_key`` and ``aws_secret_key`` will always be redacted without requiring configuration.
337
+
338
+
339
+ Example to redact the vaule for ``secret``:
340
+
341
+ Rakefile:
342
+
343
+ ```ruby
344
+ require 'tfwrapper/raketasks'
345
+
346
+ TFWrapper::RakeTasks.install_tasks(
347
+ '.',
348
+ tf_vars_from_env: {'foo' => 'FOO', 'bar' => 'BAR', 'secret' => 'SECRET'},
349
+ tf_sensitive_vars: ['secret']
350
+ )
351
+ ```
352
+
329
353
  ## Development
330
354
 
331
355
  1. ``bundle install --path vendor``
@@ -78,9 +78,12 @@ module TFWrapper
78
78
  # non-empty. Raise StandardError if any aren't.
79
79
  #
80
80
  # @param required [Array] list of required environment variables
81
- def self.check_env_vars(required)
81
+ # @param allowed_missing [Array] list of environment variables to allow to
82
+ # be empty or missing.
83
+ def self.check_env_vars(required, allowed_missing)
82
84
  missing = []
83
85
  required.each do |name|
86
+ next if allowed_missing.include?(name)
84
87
  if !ENV.include?(name)
85
88
  puts "ERROR: Environment variable '#{name}' must be set."
86
89
  missing << name
@@ -55,8 +55,12 @@ module TFWrapper
55
55
  # configurations in the same Rakefile.
56
56
  # @option opts [Hash] :tf_vars_from_env hash of Terraform variables to the
57
57
  # (required) environment variables to populate their values from
58
+ # @option opts [Hash] :allowed_empty_vars array of environment variable
59
+ # names (specified in :tf_vars_from_env) to allow to be empty or missing.
58
60
  # @option opts [Hash] :tf_extra_vars hash of Terraform variables to their
59
61
  # values; overrides any same-named keys in ``tf_vars_from_env``
62
+ # @option opts [Array] :tf_sensitive_vars list of Terraform variables
63
+ # which should not be printed
60
64
  # @option opts [String] :consul_url URL to access Consul at, for the
61
65
  # ``:consul_env_vars_prefix`` option.
62
66
  # @option opts [String] :consul_env_vars_prefix if specified and not nil,
@@ -96,6 +100,8 @@ module TFWrapper
96
100
  @ns_prefix = opts.fetch(:namespace_prefix, nil)
97
101
  @consul_env_vars_prefix = opts.fetch(:consul_env_vars_prefix, nil)
98
102
  @tf_vars_from_env = opts.fetch(:tf_vars_from_env, {})
103
+ @allowed_empty_vars = opts.fetch(:allowed_empty_vars, [])
104
+ @tf_sensitive_vars = opts.fetch(:tf_sensitive_vars, [])
99
105
  @tf_extra_vars = opts.fetch(:tf_extra_vars, {})
100
106
  @backend_config = opts.fetch(:backend_config, {})
101
107
  @consul_url = opts.fetch(:consul_url, nil)
@@ -162,7 +168,9 @@ module TFWrapper
162
168
  desc 'Run terraform init with appropriate arguments'
163
169
  task :init do |t|
164
170
  @before_proc.call(t.name, @tf_dir) unless @before_proc.nil?
165
- TFWrapper::Helpers.check_env_vars(@tf_vars_from_env.values)
171
+ TFWrapper::Helpers.check_env_vars(
172
+ @tf_vars_from_env.values, @allowed_empty_vars
173
+ )
166
174
  @tf_version = check_tf_version
167
175
  cmd = [
168
176
  'terraform',
@@ -314,7 +322,9 @@ module TFWrapper
314
322
  tf_vars = terraform_vars
315
323
  puts 'Terraform vars:'
316
324
  tf_vars.sort.map do |k, v|
317
- if %w[aws_access_key aws_secret_key].include?(k)
325
+ redacted_list = (%w[aws_access_key aws_secret_key] +
326
+ @tf_sensitive_vars)
327
+ if redacted_list.include?(k)
318
328
  puts "#{k} => (redacted)"
319
329
  else
320
330
  puts "#{k} => #{v}"
@@ -391,19 +401,21 @@ module TFWrapper
391
401
  cmd, @tf_dir, progress: stream_type
392
402
  )
393
403
  if status != 0 && out_err.include?('hrottling')
394
- raise StandardError, 'Terraform hit AWS API rate limiting'
404
+ raise StandardError, "#{out_err}\nTerraform hit AWS API rate limiting"
395
405
  end
396
406
  if status != 0 && out_err.include?('status code: 403')
397
- raise StandardError, 'Terraform command got 403 error - access ' \
398
- 'denied or credentials not propagated'
407
+ raise StandardError, "#{out_err}\nTerraform command got 403 error " \
408
+ '- access denied or credentials not propagated'
399
409
  end
400
410
  if status != 0 && out_err.include?('status code: 401')
401
- raise StandardError, 'Terraform command got 401 error - access ' \
402
- 'denied or credentials not propagated'
411
+ raise StandardError, "#{out_err}\nTerraform command got 401 error " \
412
+ '- access denied or credentials not propagated'
403
413
  end
404
414
  end
405
415
  # end exponential backoff
406
416
  unless status.zero?
417
+ # if we weren't streaming output, send it now
418
+ STDERR.puts out_err unless stream_type == :stream
407
419
  raise StandardError, "Errors have occurred executing: '#{cmd}' " \
408
420
  "(exited #{status})"
409
421
  end
@@ -456,7 +468,16 @@ module TFWrapper
456
468
 
457
469
  puts "Writing stack information to #{@consul_url} at: "\
458
470
  "#{@consul_env_vars_prefix}"
459
- puts JSON.pretty_generate(data)
471
+
472
+ redacted_list = (%w[aws_access_key aws_secret_key] +
473
+ @tf_sensitive_vars)
474
+ sanitized_data = data.clone
475
+ @tf_vars_from_env.each do |k, v|
476
+ # We are trying to determine which ENV var maps
477
+ # to the sensitive terraform variable
478
+ sanitized_data[v] = '(redacted)' if redacted_list.include?(k)
479
+ end
480
+ puts JSON.pretty_generate(sanitized_data)
460
481
  raw = JSON.generate(data)
461
482
  Diplomat::Kv.put(@consul_env_vars_prefix, raw)
462
483
  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.5.0'
7
+ VERSION = '0.6.3'
8
8
  end
@@ -3,6 +3,7 @@
3
3
  require 'ffi'
4
4
  require 'faraday'
5
5
  require 'json'
6
+ require 'retries'
6
7
 
7
8
  def fixture_dir
8
9
  File.absolute_path(
@@ -28,9 +29,9 @@ def desired_tf_version
28
29
  end
29
30
 
30
31
  def latest_tf_version
31
- resp = Faraday.get('https://api.github.com/repos/hashicorp/terraform/releases/latest')
32
- rel = JSON.parse(resp.body)['tag_name'].sub(/^v/, '')
33
- puts "Found latest terraform release on GitHub: #{rel}"
32
+ resp = Faraday.get('https://checkpoint-api.hashicorp.com/v1/check/terraform')
33
+ rel = JSON.parse(resp.body)['current_version']
34
+ puts "Found latest terraform release as: #{rel}"
34
35
  rel
35
36
  end
36
37
 
@@ -922,6 +922,45 @@ describe 'tfwrapper' do
922
922
  end
923
923
  end
924
924
  end
925
+ context 'when terraform fails' do
926
+ describe 'failing_tf:plan' do
927
+ before(:all) do
928
+ @out_err, @ecode = Open3.capture2e(
929
+ 'timeout -k 60 45 bundle exec rake failing_tf:plan',
930
+ chdir: @fixturepath
931
+ )
932
+ @varpath = File.join(@fixturepath, 'failing_build.tfvars.json')
933
+ end
934
+ after(:all) do
935
+ File.delete(@varpath) if File.file?(@varpath)
936
+ end
937
+ it 'does not time out' do
938
+ expect(@ecode.exitstatus).to_not eq(124)
939
+ expect(@ecode.exitstatus).to_not eq(137)
940
+ end
941
+ it 'exits 1' do
942
+ expect(@ecode.exitstatus).to eq(1)
943
+ end
944
+ it 'returns the terraform output' do
945
+ expect(@out_err).to match(
946
+ /Terraform\sv0\.11\.2.*
947
+ terraform_runner\scommand:\s'terraform\sinit\s-input=false'.*
948
+ Running\swith:\sTerraform\sv0\.11\.2.*
949
+ Initializing\sthe\sbackend\.\.\..*
950
+ Successfully\sconfigured\sthe\sbackend\s"consul".*
951
+ Terraform\shas\sbeen\ssuccessfully\sinitialized.*
952
+ terraform_runner\scommand\s'terraform\sinit\s-input=false'\s
953
+ finished\sand\sexited\s0.*
954
+ consul_key_prefix\.landscapeTest:\s"path_prefix":\srequired\s
955
+ field\sis\snot\sset.*
956
+ rake\saborted.*
957
+ StandardError:\sErrors\shave\soccurred\sexecuting:\s
958
+ 'terraform\splan\s-var-file.*
959
+ Tasks:\sTOP\s=>\sfailing_tf:plan.*/xm
960
+ )
961
+ end
962
+ end
963
+ end
925
964
  end
926
965
  end
927
966
  end
@@ -30,3 +30,9 @@ TFWrapper::RakeTasks.install_tasks(
30
30
  namespace_prefix: 'lines',
31
31
  landscape_progress: :lines
32
32
  )
33
+
34
+ TFWrapper::RakeTasks.install_tasks(
35
+ 'failingTerraform/',
36
+ namespace_prefix: 'failing',
37
+ landscape_progress: :dots
38
+ )
@@ -0,0 +1,28 @@
1
+ terraform {
2
+ required_version = "> 0.9.0"
3
+ backend "consul" {
4
+ address = "127.0.0.1:8500"
5
+ path = "terraform/landscapeTestFailure"
6
+ }
7
+ }
8
+
9
+ provider "consul" {
10
+ address = "127.0.0.1:8500"
11
+ version = "1.0.0"
12
+ }
13
+
14
+ locals {
15
+ keys = {
16
+ foo = "foo2val"
17
+ bar = "bar2val"
18
+ baz = "baz2val"
19
+ }
20
+ }
21
+
22
+ variable "foo" { default = "bar" }
23
+
24
+ resource "consul_key_prefix" "landscapeTest" {
25
+ invalid_param = "whoCares"
26
+ }
27
+
28
+ output "foo_variable" { value = "${var.foo}" }
@@ -8,7 +8,7 @@ terraform {
8
8
 
9
9
  provider "consul" {
10
10
  address = "127.0.0.1:8500"
11
- version = "~> 1.0"
11
+ version = "1.0.0"
12
12
  }
13
13
 
14
14
  locals {
@@ -1,12 +1,12 @@
1
1
  Terraform v0.11.2
2
2
 
3
3
  Your version of Terraform is out of date! The latest version
4
- is 0.11.5. You can update by downloading from www.terraform.io/downloads.html
5
- terraform_runner command: 'terraform init -input=false' (in /home/jantman/manheim/git/github_dot_com/tfwrapper/spec/fixtures/landscapeTest)
4
+ is %%TF_LATEST_VER%%. You can update by downloading from www.terraform.io/downloads.html
5
+ terraform_runner command: 'terraform init -input=false' (in %%FIXTUREPATH%%)
6
6
  Running with: Terraform v0.11.2
7
7
 
8
8
  Your version of Terraform is out of date! The latest version
9
- is 0.11.5. You can update by downloading from www.terraform.io/downloads.html
9
+ is %%TF_LATEST_VER%%. You can update by downloading from www.terraform.io/downloads.html
10
10
 
11
11
  Initializing the backend...
12
12
  
@@ -27,10 +27,10 @@ If you ever set or change modules or backend configuration for Terraform,
27
27
  rerun this command to reinitialize your working directory. If you forget, other
28
28
  commands will detect it and remind you to do so if necessary.
29
29
  terraform_runner command 'terraform init -input=false' finished and exited 0
30
- Terraform vars written to: /home/jantman/manheim/git/github_dot_com/tfwrapper/spec/fixtures/landscapeTest/dots_build.tfvars.json
31
- terraform_runner command: 'terraform plan -var-file /home/jantman/manheim/git/github_dot_com/tfwrapper/spec/fixtures/landscapeTest/dots_build.tfvars.json' (in /home/jantman/manheim/git/github_dot_com/tfwrapper/spec/fixtures/landscapeTest)
30
+ Terraform vars written to: %%FIXTUREPATH%%/dots_build.tfvars.json
31
+ terraform_runner command: 'terraform plan -var-file %%FIXTUREPATH%%/dots_build.tfvars.json' (in %%FIXTUREPATH%%)
32
32
  Terraform vars:
33
- ..........................terraform_runner command 'terraform plan -var-file /home/jantman/manheim/git/github_dot_com/tfwrapper/spec/fixtures/landscapeTest/dots_build.tfvars.json' finished and exited 0
33
+ ..........................terraform_runner command 'terraform plan -var-file %%FIXTUREPATH%%/dots_build.tfvars.json' finished and exited 0
34
34
 
35
35
  ~ consul_key_prefix.landscapeTest
36
36
   subkeys.foo: {
@@ -43,4 +43,3 @@ Terraform vars:
43
43
  }
44
44
 
45
45
  Plan: 0 to add, 1 to change, 0 to destroy.
46
-
@@ -1,12 +1,12 @@
1
1
  Terraform v0.11.2
2
2
 
3
3
  Your version of Terraform is out of date! The latest version
4
- is 0.11.5. You can update by downloading from www.terraform.io/downloads.html
5
- terraform_runner command: 'terraform init -input=false' (in /home/jantman/manheim/git/github_dot_com/tfwrapper/spec/fixtures/landscapeTest)
4
+ is %%TF_LATEST_VER%%. You can update by downloading from www.terraform.io/downloads.html
5
+ terraform_runner command: 'terraform init -input=false' (in %%FIXTUREPATH%%)
6
6
  Running with: Terraform v0.11.2
7
7
 
8
8
  Your version of Terraform is out of date! The latest version
9
- is 0.11.5. You can update by downloading from www.terraform.io/downloads.html
9
+ is %%TF_LATEST_VER%%. You can update by downloading from www.terraform.io/downloads.html
10
10
 
11
11
  Initializing the backend...
12
12
  
@@ -27,8 +27,8 @@ If you ever set or change modules or backend configuration for Terraform,
27
27
  rerun this command to reinitialize your working directory. If you forget, other
28
28
  commands will detect it and remind you to do so if necessary.
29
29
  terraform_runner command 'terraform init -input=false' finished and exited 0
30
- Terraform vars written to: /home/jantman/manheim/git/github_dot_com/tfwrapper/spec/fixtures/landscapeTest/lines_build.tfvars.json
31
- terraform_runner command: 'terraform plan -var-file /home/jantman/manheim/git/github_dot_com/tfwrapper/spec/fixtures/landscapeTest/lines_build.tfvars.json' (in /home/jantman/manheim/git/github_dot_com/tfwrapper/spec/fixtures/landscapeTest)
30
+ Terraform vars written to: %%FIXTUREPATH%%/lines_build.tfvars.json
31
+ terraform_runner command: 'terraform plan -var-file %%FIXTUREPATH%%/lines_build.tfvars.json' (in %%FIXTUREPATH%%)
32
32
  Terraform vars:
33
33
  .
34
34
  .
@@ -56,7 +56,7 @@ Terraform vars:
56
56
  .
57
57
  .
58
58
  .
59
- terraform_runner command 'terraform plan -var-file /home/jantman/manheim/git/github_dot_com/tfwrapper/spec/fixtures/landscapeTest/lines_build.tfvars.json' finished and exited 0
59
+ terraform_runner command 'terraform plan -var-file %%FIXTUREPATH%%/lines_build.tfvars.json' finished and exited 0
60
60
  ~ consul_key_prefix.landscapeTest
61
61
   subkeys.foo: {
62
62
  - "bar": "barval",
@@ -68,4 +68,3 @@ terraform_runner command 'terraform plan -var-file /home/jantman/manheim/git/git
68
68
  }
69
69
 
70
70
  Plan: 0 to add, 1 to change, 0 to destroy.
71
-
@@ -8,6 +8,7 @@ terraform {
8
8
 
9
9
  provider "consul" {
10
10
  address = "127.0.0.1:8500"
11
+ version = "1.0.0"
11
12
  }
12
13
 
13
14
  variable "foo" { default = "bar" }
@@ -8,6 +8,7 @@ terraform {
8
8
 
9
9
  provider "consul" {
10
10
  address = "127.0.0.1:8500"
11
+ version = "1.0.0"
11
12
  }
12
13
 
13
14
  variable "foo" {}
@@ -8,6 +8,7 @@ terraform {
8
8
 
9
9
  provider "consul" {
10
10
  address = "127.0.0.1:8500"
11
+ version = "1.0.0"
11
12
  }
12
13
 
13
14
  variable "foo" {}
@@ -7,6 +7,7 @@ terraform {
7
7
 
8
8
  provider "consul" {
9
9
  address = "127.0.0.1:8500"
10
+ version = "1.0.0"
10
11
  }
11
12
 
12
13
  variable "foo" {}
@@ -7,6 +7,7 @@ terraform {
7
7
 
8
8
  provider "consul" {
9
9
  address = "127.0.0.1:8500"
10
+ version = "1.0.0"
10
11
  }
11
12
 
12
13
  variable "foo" {}
@@ -213,10 +213,16 @@ describe TFWrapper::Helpers do
213
213
  it 'returns nil if vars present' do
214
214
  ENV['foo'] = 'fooval'
215
215
  ENV['bar'] = 'barval'
216
- expect(TFWrapper::Helpers.check_env_vars(%w[foo bar])).to be_nil
216
+ expect(TFWrapper::Helpers.check_env_vars(%w[foo bar], [])).to be_nil
217
217
  ENV.delete('foo')
218
218
  ENV.delete('bar')
219
219
  end
220
+ it 'returns nil if vars ignored' do
221
+ ENV['foo'] = ''
222
+ expect(TFWrapper::Helpers.check_env_vars(%w[foo bar], %w[foo bar]))
223
+ .to be_nil
224
+ ENV.delete('foo')
225
+ end
220
226
  it 'exits if not present' do
221
227
  ENV.delete('foo')
222
228
  ENV.delete('bar')
@@ -224,7 +230,7 @@ describe TFWrapper::Helpers do
224
230
  .with('ERROR: Environment variable \'foo\' must be set.')
225
231
  expect(STDOUT).to receive(:puts)
226
232
  .with('ERROR: Environment variable \'bar\' must be set.')
227
- expect { TFWrapper::Helpers.check_env_vars(%w[foo bar]) }
233
+ expect { TFWrapper::Helpers.check_env_vars(%w[foo bar], %w[baz]) }
228
234
  .to raise_error StandardError, 'Missing or empty environment ' \
229
235
  'variables: ["foo", "bar"]'
230
236
  end
@@ -235,11 +241,31 @@ describe TFWrapper::Helpers do
235
241
  .with("ERROR: Environment variable 'foo' must not be empty.")
236
242
  expect(STDOUT).to receive(:puts)
237
243
  .with("ERROR: Environment variable 'bar' must not be empty.")
238
- expect { TFWrapper::Helpers.check_env_vars(%w[foo bar]) }
244
+ expect { TFWrapper::Helpers.check_env_vars(%w[foo bar], %w[baz]) }
239
245
  .to raise_error StandardError, 'Missing or empty environment ' \
240
246
  'variables: ["foo", "bar"]'
241
247
  ENV.delete('foo')
242
248
  ENV.delete('bar')
243
249
  end
250
+ it 'exits if not present and partially ignored' do
251
+ ENV.delete('foo')
252
+ ENV.delete('bar')
253
+ expect(STDOUT).to receive(:puts)
254
+ .with('ERROR: Environment variable \'foo\' must be set.')
255
+ expect { TFWrapper::Helpers.check_env_vars(%w[foo bar], %w[bar]) }
256
+ .to raise_error StandardError, 'Missing or empty environment ' \
257
+ 'variables: ["foo"]'
258
+ end
259
+ it 'exits if empty and partially ignored' do
260
+ ENV['foo'] = ''
261
+ ENV['bar'] = ' '
262
+ expect(STDOUT).to receive(:puts)
263
+ .with("ERROR: Environment variable 'foo' must not be empty.")
264
+ expect { TFWrapper::Helpers.check_env_vars(%w[foo bar], %w[bar]) }
265
+ .to raise_error StandardError, 'Missing or empty environment ' \
266
+ 'variables: ["foo"]'
267
+ ENV.delete('foo')
268
+ ENV.delete('bar')
269
+ end
244
270
  end
245
271
  end
@@ -59,6 +59,8 @@ describe TFWrapper::RakeTasks do
59
59
  expect(cls.instance_variable_get('@tf_dir')).to eq('/rake/dir/tfdir')
60
60
  expect(cls.instance_variable_get('@consul_env_vars_prefix')).to eq(nil)
61
61
  expect(cls.instance_variable_get('@tf_vars_from_env')).to eq({})
62
+ expect(cls.instance_variable_get('@allowed_empty_vars')).to eq([])
63
+ expect(cls.instance_variable_get('@tf_sensitive_vars')).to eq([])
62
64
  expect(cls.instance_variable_get('@tf_extra_vars')).to eq({})
63
65
  expect(cls.instance_variable_get('@backend_config')).to eq({})
64
66
  expect(cls.instance_variable_get('@consul_url')).to eq(nil)
@@ -87,6 +89,8 @@ describe TFWrapper::RakeTasks do
87
89
  'tf/dir',
88
90
  consul_env_vars_prefix: 'cvprefix',
89
91
  tf_vars_from_env: { 'foo' => 'bar' },
92
+ allowed_empty_vars: %w[bar blam],
93
+ tf_sensitive_vars: %w[secret],
90
94
  tf_extra_vars: { 'baz' => 'blam' },
91
95
  consul_url: 'foobar',
92
96
  before_proc: bproc,
@@ -100,6 +104,10 @@ describe TFWrapper::RakeTasks do
100
104
  .to eq('cvprefix')
101
105
  expect(cls.instance_variable_get('@tf_vars_from_env'))
102
106
  .to eq('foo' => 'bar')
107
+ expect(cls.instance_variable_get('@allowed_empty_vars'))
108
+ .to eq(%w[bar blam])
109
+ expect(cls.instance_variable_get('@tf_sensitive_vars'))
110
+ .to eq(%w[secret])
103
111
  expect(cls.instance_variable_get('@tf_extra_vars'))
104
112
  .to eq('baz' => 'blam')
105
113
  expect(cls.instance_variable_get('@backend_config')).to eq({})
@@ -317,6 +325,7 @@ describe TFWrapper::RakeTasks do
317
325
  .to eq(Gem::Version.new('0.0.0'))
318
326
  vars = { foo: 'bar', baz: 'blam' }
319
327
  subject.instance_variable_set('@tf_vars_from_env', vars)
328
+ subject.instance_variable_set('@allowed_empty_vars', ['bar'])
320
329
  allow(TFWrapper::Helpers).to receive(:check_env_vars)
321
330
  allow(ENV).to receive(:[])
322
331
  subject.instance_variable_set(
@@ -329,7 +338,7 @@ describe TFWrapper::RakeTasks do
329
338
  allow(subject).to receive(:check_tf_version)
330
339
  .and_return(Gem::Version.new('0.9.5'))
331
340
  expect(TFWrapper::Helpers)
332
- .to receive(:check_env_vars).once.ordered.with(vars.values)
341
+ .to receive(:check_env_vars).once.ordered.with(vars.values, ['bar'])
333
342
  expect(subject).to receive(:check_tf_version).once.ordered
334
343
  expect(subject).to receive(:terraform_runner).once.ordered
335
344
  .with('terraform init -input=false '\
@@ -351,7 +360,7 @@ describe TFWrapper::RakeTasks do
351
360
  allow(subject).to receive(:check_tf_version)
352
361
  .and_return(Gem::Version.new('0.10.2'))
353
362
  expect(TFWrapper::Helpers)
354
- .to receive(:check_env_vars).once.ordered.with(vars.values)
363
+ .to receive(:check_env_vars).once.ordered.with(vars.values, [])
355
364
  expect(subject).to receive(:check_tf_version).once.ordered
356
365
  expect(subject).to receive(:terraform_runner).once.ordered
357
366
  .with('terraform init -input=false')
@@ -827,6 +836,7 @@ describe TFWrapper::RakeTasks do
827
836
  Rake.application = rake_application
828
837
  end
829
838
  before do
839
+ subject.instance_variable_set('@tf_sensitive_vars', ['secret'])
830
840
  subject.install_write_tf_vars
831
841
  end
832
842
 
@@ -839,7 +849,8 @@ describe TFWrapper::RakeTasks do
839
849
  vars = {
840
850
  'foo' => 'bar',
841
851
  'baz' => 'blam',
842
- 'aws_access_key' => 'ak'
852
+ 'aws_access_key' => 'ak',
853
+ 'secret' => 'abc'
843
854
  }
844
855
  allow(subject).to receive(:terraform_vars).and_return(vars)
845
856
  allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
@@ -851,6 +862,8 @@ describe TFWrapper::RakeTasks do
851
862
  expect(STDOUT).to receive(:puts).once.with('Terraform vars:')
852
863
  expect(STDOUT).to receive(:puts)
853
864
  .once.with('aws_access_key => (redacted)')
865
+ expect(STDOUT).to receive(:puts)
866
+ .once.with('secret => (redacted)')
854
867
  expect(STDOUT).to receive(:puts).once.with('baz => blam')
855
868
  expect(STDOUT).to receive(:puts).once.with('foo => bar')
856
869
  expect(File).to receive(:open).once.with('file.tfvars.json', 'w')
@@ -912,6 +925,7 @@ describe TFWrapper::RakeTasks do
912
925
  Rake.application = rake_application
913
926
  end
914
927
  before do
928
+ subject.instance_variable_set('@tf_sensitive_vars', ['secret'])
915
929
  subject.instance_variable_set('@ns_prefix', 'foo')
916
930
  subject.install_write_tf_vars
917
931
  end
@@ -925,7 +939,8 @@ describe TFWrapper::RakeTasks do
925
939
  vars = {
926
940
  'foo' => 'bar',
927
941
  'baz' => 'blam',
928
- 'aws_access_key' => 'ak'
942
+ 'aws_access_key' => 'ak',
943
+ 'secret' => 'abc'
929
944
  }
930
945
  allow(subject).to receive(:terraform_vars).and_return(vars)
931
946
  allow(subject).to receive(:var_file_path)
@@ -938,6 +953,8 @@ describe TFWrapper::RakeTasks do
938
953
  expect(STDOUT).to receive(:puts).once.with('Terraform vars:')
939
954
  expect(STDOUT).to receive(:puts)
940
955
  .once.with('aws_access_key => (redacted)')
956
+ expect(STDOUT).to receive(:puts)
957
+ .once.with('secret => (redacted)')
941
958
  expect(STDOUT).to receive(:puts).once.with('baz => blam')
942
959
  expect(STDOUT).to receive(:puts).once.with('foo => bar')
943
960
  expect(File).to receive(:open).once.with('foo_file.tfvars.json', 'w')
@@ -1233,10 +1250,12 @@ describe TFWrapper::RakeTasks do
1233
1250
  expect(STDERR).to receive(:puts).once
1234
1251
  .with("terraform_runner command: 'foo' (in tfdir)")
1235
1252
  expect(STDERR).to receive(:puts).once
1236
- .with(/terraform_runner\sfailed\swith\sTerraform\shit\sAWS\sAPI\srate\s
1253
+ .with(/terraform_runner\sfailed\swith\sfoo\sThrottling\sbar\s+
1254
+ Terraform\shit\sAWS\sAPI\srate\s
1237
1255
  limiting;\sretry\sattempt\s1;\s.+\sseconds\shave\spassed\./x)
1238
1256
  expect(STDERR).to receive(:puts).once
1239
- .with(/terraform_runner\sfailed\swith\sTerraform\shit\sAWS\sAPI\srate\s
1257
+ .with(/terraform_runner\sfailed\swith\sfoo\sThrottling\sbar\s+
1258
+ Terraform\shit\sAWS\sAPI\srate\s
1240
1259
  limiting;\sretry\sattempt\s2;\s.+\sseconds\shave\spassed\./x)
1241
1260
  expect(STDERR).to receive(:puts).once
1242
1261
  .with("terraform_runner command 'foo' finished and exited 0")
@@ -1258,11 +1277,13 @@ describe TFWrapper::RakeTasks do
1258
1277
  expect(STDERR).to receive(:puts).once
1259
1278
  .with("terraform_runner command: 'foo' (in tfdir)")
1260
1279
  expect(STDERR).to receive(:puts).once
1261
- .with(/terraform_runner\sfailed\swith\sTerraform\scommand\sgot\s403\s
1280
+ .with(/terraform_runner\sfailed\swith\sfoo\sstatus\scode:\s403\sbar\s+
1281
+ Terraform\scommand\sgot\s403\s
1262
1282
  error\s-\saccess\sdenied\sor\scredentials\snot\spropagated;\sretry\s
1263
1283
  attempt\s1;\s.+\sseconds\shave\spassed\./x)
1264
1284
  expect(STDERR).to receive(:puts).once
1265
- .with(/terraform_runner\sfailed\swith\sTerraform\scommand\sgot\s403\s
1285
+ .with(/terraform_runner\sfailed\swith\sfoo\sstatus\scode:\s403\sbar\s+
1286
+ Terraform\scommand\sgot\s403\s
1266
1287
  error\s-\saccess\sdenied\sor\scredentials\snot\spropagated;\sretry\s
1267
1288
  attempt\s2;\s.+\sseconds\shave\spassed\./x)
1268
1289
  expect(STDERR).to receive(:puts).once
@@ -1285,11 +1306,13 @@ describe TFWrapper::RakeTasks do
1285
1306
  expect(STDERR).to receive(:puts).once
1286
1307
  .with("terraform_runner command: 'foo' (in tfdir)")
1287
1308
  expect(STDERR).to receive(:puts).once
1288
- .with(/terraform_runner\sfailed\swith\sTerraform\scommand\sgot\s401\s
1309
+ .with(/terraform_runner\sfailed\swith\sfoo\sstatus\scode:\s401\sbar\s+
1310
+ Terraform\scommand\sgot\s401\s
1289
1311
  error\s-\saccess\sdenied\sor\scredentials\snot\spropagated;\sretry\s
1290
1312
  attempt\s1;\s.+\sseconds\shave\spassed\./x)
1291
1313
  expect(STDERR).to receive(:puts).once
1292
- .with(/terraform_runner\sfailed\swith\sTerraform\scommand\sgot\s401\s
1314
+ .with(/terraform_runner\sfailed\swith\sfoo\sstatus\scode:\s401\sbar\s+
1315
+ Terraform\scommand\sgot\s401\s
1293
1316
  error\s-\saccess\sdenied\sor\scredentials\snot\spropagated;\sretry\s
1294
1317
  attempt\s2;\s.+\sseconds\shave\spassed\./x)
1295
1318
  expect(STDERR).to receive(:puts).once
@@ -1306,6 +1329,18 @@ describe TFWrapper::RakeTasks do
1306
1329
  expect { subject.terraform_runner('foo') }
1307
1330
  .to raise_error('Errors have occurred executing: \'foo\' (exited 1)')
1308
1331
  end
1332
+ it 'prints output to STDERR if plan exits non-zero and not :stream' do
1333
+ allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1334
+ .and_return(['myoutput', 1])
1335
+ expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output).once
1336
+ .with('foo', 'tfdir', progress: :dots)
1337
+ expect(STDERR).to receive(:puts).once
1338
+ .with('terraform_runner command: \'foo\' (in tfdir)')
1339
+ expect(STDERR).to receive(:puts).once
1340
+ .with('myoutput')
1341
+ expect { subject.terraform_runner('foo', progress: :dots) }
1342
+ .to raise_error('Errors have occurred executing: \'foo\' (exited 1)')
1343
+ end
1309
1344
  it 'raises an error if the progress option is invalid' do
1310
1345
  allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1311
1346
  .and_return(['', 1])
@@ -1386,21 +1421,28 @@ describe TFWrapper::RakeTasks do
1386
1421
  describe '#update_consul_stack_env_vars' do
1387
1422
  context 'when @consul_url and @consul_env_vars_prefix are specified' do
1388
1423
  it 'saves the variables in Consul' do
1389
- vars = { 'foo' => 'bar', 'baz' => 'blam' }
1390
- expected = { 'bar' => 'barVal', 'blam' => 'blamVal' }
1424
+ vars = { 'foo' => 'bar', 'baz' => 'blam', 'secret' => 'SECRET' }
1425
+ expected = { 'bar' => 'barVal',
1426
+ 'blam' => 'blamVal',
1427
+ 'SECRET' => 'abc' }
1428
+ sanitized = { 'bar' => 'barVal',
1429
+ 'blam' => 'blamVal',
1430
+ 'SECRET' => '(redacted)' }
1391
1431
  subject.instance_variable_set('@tf_vars_from_env', vars)
1392
1432
  subject.instance_variable_set('@consul_url', 'foo://bar')
1393
1433
  subject.instance_variable_set('@consul_env_vars_prefix', 'my/prefix')
1434
+ subject.instance_variable_set('@tf_sensitive_vars', ['secret'])
1394
1435
  allow(ENV).to receive(:[])
1395
1436
  allow(ENV).to receive(:[]).with('CONSUL_HOST').and_return('chost')
1396
1437
  allow(ENV).to receive(:[]).with('bar').and_return('barVal')
1397
1438
  allow(ENV).to receive(:[]).with('blam').and_return('blamVal')
1439
+ allow(ENV).to receive(:[]).with('SECRET').and_return('abc')
1398
1440
  allow(Diplomat::Kv).to receive(:put)
1399
1441
 
1400
1442
  expect(STDOUT).to receive(:puts).once
1401
1443
  .with('Writing stack information to foo://bar at: my/prefix')
1402
1444
  expect(STDOUT).to receive(:puts).once
1403
- .with(JSON.pretty_generate(expected))
1445
+ .with(JSON.pretty_generate(sanitized))
1404
1446
  expect(Diplomat::Kv).to receive(:put)
1405
1447
  .once.with('my/prefix', JSON.generate(expected))
1406
1448
  subject.update_consul_stack_env_vars
@@ -23,6 +23,7 @@ Gem::Specification.new do |gem|
23
23
  # awful, but these are to allow use with ruby 2.1.x
24
24
  gem.add_development_dependency 'ruby_dep', '1.3.1'
25
25
  gem.add_development_dependency 'listen', '3.0.7'
26
+ gem.add_development_dependency 'rb-inotify', '0.9.10'
26
27
 
27
28
  # guard-yard uses Pry which needs readline. If we're in RVM, we'll need this:
28
29
  gem.add_development_dependency 'rb-readline', '~> 0.5'
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.5.0
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - jantman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-30 00:00:00.000000000 Z
11
+ date: 2020-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: retries
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
54
  version: 3.0.7
55
+ - !ruby/object:Gem::Dependency
56
+ name: rb-inotify
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.9.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.9.10
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rb-readline
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -351,13 +365,13 @@ extra_rdoc_files: []
351
365
  files:
352
366
  - ".gitignore"
353
367
  - ".rubocop.yml"
368
+ - ".travis.yml"
354
369
  - ChangeLog.md
355
370
  - Gemfile
356
371
  - Guardfile
357
372
  - LICENSE
358
373
  - README.md
359
374
  - Rakefile
360
- - circle.yml
361
375
  - lib/tfwrapper.rb
362
376
  - lib/tfwrapper/helpers.rb
363
377
  - lib/tfwrapper/raketasks.rb
@@ -367,6 +381,7 @@ files:
367
381
  - spec/acceptance/consulserver.rb
368
382
  - spec/fixtures/Rakefile
369
383
  - spec/fixtures/landscapeTest/Rakefile
384
+ - spec/fixtures/landscapeTest/failingTerraform/main.tf
370
385
  - spec/fixtures/landscapeTest/main.tf
371
386
  - spec/fixtures/landscapeTest/state.json
372
387
  - spec/fixtures/landscapeTest/with_landscape_default.out
@@ -406,7 +421,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
406
421
  version: '0'
407
422
  requirements: []
408
423
  rubyforge_project:
409
- rubygems_version: 2.5.2
424
+ rubygems_version: 2.7.6
410
425
  signing_key:
411
426
  specification_version: 4
412
427
  summary: Rake tasks for running Hashicorp Terraform sanely
@@ -416,6 +431,7 @@ test_files:
416
431
  - spec/acceptance/consulserver.rb
417
432
  - spec/fixtures/Rakefile
418
433
  - spec/fixtures/landscapeTest/Rakefile
434
+ - spec/fixtures/landscapeTest/failingTerraform/main.tf
419
435
  - spec/fixtures/landscapeTest/main.tf
420
436
  - spec/fixtures/landscapeTest/state.json
421
437
  - spec/fixtures/landscapeTest/with_landscape_default.out
data/circle.yml DELETED
@@ -1,32 +0,0 @@
1
-
2
- dependencies:
3
- cache_directories:
4
- - "~/.rvm/gems"
5
- pre:
6
- - sudo add-apt-repository -y ppa:git-core/ppa && sudo apt-get update && sudo apt-get install git
7
- override:
8
- - 'bundle install --without landscape'
9
- - 'rvm 2.0.0-p598 exec bundle install --without landscape'
10
- - 'rvm 2.1.8 exec bundle install --without landscape'
11
- - 'rvm 2.2.5 exec bundle install --without landscape'
12
- - 'rvm 2.3.1 exec bundle install --without landscape'
13
- - 'rvm 2.4.1 exec bundle install'
14
-
15
- test:
16
- override:
17
- - 'bundle exec ruby --version'
18
- - 'bundle exec rake spec:unit'
19
- - 'bundle exec rake rubocop'
20
- - 'rvm 2.0.0-p598 exec bundle exec rake spec:unit'
21
- - 'rvm 2.1.8 exec bundle exec rake spec:unit'
22
- - 'rvm 2.2.5 exec bundle exec rake spec:unit'
23
- - 'rvm 2.3.1 exec bundle exec rake spec:unit'
24
- - 'rvm 2.4.1 exec bundle exec rake spec:unit'
25
- - 'rvm 2.3.1 exec bundle exec rake spec:acceptance TF_VERSION=0.9.2'
26
- - 'rvm 2.3.1 exec bundle exec rake spec:acceptance TF_VERSION=0.9.7'
27
- - 'rvm 2.3.1 exec bundle exec rake spec:acceptance TF_VERSION=0.10.0'
28
- - 'rvm 2.3.1 exec bundle exec rake spec:acceptance TF_VERSION=0.10.2'
29
- - 'rvm 2.3.1 exec bundle exec rake spec:acceptance TF_VERSION=0.11.2'
30
- - 'rvm 2.3.1 exec bundle exec rake spec:acceptance TF_VERSION=latest'
31
- - 'rvm 2.4.1 exec bundle exec rake spec:acceptance TF_VERSION=0.11.2'
32
- - 'bundle exec rake yard:generate'