tfwrapper 0.4.1 → 0.6.2

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.
@@ -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.4.1'
7
+ VERSION = '0.6.2'
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(
@@ -24,12 +25,24 @@ def desired_tf_version
24
25
  return ENV['TF_VERSION']
25
26
  end
26
27
  # else get the latest release from GitHub
27
- resp = Faraday.get('https://api.github.com/repos/hashicorp/terraform/releases/latest')
28
- rel = JSON.parse(resp.body)['tag_name'].sub(/^v/, '')
29
- puts "Found latest terraform release on GitHub: #{rel}"
28
+ latest_tf_version
29
+ end
30
+
31
+ def latest_tf_version
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}"
30
35
  rel
31
36
  end
32
37
 
38
+ # Given the example terraform plan output with placeholders for the
39
+ # latest terraform version and fixtures path, return the interpolated string.
40
+ def clean_tf_plan_output(raw_out, latest_ver, fixture_path)
41
+ raw_out
42
+ .gsub('%%TF_LATEST_VER%%', latest_ver)
43
+ .gsub('%%FIXTUREPATH%%', fixture_path)
44
+ end
45
+
33
46
  class HashicorpFetcher
34
47
  def initialize(program, version)
35
48
  @program = program
@@ -18,6 +18,10 @@ else
18
18
  APPLY_CMD = 'terraform apply'
19
19
  end
20
20
 
21
+ without_landscape = !HAVE_LANDSCAPE && TF_VERSION == '0.11.2'
22
+ with_landscape = HAVE_LANDSCAPE && TF_VERSION == '0.11.2'
23
+ latest_tf_ver = latest_tf_version
24
+
21
25
  Diplomat.configure do |config|
22
26
  config.url = 'http://127.0.0.1:8500'
23
27
  end
@@ -734,4 +738,229 @@ describe 'tfwrapper' do
734
738
  end
735
739
  end
736
740
  end
