terraspace 1.1.6 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/.cody/all/bin/build.sh +33 -0
  3. data/.cody/all/buildspec.yml +10 -0
  4. data/.cody/{aws/role.rb → all/iam_role.rb} +0 -0
  5. data/.cody/all/project.rb +6 -0
  6. data/.cody/aws/bin/build.sh +5 -0
  7. data/.cody/aws/iam_role.rb +6 -0
  8. data/.cody/aws/project.rb +6 -2
  9. data/.cody/azurerm/bin/build.sh +5 -0
  10. data/.cody/azurerm/{role.rb → iam_role.rb} +0 -0
  11. data/.cody/azurerm/project.rb +5 -3
  12. data/.cody/google/bin/build.sh +5 -0
  13. data/.cody/google/{role.rb → iam_role.rb} +0 -0
  14. data/.cody/google/project.rb +5 -3
  15. data/.cody/none/bin/build.sh +5 -0
  16. data/.cody/none/{role.rb → iam_role.rb} +0 -0
  17. data/.cody/none/project.rb +6 -2
  18. data/.cody/shared/script/install/terraform.sh +2 -1
  19. data/.cody/shared/script/update/gemfile.sh +2 -0
  20. data/.cody/unit/project.rb +2 -2
  21. data/.gitignore +2 -0
  22. data/.pipedream/pipeline.rb +4 -3
  23. data/CHANGELOG.md +30 -0
  24. data/exe/terraspace +0 -7
  25. data/lib/templates/base/project/config/app.rb +3 -0
  26. data/lib/templates/plugin/ci/%gem_name%.gemspec.tt +32 -0
  27. data/lib/templates/plugin/ci/.gitignore +12 -0
  28. data/lib/templates/plugin/{.rspec → ci/.rspec} +0 -0
  29. data/lib/templates/plugin/ci/.rubocop.yml +13 -0
  30. data/lib/templates/plugin/ci/CHANGELOG.md.tt +5 -0
  31. data/lib/templates/plugin/ci/Gemfile +10 -0
  32. data/lib/templates/plugin/ci/LICENSE.txt +21 -0
  33. data/lib/templates/plugin/ci/README.md.tt +19 -0
  34. data/lib/templates/plugin/ci/Rakefile +12 -0
  35. data/lib/templates/plugin/ci/lib/%gem_name%/autoloader.rb.tt +23 -0
  36. data/lib/templates/plugin/ci/lib/%gem_name%/interface.rb.tt +15 -0
  37. data/lib/templates/plugin/ci/lib/%gem_name%/pr.rb.tt +15 -0
  38. data/lib/templates/plugin/ci/lib/%gem_name%/vars.rb.tt +26 -0
  39. data/lib/templates/plugin/ci/lib/%gem_name%/version.rb.tt +5 -0
  40. data/lib/templates/plugin/ci/lib/%gem_name%.rb.tt +17 -0
  41. data/lib/templates/plugin/ci/spec/%gem_name%_spec.rb.tt +7 -0
  42. data/lib/templates/plugin/ci/spec/spec_helper.rb.tt +15 -0
  43. data/lib/templates/plugin/{.gitignore → core/.gitignore} +0 -0
  44. data/lib/templates/plugin/core/.rspec +3 -0
  45. data/lib/templates/plugin/{CHANGELOG.md → core/CHANGELOG.md} +0 -0
  46. data/lib/templates/plugin/{Gemfile → core/Gemfile} +0 -0
  47. data/lib/templates/plugin/{LICENSE.txt → core/LICENSE.txt} +0 -0
  48. data/lib/templates/plugin/{README.md.tt → core/README.md.tt} +0 -0
  49. data/lib/templates/plugin/{Rakefile → core/Rakefile} +0 -0
  50. data/lib/templates/plugin/{bin → core/bin}/console.tt +0 -0
  51. data/lib/templates/plugin/{bin → core/bin}/setup +0 -0
  52. data/lib/templates/plugin/{lib → core/lib}/templates/hcl/module/main.tf +0 -0
  53. data/lib/templates/plugin/{lib → core/lib}/templates/hcl/module/outputs.tf +0 -0
  54. data/lib/templates/plugin/{lib → core/lib}/templates/hcl/module/variables.tf +0 -0
  55. data/lib/templates/plugin/{lib → core/lib}/templates/hcl/project/config/terraform/backend.tf.tt +0 -0
  56. data/lib/templates/plugin/{lib → core/lib}/templates/hcl/project/config/terraform/provider.tf +0 -0
  57. data/lib/templates/plugin/{lib → core/lib}/templates/hcl/stack/main.tf +0 -0
  58. data/lib/templates/plugin/{lib → core/lib}/templates/hcl/stack/outputs.tf +0 -0
  59. data/lib/templates/plugin/{lib → core/lib}/templates/hcl/stack/variables.tf +0 -0
  60. data/lib/templates/plugin/{lib → core/lib}/templates/ruby/module/main.rb +0 -0
  61. data/lib/templates/plugin/{lib → core/lib}/templates/ruby/module/outputs.rb +0 -0
  62. data/lib/templates/plugin/{lib → core/lib}/templates/ruby/module/variables.rb +0 -0
  63. data/lib/templates/plugin/{lib → core/lib}/templates/ruby/project/config/terraform/backend.rb.tt +0 -0
  64. data/lib/templates/plugin/{lib → core/lib}/templates/ruby/project/config/terraform/provider.rb +0 -0
  65. data/lib/templates/plugin/{lib → core/lib}/templates/ruby/stack/main.rb +0 -0
  66. data/lib/templates/plugin/{lib → core/lib}/templates/ruby/stack/outputs.rb +0 -0
  67. data/lib/templates/plugin/{lib → core/lib}/templates/ruby/stack/variables.rb +0 -0
  68. data/lib/templates/plugin/{lib → core/lib}/templates/test/rspec/module/test/.rspec +0 -0
  69. data/lib/templates/plugin/{lib → core/lib}/templates/test/rspec/module/test/Gemfile +0 -0
  70. data/lib/templates/plugin/{lib → core/lib}/templates/test/rspec/module/test/spec/fixtures/stack/main.tf +0 -0
  71. data/lib/templates/plugin/{lib → core/lib}/templates/test/rspec/module/test/spec/fixtures/stack/outputs.tf +0 -0
  72. data/lib/templates/plugin/{lib → core/lib}/templates/test/rspec/module/test/spec/fixtures/stack/variables.tf +0 -0
  73. data/lib/templates/plugin/{lib → core/lib}/templates/test/rspec/module/test/spec/main_spec.rb +0 -0
  74. data/lib/templates/plugin/{lib → core/lib}/templates/test/rspec/module/test/spec/spec_helper.rb +0 -0
  75. data/lib/templates/plugin/{lib → core/lib}/terraspace_plugin_%name%/autoloader.rb.tt +0 -0
  76. data/lib/templates/plugin/{lib → core/lib}/terraspace_plugin_%name%/clients.rb.tt +0 -0
  77. data/lib/templates/plugin/{lib → core/lib}/terraspace_plugin_%name%/interfaces/backend.rb.tt +0 -0
  78. data/lib/templates/plugin/{lib → core/lib}/terraspace_plugin_%name%/interfaces/config.rb.tt +0 -0
  79. data/lib/templates/plugin/{lib → core/lib}/terraspace_plugin_%name%/interfaces/expander.rb.tt +0 -0
  80. data/lib/templates/plugin/{lib → core/lib}/terraspace_plugin_%name%/interfaces/layer.rb.tt +0 -0
  81. data/lib/templates/plugin/{lib → core/lib}/terraspace_plugin_%name%/version.rb.tt +0 -0
  82. data/lib/templates/plugin/{lib → core/lib}/terraspace_plugin_%name%.rb.tt +0 -0
  83. data/lib/templates/plugin/{spec → core/spec}/spec_helper.rb.tt +0 -0
  84. data/lib/templates/plugin/{spec → core/spec}/terraspace_provider_%name%_spec.rb.tt +0 -0
  85. data/lib/templates/plugin/{terraspace_plugin_%name%.gemspec.tt → core/terraspace_plugin_%name%.gemspec.tt} +0 -0
  86. data/lib/terraspace/all/runner.rb +4 -1
  87. data/lib/terraspace/all/summary.rb +2 -0
  88. data/lib/terraspace/app.rb +23 -4
  89. data/lib/terraspace/builder/children.rb +6 -7
  90. data/lib/terraspace/builder.rb +8 -2
  91. data/lib/terraspace/cli/concerns/plan_path.rb +8 -0
  92. data/lib/terraspace/cli/down.rb +4 -0
  93. data/lib/terraspace/cli/init.rb +1 -1
  94. data/lib/terraspace/cli/new/ci.rb +121 -0
  95. data/lib/terraspace/cli/new/example.rb +1 -1
  96. data/lib/terraspace/cli/new/helpers/plugin_gem.rb +1 -1
  97. data/lib/terraspace/cli/new/plugin/ci.rb +46 -0
  98. data/lib/terraspace/cli/new/plugin/core.rb +26 -0
  99. data/lib/terraspace/cli/new/plugin/helper.rb +4 -1
  100. data/lib/terraspace/cli/new/plugin.rb +8 -15
  101. data/lib/terraspace/cli/new/test.rb +1 -1
  102. data/lib/terraspace/cli/new.rb +17 -13
  103. data/lib/terraspace/cli/plan.rb +13 -0
  104. data/lib/terraspace/cli/setup/check.rb +8 -0
  105. data/lib/terraspace/cli/up.rb +8 -12
  106. data/lib/terraspace/cli.rb +2 -2
  107. data/lib/terraspace/cloud/api/cani.rb +30 -0
  108. data/lib/terraspace/cloud/api/concern/errors.rb +12 -0
  109. data/lib/terraspace/cloud/api/concern/record.rb +18 -0
  110. data/lib/terraspace/cloud/api/concern.rb +38 -0
  111. data/lib/terraspace/cloud/api/http_methods.rb +116 -0
  112. data/lib/terraspace/cloud/api/validate.rb +24 -0
  113. data/lib/terraspace/cloud/api.rb +33 -0
  114. data/lib/terraspace/cloud/base.rb +97 -0
  115. data/lib/terraspace/cloud/ci/generic.rb +25 -0
  116. data/lib/terraspace/cloud/ci/manual.rb +81 -0
  117. data/lib/terraspace/cloud/ci/vcs/base.rb +36 -0
  118. data/lib/terraspace/cloud/ci/vcs/bitbucket.rb +11 -0
  119. data/lib/terraspace/cloud/ci/vcs/github.rb +11 -0
  120. data/lib/terraspace/cloud/ci/vcs/gitlab.rb +11 -0
  121. data/lib/terraspace/cloud/ci/vcs.rb +18 -0
  122. data/lib/terraspace/cloud/ci.rb +56 -0
  123. data/lib/terraspace/cloud/context.rb +14 -0
  124. data/lib/terraspace/cloud/folder/base.rb +17 -0
  125. data/lib/terraspace/cloud/folder/package.rb +33 -0
  126. data/lib/terraspace/cloud/folder/tidy.rb +54 -0
  127. data/lib/terraspace/cloud/folder/uploader.rb +37 -0
  128. data/lib/terraspace/cloud/folder.rb +11 -0
  129. data/lib/terraspace/cloud/plan.rb +47 -0
  130. data/lib/terraspace/cloud/update.rb +37 -0
  131. data/lib/terraspace/command.rb +16 -1
  132. data/lib/terraspace/compiler/dsl/syntax/mod.rb +2 -2
  133. data/lib/terraspace/compiler/dsl/syntax/tfvar.rb +1 -1
  134. data/lib/terraspace/compiler/expander/backend.rb +1 -1
  135. data/lib/terraspace/compiler/expander.rb +1 -1
  136. data/lib/terraspace/compiler/strategy/tfvar/layer.rb +56 -29
  137. data/lib/terraspace/core.rb +36 -3
  138. data/lib/terraspace/ext/core/module.rb +9 -4
  139. data/lib/terraspace/hooks/builder.rb +1 -1
  140. data/lib/terraspace/logger.rb +32 -5
  141. data/lib/terraspace/mod.rb +21 -9
  142. data/lib/terraspace/plugin/expander/interface.rb +19 -11
  143. data/lib/terraspace/plugin.rb +14 -5
  144. data/lib/terraspace/shell.rb +7 -2
  145. data/lib/terraspace/terraform/args/thor.rb +8 -2
  146. data/lib/terraspace/terraform/ihooks/after/apply.rb +8 -0
  147. data/lib/terraspace/terraform/ihooks/after/destroy.rb +8 -0
  148. data/lib/terraspace/terraform/ihooks/after/plan.rb +31 -2
  149. data/lib/terraspace/terraform/ihooks/base.rb +7 -3
  150. data/lib/terraspace/terraform/ihooks/before/apply.rb +8 -0
  151. data/lib/terraspace/terraform/ihooks/before/destroy.rb +8 -0
  152. data/lib/terraspace/terraform/ihooks/before/plan.rb +11 -3
  153. data/lib/terraspace/terraform/runner.rb +19 -5
  154. data/lib/terraspace/version.rb +1 -1
  155. data/lib/terraspace.rb +2 -0
  156. data/terraspace.gemspec +1 -0
  157. metadata +119 -51
  158. data/.pipedream/schedule.rb +0 -3