741
+ context 'landscapeTest', order: :defined do
742
+ before(:all) do
743
+ @fixturepath = File.absolute_path(
744
+ File.join(File.dirname(__FILE__), '..', 'fixtures', 'landscapeTest')
745
+ )
746
+ end
747
+ before(:each) do
748
+ Diplomat::Kv.put(
749
+ 'landscapeTest/foo', '{"bar":"barval","baz":"bazval","foo":"fooval"}'
750
+ )
751
+ Diplomat::Kv.put(
752
+ 'terraform/landscapeTest',
753
+ File.read(File.join(@fixturepath, 'state.json'))
754
+ )
755
+ end
756
+ context 'without landscape installed', if: without_landscape do
757
+ describe 'default_tf:plan' do
758
+ before(:all) do
759
+ @out_err, @ecode = Open3.capture2e(
760
+ 'timeout -k 60 45 bundle exec rake default_tf:plan',
761
+ chdir: @fixturepath
762
+ )
763
+ @varpath = File.join(@fixturepath, 'default_build.tfvars.json')
764
+ end
765
+ after(:all) do
766
+ File.delete(@varpath) if File.file?(@varpath)
767
+ end
768
+ it 'does not time out' do
769
+ expect(@ecode.exitstatus).to_not eq(124)
770
+ expect(@ecode.exitstatus).to_not eq(137)
771
+ end
772
+ it 'exits zero' do
773
+ expect(@ecode.exitstatus).to eq(0)
774
+ end
775
+ it 'returns unmodified terraform output' do
776
+ expected = clean_tf_plan_output(
777
+ File.read(File.join(@fixturepath, 'without_landscape.out')),
778
+ latest_tf_ver, @fixturepath
779
+ )
780
+ expect(@out_err.strip).to eq(expected.strip)
781
+ end
782
+ end
783
+ end
784
+ context 'with landscape installed', if: with_landscape do
785
+ context 'and disabled' do
786
+ describe 'disabled_tf:plan' do
787
+ before(:all) do
788
+ @out_err, @ecode = Open3.capture2e(
789
+ 'timeout -k 60 45 bundle exec rake disabled_tf:plan',
790
+ chdir: @fixturepath
791
+ )
792
+ @varpath = File.join(@fixturepath, 'disabled_build.tfvars.json')
793
+ end
794
+ after(:all) do
795
+ File.delete(@varpath) if File.file?(@varpath)
796
+ end
797
+ it 'does not time out' do
798
+ expect(@ecode.exitstatus).to_not eq(124)
799
+ expect(@ecode.exitstatus).to_not eq(137)
800
+ end
801
+ it 'exits zero' do
802
+ expect(@ecode.exitstatus).to eq(0)
803
+ end
804
+ it 'returns unmodified terraform output' do
805
+ expected = clean_tf_plan_output(
806
+ File.read(File.join(@fixturepath, 'without_landscape.out')),
807
+ latest_tf_ver, @fixturepath
808
+ ).gsub('default_build.tfvars.json', 'disabled_build.tfvars.json')
809
+ expect(@out_err.strip).to eq(expected.strip)
810
+ end
811
+ end
812
+ end
813
+ context 'and default progress' do
814
+ describe 'default_tf:plan' do
815
+ before(:all) do
816
+ @out_err, @ecode = Open3.capture2e(
817
+ 'timeout -k 60 45 bundle exec rake default_tf:plan',
818
+ chdir: @fixturepath
819
+ )
820
+ @varpath = File.join(@fixturepath, 'default_build.tfvars.json')
821
+ end
822
+ after(:all) do
823
+ File.delete(@varpath) if File.file?(@varpath)
824
+ end
825
+ it 'does not time out' do
826
+ expect(@ecode.exitstatus).to_not eq(124)
827
+ expect(@ecode.exitstatus).to_not eq(137)
828
+ end
829
+ it 'exits zero' do
830
+ expect(@ecode.exitstatus).to eq(0)
831
+ end
832
+ it 'returns landscape output and no plan output' do
833
+ expected = clean_tf_plan_output(
834
+ File.read(File.join(@fixturepath, 'with_landscape_default.out')),
835
+ latest_tf_ver, @fixturepath
836
+ )
837
+ expect(@out_err.strip).to eq(expected.strip)
838
+ end
839
+ end
840
+ end
841
+ context 'and dots progress' do
842
+ describe 'dots_tf:plan' do
843
+ before(:all) do
844
+ @out_err, @ecode = Open3.capture2e(
845
+ 'timeout -k 60 45 bundle exec rake dots_tf:plan',
846
+ chdir: @fixturepath
847
+ )
848
+ @varpath = File.join(@fixturepath, 'dots_build.tfvars.json')
849
+ end
850
+ after(:all) do
851
+ File.delete(@varpath) if File.file?(@varpath)
852
+ end
853
+ it 'does not time out' do
854
+ expect(@ecode.exitstatus).to_not eq(124)
855
+ expect(@ecode.exitstatus).to_not eq(137)
856
+ end
857
+ it 'exits zero' do
858
+ expect(@ecode.exitstatus).to eq(0)
859
+ end
860
+ it 'returns progress dots for plan output and landscape output' do
861
+ expected = clean_tf_plan_output(
862
+ File.read(File.join(@fixturepath, 'with_landscape_dots.out')),
863
+ latest_tf_ver, @fixturepath
864
+ )
865
+ expect(@out_err.strip).to eq(expected.strip)
866
+ end
867
+ end
868
+ end
869
+ context 'and lines progress' do
870
+ describe 'lines_tf:plan' do
871
+ before(:all) do
872
+ @out_err, @ecode = Open3.capture2e(
873
+ 'timeout -k 60 45 bundle exec rake lines_tf:plan',
874
+ chdir: @fixturepath
875
+ )
876
+ @varpath = File.join(@fixturepath, 'lines_build.tfvars.json')
877
+ end
878
+ after(:all) do
879
+ File.delete(@varpath) if File.file?(@varpath)
880
+ end
881
+ it 'does not time out' do
882
+ expect(@ecode.exitstatus).to_not eq(124)
883
+ expect(@ecode.exitstatus).to_not eq(137)
884
+ end
885
+ it 'exits zero' do
886
+ expect(@ecode.exitstatus).to eq(0)
887
+ end
888
+ it 'returns progress lines for plan output and landscape output' do
889
+ expected = clean_tf_plan_output(
890
+ File.read(File.join(@fixturepath, 'with_landscape_lines.out')),
891
+ latest_tf_ver, @fixturepath
892
+ )
893
+ expect(@out_err.strip).to eq(expected.strip)
894
+ end
895
+ end
896
+ end
897
+ context 'and stream progress' do
898
+ describe 'stream_tf:plan' do
899
+ before(:all) do
900
+ @out_err, @ecode = Open3.capture2e(
901
+ 'timeout -k 60 45 bundle exec rake stream_tf:plan',
902
+ chdir: @fixturepath
903
+ )
904
+ @varpath = File.join(@fixturepath, 'stream_build.tfvars.json')
905
+ end
906
+ after(:all) do
907
+ File.delete(@varpath) if File.file?(@varpath)
908
+ end
909
+ it 'does not time out' do
910
+ expect(@ecode.exitstatus).to_not eq(124)
911
+ expect(@ecode.exitstatus).to_not eq(137)
912
+ end
913
+ it 'exits zero' do
914
+ expect(@ecode.exitstatus).to eq(0)
915
+ end
916
+ it 'returns streaming plan output and landscape output' do
917
+ expected = clean_tf_plan_output(
918
+ File.read(File.join(@fixturepath, 'with_landscape_stream.out')),
919
+ latest_tf_ver, @fixturepath
920
+ )
921
+ expect(@out_err.strip).to eq(expected.strip)
922
+ end
923
+ end
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
964
+ end
965
+ end
737
966
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tfwrapper/raketasks'
4
+
5
+ TFWrapper::RakeTasks.install_tasks(
6
+ '.',
7
+ namespace_prefix: 'default'
8
+ )
9
+
10
+ TFWrapper::RakeTasks.install_tasks(
11
+ '.',
12
+ namespace_prefix: 'disabled',
13
+ disable_landscape: true
14
+ )
15
+
16
+ TFWrapper::RakeTasks.install_tasks(
17
+ '.',
18
+ namespace_prefix: 'stream',
19
+ landscape_progress: :stream
20
+ )
21
+
22
+ TFWrapper::RakeTasks.install_tasks(
23
+ '.',
24
+ namespace_prefix: 'dots',
25
+ landscape_progress: :dots
26
+ )
27
+
28
+ TFWrapper::RakeTasks.install_tasks(
29
+ '.',
30
+ namespace_prefix: 'lines',
31
+ landscape_progress: :lines
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}" }
@@ -0,0 +1,32 @@
1
+ terraform {
2
+ required_version = "> 0.9.0"
3
+ backend "consul" {
4
+ address = "127.0.0.1:8500"
5
+ path = "terraform/landscapeTest"
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
+ path_prefix = "landscapeTest/"
26
+
27
+ subkeys = {
28
+ foo = "${jsonencode(local.keys)}"
29
+ }
30
+ }
31
+
32
+ output "foo_variable" { value = "${var.foo}" }
@@ -0,0 +1,43 @@
1
+ {
2
+ "version": 3,
3
+ "terraform_version": "0.11.2",
4
+ "serial": 1,
5
+ "lineage": "2bab32f5-67fc-4210-8a74-af61d21a5420",
6
+ "modules": [
7
+ {
8
+ "path": [
9
+ "root"
10
+ ],
11
+ "outputs": {
12
+ "foo_variable": {
13
+ "sensitive": false,
14
+ "type": "string",
15
+ "value": "bar"
16
+ }
17
+ },
18
+ "resources": {
19
+ "consul_key_prefix.landscapeTest": {
20
+ "type": "consul_key_prefix",
21
+ "depends_on": [
22
+ "local.keys"
23
+ ],
24
+ "primary": {
25
+ "id": "landscapeTest/",
26
+ "attributes": {
27
+ "datacenter": "dc1",
28
+ "id": "landscapeTest/",
29
+ "path_prefix": "landscapeTest/",
30
+ "subkeys.%": "1",
31
+ "subkeys.foo": "{\"bar\":\"bar2val\",\"baz\":\"baz2val\",\"foo\":\"foo2val\"}"
32
+ },
33
+ "meta": {},
34
+ "tainted": false
35
+ },
36
+ "deposed": [],
37
+ "provider": "provider.consul"
38
+ }
39
+ },
40
+ "depends_on": []
41
+ }
42
+ ]
43
+ }
@@ -0,0 +1,45 @@
1
+ Terraform v0.11.2
2
+
3
+ Your version of Terraform is out of date! The latest version
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
+ Running with: Terraform v0.11.2
7
+
8
+ Your version of Terraform is out of date! The latest version
9
+ is %%TF_LATEST_VER%%. You can update by downloading from www.terraform.io/downloads.html
10
+
11
+ Initializing the backend...
12
+ 
13
+ Successfully configured the backend "consul"! Terraform will automatically
14
+ use this backend unless the backend configuration changes.
15
+
16
+ Initializing provider plugins...
17
+ - Checking for available provider plugins on https://releases.hashicorp.com...
18
+ - Downloading plugin for provider "consul" (1.0.0)...
19
+
20
+ Terraform has been successfully initialized!
21
+ 
22
+ You may now begin working with Terraform. Try running "terraform plan" to see
23
+ any changes that are required for your infrastructure. All Terraform commands
24
+ should now work.
25
+
26
+ If you ever set or change modules or backend configuration for Terraform,
27
+ rerun this command to reinitialize your working directory. If you forget, other
28
+ commands will detect it and remind you to do so if necessary.
29
+ terraform_runner command 'terraform init -input=false' finished and exited 0
30
+ Terraform vars written to: %%FIXTUREPATH%%/default_build.tfvars.json
31
+ terraform_runner command: 'terraform plan -var-file %%FIXTUREPATH%%/default_build.tfvars.json' (in %%FIXTUREPATH%%)
32
+ Terraform vars:
33
+ terraform_runner command 'terraform plan -var-file %%FIXTUREPATH%%/default_build.tfvars.json' finished and exited 0
34
+ ~ consul_key_prefix.landscapeTest
35
+  subkeys.foo: {
36
+ - "bar": "barval",
37
+ - "baz": "bazval",
38
+ - "foo": "fooval"
39
+ + "bar": "bar2val",
40
+ + "baz": "baz2val",
41
+ + "foo": "foo2val"
42
+ }
43
+
44
+ Plan: 0 to add, 1 to change, 0 to destroy.
45
+