@@ -58,7 +58,7 @@ module Terraspace::Plugin::Expander
58
58
  #
59
59
  # cache_dir:
60
60
  #
61
- # :CACHE_ROOT/:REGION/:ENV/:BUILD_DIR/
61
+ # :REGION/:ENV/:BUILD_DIR/
62
62
  #
63
63
  # s3 backend key:
64
64
  #
@@ -69,21 +69,24 @@ module Terraspace::Plugin::Expander
69
69
  # :MOD_NAME-:ENV-:REGION-:INSTANCE
70
70
  #
71
71
  def strip(string)
72
- string.sub(/^-+/,'').sub(/-+$/,'') # remove leading and trailing -
73
- .sub(%r{/+$},'') # only remove trailing / or else /home/ec2-user => home/ec2-user
72
+ string.sub(%r{/+$},'') # only remove trailing / or else /home/ec2-user => home/ec2-user
74
73
  .sub(/:\/\//, 'TMP_KEEP_HTTP') # so we can keep ://. IE: https:// or http://
75
74
  .gsub(%r{/+},'/') # remove double slashes are more. IE: // -> / Useful of region is '' in generic expander
76
75
  .sub('TMP_KEEP_HTTP', '://') # restore :// IE: https:// or http://
76
+ .sub(/^-+/,'').sub(/-+$/,'') # remove leading and trailing -
77
77
  end
78
78
 
79
79
  def var_value(unexpanded)
80
- name = unexpanded.sub(':','').downcase
81
- if respond_to?(name)
82
- value = send(name).to_s
80
+ name = unexpanded.sub(':','')
81
+ downcase = name.downcase
82
+ if respond_to?(downcase)
83
+ value = send(downcase).to_s
84
+ elsif !ENV[name].blank?
85
+ return ENV[name]
83
86
  else
84
87
  return unexpanded
85
88
  end
86
- if name == "namespace" && Terraspace.config.layering.enable_names.expansion
89
+ if downcase == "namespace" && Terraspace.config.layering.enable_names.expansion
87
90
  value = friendly_name(value)
88
91
  end
89
92
  value
@@ -93,9 +96,10 @@ module Terraspace::Plugin::Expander
93
96
  @mod.name
94
97
  end
95
98
 
96
- def env
97
- Terraspace.env
98
- end
99
+ def app; Terraspace.app ; end
100
+ def role; Terraspace.role ; end
101
+ def env; Terraspace.env ; end
102
+ def extra; Terraspace.extra ; end
99
103
 
100
104
  def type_instance
101
105
  [type, instance].reject { |s| s.blank? }.join('-')
@@ -110,8 +114,12 @@ module Terraspace::Plugin::Expander
110
114
  Terraspace.cache_root
111
115
  end
112
116
 
117
+ def project
118
+ Terraspace.config.cloud.project
119
+ end
120
+
113
121
  # So default config works:
114
- # config.cache_dir = ":CACHE_ROOT/:REGION/:ENV/:BUILD_DIR"
122
+ # config.cache_dir = ":REGION/:ENV/:BUILD_DIR"
115
123
  # For when folks configure it with the http backend for non-cloud providers
116
124
  # The double slash // will be replace with a single slash in expander/interface.rb
117
125
  def region
@@ -7,7 +7,7 @@ module Terraspace
7
7
  # Example meta:
8
8
  #
9
9
  # {
10
- # "aws => {root: "/path", backend: "s3"}
10
+ # "aws" => {root: "/path", backend: "s3"}
11
11
  # "google" => {root: "/path", backend: "gcs"},
12
12
  # }
13
13
  #
@@ -16,6 +16,10 @@ module Terraspace
16
16
  @@meta
17
17
  end
18
18
 
19
+ def register(plugin, data)
20
+ @@meta[plugin] = data
21
+ end
22
+
19
23
  def config_classes
20
24
  @@meta.map { |plugin, data| data[:config_class] }.compact
21
25
  end
@@ -50,10 +54,6 @@ module Terraspace
50
54
  end
51
55
  end
52
56
 
53
- def register(plugin, data)
54
- @@meta[plugin] = data
55
- end
56
-
57
57
  # Example return:
58
58
  #
59
59
  # TerraspacePluginAws::Interfaces::Backend
@@ -72,6 +72,15 @@ module Terraspace
72
72
  end
73
73
  memoize :find_with
74
74
 
75
+ # Returns simple String: aws
76
+ def autodetect
77
+ plugins = meta.keys
78
+ precedence = %w[aws azurerm google]
79
+ precedence.find do |p|
80
+ plugins.include?(p)
81
+ end
82
+ end
83
+
75
84
  extend self
76
85
  end
77
86
  end
@@ -34,6 +34,11 @@ module Terraspace
34
34
 
35
35
  def popen3(env)
36
36
  Open3.popen3(env, @command, chdir: @mod.cache_dir) do |stdin, stdout, stderr, wait_thread|
37
+ # interesting. simply handling the trap and doing nothing works
38
+ # Think its because ctrl-c is sent to both processes.
39
+ # 1. we do nothing in here in the parent process
40
+ # 2. in the child process the ctrl-c gets sent directly to the terraform command
41
+ Signal.trap("INT") { }
37
42
  handle_streams(stdin, stdout, stderr)
38
43
  status = wait_thread.value.exitstatus
39
44
  exit_status(status)
@@ -112,6 +117,7 @@ module Terraspace
112
117
  end
113
118
  if matched
114
119
  answer = $stdin.gets
120
+ logger.stdin_capture(answer.strip)
115
121
  stdin.write_nonblock(answer)
116
122
  end
117
123
  end
@@ -139,8 +145,7 @@ module Terraspace
139
145
  if @error && @error.known?
140
146
  raise @error.instance
141
147
  elsif exit_on_fail
142
- logger.error "Error running command: #{@command}".color(:red)
143
- exit status
148
+ raise ShellError.new("Error running command: #{@command}")
144
149
  end
145
150
  end
146
151
  end
@@ -83,7 +83,7 @@ module Terraspace::Terraform::Args
83
83
 
84
84
  def output_args
85
85
  args = []
86
- args << "> #{expand.out}" if expand.out
86
+ args << "> #{out_option}" if out_option
87
87
  args
88
88
  end
89
89
 
@@ -91,12 +91,18 @@ module Terraspace::Terraform::Args
91
91
  args = []
92
92
  args << input_option
93
93
  args << "-destroy" if @options[:destroy]
94
- args << "-out #{expand.out}" if expand.out
94
+ args << "-out #{out_option}" if out_option
95
95
  # Note: based on the expand.out will run an internal hook to copy plan
96
96
  # file back up to the root project folder for use. Think this is convenient and expected behavior.
97
97
  args
98
98
  end
99
99
 
100
+ def out_option
101
+ out = expand.out
102
+ FileUtils.mkdir_p(File.dirname("#{@mod.cache_dir}/#{out}"))
103
+ out
104
+ end
105
+
100
106
  def show_args
101
107
  args = []
102
108
  plan = expand.plan
@@ -0,0 +1,8 @@
1
+ module Terraspace::Terraform::Ihooks::After
2
+ class Apply < Terraspace::Terraform::Ihooks::Base
3
+ def run
4
+ return unless Terraspace.cloud?
5
+ Terraspace::Cloud::Update.new(@options.merge(stack: @mod.name, kind: "apply")).run
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Terraspace::Terraform::Ihooks::After
2
+ class Destroy < Terraspace::Terraform::Ihooks::Base
3
+ def run
4
+ return unless Terraspace.cloud?
5
+ Terraspace::Cloud::Update.new(@options.merge(stack: @mod.name, kind: "destroy")).run
6
+ end
7
+ end
8
+ end
@@ -1,8 +1,11 @@
1
1
  module Terraspace::Terraform::Ihooks::After
2
2
  class Plan < Terraspace::Terraform::Ihooks::Base
3
+ include Terraspace::CLI::Concerns::PlanPath
4
+
3
5
  def run
4
- return if !out_option || @options[:copy_to_root] == false
5
- copy_to_root(out_option)
6
+ return if !@mod.out_option || @options[:copy_to_root] == false
7
+ @success = copy_to_root(@mod.out_option)
8
+ cloud_create_plan
6
9
  end
7
10
 
8
11
  def copy_to_root(file)
@@ -10,8 +13,34 @@ module Terraspace::Terraform::Ihooks::After
10
13
  name = file.sub("#{Terraspace.root}/",'')
11
14
  src = "#{@mod.cache_dir}/#{name}"
12
15
  dest = name
16
+ return false unless File.exist?(src) # plan wont exists if the plan errors
13
17
  FileUtils.mkdir_p(File.dirname(dest))
14
18
  FileUtils.cp(src, dest)
19
+ !!dest
20
+ end
21
+
22
+ def cloud_create_plan
23
+ return unless Terraspace.cloud?
24
+
25
+ unless @mod.out_option.include?("_cache2")
26
+ # copy absolute path directly
27
+ src = @mod.out_option.starts_with?('/') ? @mod.out_option : "#{@mod.cache_dir}/#{@mod.out_option}"
28
+ dest = "#{@mod.cache_dir}/#{plan_path}"
29
+ FileUtils.mkdir_p(File.dirname(dest))
30
+ FileUtils.cp(src, dest)
31
+ end
32
+
33
+ # for both:
34
+ # terraspace plan demo --destroy
35
+ # terraspace down demo
36
+ kind = destroy? ? "destroy" : "apply"
37
+ if Terraspace.command?("plan")
38
+ Terraspace::Cloud::Plan.new(@options.merge(stack: @mod.name, kind: kind)).run
39
+ end
40
+ # create update if not plan and plan failed
41
+ if !Terraspace.command?("plan") && !@success
42
+ Terraspace::Cloud::Update.new(@options.merge(stack: @mod.name, kind: kind)).run
43
+ end
15
44
  end
16
45
  end
17
46
  end
@@ -1,13 +1,17 @@
1
1
  module Terraspace::Terraform::Ihooks
2
2
  class Base < Terraspace::CLI::Base
3
+ include Terraspace::Cloud::Api::Concern
4
+
3
5
  def initialize(name, options={})
4
6
  @name = name
7
+ @success = options[:success]
5
8
  super(options)
6
9
  end
7
10
 
8
- def out_option
9
- expand = Terraspace::Terraform::Args::Expand.new(@mod, @options)
10
- expand.out
11
+ def destroy?
12
+ return false if @options.nil?
13
+ result = @options[:args]&.include?('--destroy') || @options[:destroy]
14
+ !!result
11
15
  end
12
16
  end
13
17
  end
@@ -0,0 +1,8 @@
1
+ module Terraspace::Terraform::Ihooks::Before
2
+ class Apply < Terraspace::Terraform::Ihooks::Base
3
+ def run
4
+ return unless Terraspace.cloud?
5
+ Terraspace::Cloud::Update.new(@options.merge(stack: @mod.name, kind: "apply")).cani?
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Terraspace::Terraform::Ihooks::Before
2
+ class Destroy < Terraspace::Terraform::Ihooks::Base
3
+ def run
4
+ return unless Terraspace.cloud?
5
+ Terraspace::Cloud::Update.new(@options.merge(stack: @mod.name, kind: "destroy")).cani?
6
+ end
7
+ end
8
+ end
@@ -1,12 +1,20 @@
1
1
  module Terraspace::Terraform::Ihooks::Before
2
2
  class Plan < Terraspace::Terraform::Ihooks::Base
3
3
  def run
4
- return unless out_option
5
- return if out_option =~ %r{^/} # not need to create parent dir for copy with absolute path
4
+ cani?
6
5
 
7
- name = out_option.sub("#{Terraspace.root}/",'')
6
+ return unless @mod.out_option
7
+ return if @mod.out_option =~ %r{^/} # not need to create parent dir for copy with absolute path
8
+
9
+ name = @mod.out_option.sub("#{Terraspace.root}/",'')
8
10
  dest = "#{@mod.cache_dir}/#{name}"
9
11
  FileUtils.mkdir_p(File.dirname(dest))
10
12
  end
13
+
14
+ def cani?
15
+ return unless Terraspace.cloud?
16
+ kind = destroy? ? "destroy" : "apply"
17
+ Terraspace::Cloud::Plan.new(@options.merge(stack: @mod.name, kind: kind)).cani?
18
+ end
11
19
  end
12
20
  end
@@ -14,6 +14,12 @@ module Terraspace::Terraform
14
14
  time_took do
15
15
  terraform(name, args)
16
16
  end
17
+
18
+ run_internal_hook(:after, name) # always run so plan and apply get saved to tsc
19
+ if @shell_error
20
+ logger.error @shell_error.message.color(:red)
21
+ exit 1 if name == "plan" && Terraspace.command?("up")
22
+ end
17
23
  end
18
24
 
19
25
  # default at end in case of redirection. IE: terraform output > /path
@@ -45,11 +51,17 @@ module Terraspace::Terraform
45
51
 
46
52
  params = args.flatten.join(' ')
47
53
  command = "terraform #{name} #{params}".squish
54
+ @shell_error = nil
48
55
  run_hooks("terraform.rb", name) do
49
56
  Backend.new(@mod).create
50
57
  run_internal_hook(:before, name)
51
- Terraspace::Shell.new(@mod, command, @options.merge(env: custom.env_vars)).run
52
- run_internal_hook(:after, name)
58
+ begin
59
+ Terraspace::Shell.new(@mod, command, @options.merge(env: custom.env_vars)).run
60
+ @success = true
61
+ rescue Terraspace::ShellError => exception
62
+ @shell_error = exception
63
+ @success = false
64
+ end
53
65
  end
54
66
  rescue Terraspace::SharedCacheError, Terraspace::InitRequiredError
55
67
  @retryer ||= Retryer.new(@mod, @options, name, $!)
@@ -63,11 +75,13 @@ module Terraspace::Terraform
63
75
 
64
76
  def run_internal_hook(type, name)
65
77
  begin
66
- klass = "Terraspace::Terraform::Ihooks::#{type.to_s.classify}::#{name.classify}".constantize
67
- rescue NameError
78
+ class_name = "Terraspace::Terraform::Ihooks::#{type.to_s.classify}::#{name.classify}"
79
+ klass = class_name.constantize
80
+ rescue NameError => e
81
+ logger.debug "DEBUG: #{e.class} #{e.message}".color(:red)
68
82
  return
69
83
  end
70
- ihook = klass.new(name, @options)
84
+ ihook = klass.new(name, @options.merge(success: @success))
71
85
  ihook.run
72
86
  end
73
87
 
@@ -1,3 +1,3 @@
1
1
  module Terraspace
2
- VERSION = "1.1.6"
2
+ VERSION = "2.0.1"
3
3
  end
data/lib/terraspace.rb CHANGED
@@ -33,6 +33,8 @@ module Terraspace
33
33
  class BucketNotFoundError < Error; end
34
34
  class InitRequiredError < Error; end
35
35
  class SharedCacheError < Error; end
36
+ class ShellError < Error; end
37
+ class NetworkError < Error; end
36
38
  end
37
39
 
38
40
  Terraspace::Booter.boot
data/terraspace.gemspec CHANGED
@@ -39,6 +39,7 @@ Gem::Specification.new do |spec|
39
39
  spec.add_dependency "thor"
40
40
  spec.add_dependency "tty-tree"
41
41
  spec.add_dependency "zeitwerk"
42
+ spec.add_dependency "zip_folder"
42
43
 
43
44
  # core baseline plugins
44
45
  spec.add_dependency "rspec-terraspace", ">= 0.3.1"