terraspace 0.5.12 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -7
  3. data/README.md +2 -0
  4. data/lib/terraspace/app.rb +34 -13
  5. data/lib/terraspace/app/inits.rb +13 -0
  6. data/lib/terraspace/booter.rb +1 -0
  7. data/lib/terraspace/cli.rb +12 -5
  8. data/lib/terraspace/cli/commander.rb +1 -1
  9. data/lib/terraspace/cli/down.rb +1 -1
  10. data/lib/terraspace/cli/help/{cloud → tfc}/destroy.md +1 -1
  11. data/lib/terraspace/cli/help/{cloud → tfc}/list.md +1 -1
  12. data/lib/terraspace/cli/help/{cloud → tfc}/runs/list.md +3 -3
  13. data/lib/terraspace/cli/help/{cloud → tfc}/runs/prune.md +3 -3
  14. data/lib/terraspace/cli/help/{cloud → tfc}/sync.md +3 -3
  15. data/lib/terraspace/cli/init.rb +21 -8
  16. data/lib/terraspace/cli/state.rb +10 -0
  17. data/lib/terraspace/cli/{cloud.rb → tfc.rb} +3 -3
  18. data/lib/terraspace/cli/{cloud → tfc}/runs.rb +4 -4
  19. data/lib/terraspace/compiler/builder.rb +2 -0
  20. data/lib/terraspace/compiler/strategy/tfvar.rb +16 -4
  21. data/lib/terraspace/compiler/strategy/tfvar/layer.rb +75 -52
  22. data/lib/terraspace/layering.rb +24 -0
  23. data/lib/terraspace/logger.rb +8 -1
  24. data/lib/terraspace/mod.rb +18 -3
  25. data/lib/terraspace/plugin/expander/friendly.rb +10 -0
  26. data/lib/terraspace/plugin/expander/interface.rb +6 -1
  27. data/lib/terraspace/plugin/summary/interface.rb +1 -1
  28. data/lib/terraspace/shell.rb +16 -1
  29. data/lib/terraspace/terraform/api/runs.rb +13 -2
  30. data/lib/terraspace/terraform/api/token.rb +2 -2
  31. data/lib/terraspace/terraform/api/var.rb +1 -1
  32. data/lib/terraspace/terraform/api/vars.rb +1 -1
  33. data/lib/terraspace/terraform/api/vars/base.rb +2 -0
  34. data/lib/terraspace/terraform/api/vars/json.rb +13 -1
  35. data/lib/terraspace/terraform/api/workspace.rb +10 -3
  36. data/lib/terraspace/terraform/args/default.rb +23 -13
  37. data/lib/terraspace/terraform/ihooks/after/plan.rb +17 -0
  38. data/lib/terraspace/terraform/ihooks/base.rb +8 -0
  39. data/lib/terraspace/terraform/ihooks/before/plan.rb +14 -0
  40. data/lib/terraspace/terraform/remote_state/fetcher.rb +1 -1
  41. data/lib/terraspace/terraform/runner.rb +12 -0
  42. data/lib/terraspace/terraform/{cloud → tfc}/runs.rb +1 -1
  43. data/lib/terraspace/terraform/{cloud → tfc}/runs/base.rb +1 -1
  44. data/lib/terraspace/terraform/{cloud → tfc}/runs/item_presenter.rb +1 -1
  45. data/lib/terraspace/terraform/{cloud → tfc}/runs/lister.rb +1 -1
  46. data/lib/terraspace/terraform/{cloud → tfc}/runs/pruner.rb +1 -1
  47. data/lib/terraspace/terraform/{cloud → tfc}/sync.rb +2 -2
  48. data/lib/terraspace/terraform/{cloud → tfc}/syncer.rb +1 -1
  49. data/lib/terraspace/terraform/{cloud → tfc}/workspace.rb +2 -3
  50. data/lib/terraspace/util/pretty.rb +2 -1
  51. data/lib/terraspace/version.rb +1 -1
  52. metadata +24 -17
@@ -1,5 +1,7 @@
1
1
  class Terraspace::Terraform::Api::Vars
2
2
  class Base
3
+ include Terraspace::Util::Logging
4
+
3
5
  def initialize(mod, vars_path)
4
6
  @mod, @vars_path = mod, vars_path
5
7
  end
@@ -4,11 +4,23 @@ class Terraspace::Terraform::Api::Vars
4
4
  context = Terraspace::Compiler::Erb::Context.new(@mod)
5
5
  result = RenderMePretty.result(@vars_path, context: context)
6
6
 
7
- data = JSON.load(result)
7
+ data = json_load(result)
8
8
  items = data.select do |item|
9
9
  item['data']['type'] == 'vars'
10
10
  end
11
11
  items.map { |i| i['data']['attributes'] }
12
12
  end
13
+
14
+ def json_load(result)
15
+ JSON.load(result)
16
+ rescue JSON::ParserError => e
17
+ # TODO: show exact line with error
18
+ logger.info("ERROR in json: #{e.class}: #{e.message}")
19
+ path = "/tmp/terraspace/debug/vars.json"
20
+ logger.info("Result also written to #{path} for inspection")
21
+ FileUtils.mkdir_p(File.dirname(path))
22
+ IO.write(path, result)
23
+ exit 1
24
+ end
13
25
  end
14
26
  end
@@ -24,7 +24,7 @@ class Terraspace::Terraform::Api
24
24
 
25
25
  def working_directory
26
26
  cache_dir = @mod.cache_dir.sub("#{Terraspace.root}/", '')
27
- prefix = Terraspace.config.cloud.working_dir_prefix # prepended to TFC Working Directory
27
+ prefix = Terraspace.config.tfc.working_dir_prefix # prepended to TFC Working Directory
28
28
  prefix ? "#{prefix}/#{cache_dir}" : cache_dir
29
29
  end
30
30
 
@@ -38,7 +38,8 @@ class Terraspace::Terraform::Api
38
38
  #
39
39
  # terraspace up demo --no-init
40
40
  #
41
- unless payload || options[:exit_on_fail] == false
41
+ exit_on_fail = options[:exit_on_fail].nil? ? true : options[:exit_on_fail]
42
+ if exit_on_fail && not_found_error?(payload)
42
43
  logger.error "ERROR: Unable to find the workspace: #{@name}. The workspace may not exist. Or the Terraform token may be invalid. Please double check your Terraform token.".color(:red)
43
44
  exit 1
44
45
  end
@@ -46,6 +47,12 @@ class Terraspace::Terraform::Api
46
47
  end
47
48
  memoize :details
48
49
 
50
+ def not_found_error?(payload)
51
+ return true unless payload
52
+ return false unless payload.key?('errors')
53
+ payload['errors'][0]['status'] == '404'
54
+ end
55
+
49
56
  def destroy
50
57
  # response payload from delete operation is nil
51
58
  http.delete("/organizations/#{@organization}/workspaces/#{@name}")
@@ -74,7 +81,7 @@ class Terraspace::Terraform::Api
74
81
 
75
82
  def attributes
76
83
  attrs = { name: @name }
77
- config = Terraspace.config.cloud.workspace.attrs
84
+ config = Terraspace.config.tfc.workspace.attrs
78
85
  attrs.merge!(config)
79
86
  # Default: run on all changes since app/modules can affect app/stacks
80
87
  if config['vcs-repo'] && config['file-triggers-enabled'].nil?
@@ -23,7 +23,10 @@ module Terraspace::Terraform::Args
23
23
  args = auto_approve_arg
24
24
  var_files = @options[:var_files]
25
25
  if var_files
26
- args << var_files.map { |f| "-var-file #{Dir.pwd}/#{f}" }.join(' ')
26
+ var_files.each do |file|
27
+ copy_to_cache(plan)
28
+ end
29
+ args << var_files.map { |f| "-var-file #{f}" }.join(' ')
27
30
  end
28
31
 
29
32
  args << input_option
@@ -31,15 +34,8 @@ module Terraspace::Terraform::Args
31
34
  # must be at the end
32
35
  plan = @options[:plan]
33
36
  if plan
34
- if plan.starts_with?('/')
35
- src = plan
36
- dest = src
37
- else
38
- src = "#{Dir.pwd}/#{plan}"
39
- dest = "#{@mod.cache_dir}/#{File.basename(src)}"
40
- end
41
- FileUtils.cp(src, dest) unless same_file?(src, dest)
42
- args << " #{dest}"
37
+ copy_to_cache(plan)
38
+ args << " #{plan}"
43
39
  end
44
40
  args
45
41
  end
@@ -79,19 +75,24 @@ module Terraspace::Terraform::Args
79
75
  args << input_option
80
76
  args << "-destroy" if @options[:destroy]
81
77
  args << "-out #{expanded_out}" if @options[:out]
78
+ # Note: based on the @options[:out] will run an internal hook to copy plan
79
+ # file back up to the root project folder for use. Think this is convenient and expected behavior.
82
80
  args
83
81
  end
84
82
 
85
83
  def show_args
86
84
  args = []
87
85
  args << " -json" if @options[:json]
88
- args << " #{@options[:plan]}" if @options[:plan] # terraform show /path/to/plan
86
+ plan = @options[:plan]
87
+ if plan
88
+ copy_to_cache(@options[:plan])
89
+ args << " #{@options[:plan]}" # terraform show /path/to/plan
90
+ end
89
91
  args
90
92
  end
91
93
 
92
94
  def expanded_out
93
- out = @options[:out]
94
- out.starts_with?('/') ? out : "#{Dir.pwd}/#{out}"
95
+ @options[:out]
95
96
  end
96
97
 
97
98
  def destroy_args
@@ -123,5 +124,14 @@ module Terraspace::Terraform::Args
123
124
  def same_file?(src, dest)
124
125
  src == dest
125
126
  end
127
+
128
+ def copy_to_cache(file)
129
+ return if file =~ %r{^/} # not need to copy absolute path
130
+ name = file.sub("#{Terraspace.root}/",'')
131
+ src = name
132
+ dest = "#{@mod.cache_dir}/#{name}"
133
+ FileUtils.mkdir_p(File.dirname(dest))
134
+ FileUtils.cp(src, dest) unless same_file?(src, dest)
135
+ end
126
136
  end
127
137
  end
@@ -0,0 +1,17 @@
1
+ module Terraspace::Terraform::Ihooks::After
2
+ class Plan < Terraspace::Terraform::Ihooks::Base
3
+ def run
4
+ return if !@options[:out] || @options[:copy_to_root] == false
5
+ copy_to_root(@options[:out])
6
+ end
7
+
8
+ def copy_to_root(file)
9
+ return if file =~ %r{^/} # not need to copy absolute path
10
+ name = file.sub("#{Terraspace.root}/",'')
11
+ src = "#{@mod.cache_dir}/#{name}"
12
+ dest = name
13
+ FileUtils.mkdir_p(File.dirname(dest))
14
+ FileUtils.cp(src, dest)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ module Terraspace::Terraform::Ihooks
2
+ class Base < Terraspace::CLI::Base
3
+ def initialize(name, options={})
4
+ @name = name
5
+ super(options)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ module Terraspace::Terraform::Ihooks::Before
2
+ class Plan < Terraspace::Terraform::Ihooks::Base
3
+ def run
4
+ out = @options[:out]
5
+ return unless out
6
+ return if out =~ %r{^/} # not need to create parent dir for copy with absolute path
7
+
8
+ out = @options[:out]
9
+ name = out.sub("#{Terraspace.root}/",'')
10
+ dest = "#{@mod.cache_dir}/#{name}"
11
+ FileUtils.mkdir_p(File.dirname(dest))
12
+ end
13
+ end
14
+ end
@@ -84,7 +84,7 @@ module Terraspace::Terraform::RemoteState
84
84
  end
85
85
 
86
86
  def init
87
- Terraspace::CLI::Init.new(mod: @child.name, calling_command: "apply", quiet: true, suppress_error_color: true).init
87
+ Terraspace::CLI::Init.new(mod: @child.name, quiet: true, suppress_error_color: true).init
88
88
  true
89
89
  rescue Terraspace::BucketNotFoundError # from Terraspace::Shell
90
90
  bucket_not_found_error
@@ -22,7 +22,9 @@ module Terraspace::Terraform
22
22
  params = args.flatten.join(' ')
23
23
  command = "terraform #{name} #{params}".squish
24
24
  run_hooks("terraform.rb", name) do
25
+ run_internal_hook(:before, name)
25
26
  Terraspace::Shell.new(@mod, command, @options.merge(env: custom.env_vars)).run
27
+ run_internal_hook(:after, name)
26
28
  end
27
29
  rescue Terraspace::SharedCacheError, Terraspace::InitRequiredError
28
30
  @retryer ||= Retryer.new(@mod, @options, name, $!)
@@ -34,6 +36,16 @@ module Terraspace::Terraform
34
36
  end
35
37
  end
36
38
 
39
+ def run_internal_hook(type, name)
40
+ begin
41
+ klass = "Terraspace::Terraform::Ihooks::#{type.to_s.classify}::#{name.classify}".constantize
42
+ rescue NameError
43
+ return
44
+ end
45
+ ihook = klass.new(name, @options)
46
+ ihook.run
47
+ end
48
+
37
49
  @@current_dir_message_shown = false
38
50
  def current_dir_message
39
51
  return if @@current_dir_message_shown
@@ -1,4 +1,4 @@
1
- module Terraspace::Terraform::Cloud
1
+ module Terraspace::Terraform::Tfc
2
2
  class Runs < Terraspace::CLI::Base
3
3
  def list
4
4
  lister = Lister.new(@mod, @options)
@@ -1,4 +1,4 @@
1
- class Terraspace::Terraform::Cloud::Runs
1
+ class Terraspace::Terraform::Tfc::Runs
2
2
  class Base
3
3
  extend Memoist
4
4
  include Terraspace::Util::Logging
@@ -1,4 +1,4 @@
1
- class Terraspace::Terraform::Cloud::Runs
1
+ class Terraspace::Terraform::Tfc::Runs
2
2
  class ItemPresenter
3
3
  attr_reader :id
4
4
  def initialize(raw)
@@ -1,4 +1,4 @@
1
- class Terraspace::Terraform::Cloud::Runs
1
+ class Terraspace::Terraform::Tfc::Runs
2
2
  class Lister < Base
3
3
  def run
4
4
  build_project
@@ -1,4 +1,4 @@
1
- class Terraspace::Terraform::Cloud::Runs
1
+ class Terraspace::Terraform::Tfc::Runs
2
2
  class Pruner < Base
3
3
  include Terraspace::Terraform::Api::Client
4
4
 
@@ -1,4 +1,4 @@
1
- module Terraspace::Terraform::Cloud
1
+ module Terraspace::Terraform::Tfc
2
2
  class Sync < Terraspace::CLI::Base
3
3
  extend Memoist
4
4
  include Terraspace::Terraform::Api::Client
@@ -16,7 +16,7 @@ module Terraspace::Terraform::Cloud
16
16
  # So we check and create the workspace if necessary.
17
17
  def run
18
18
  # Note: workspace still gets created by `terraform init` However, variables wont be sync if returns early
19
- return unless Terraspace.config.cloud.auto_sync || @options[:override_auto_sync]
19
+ return unless Terraspace.config.tfc.auto_sync || @options[:override_auto_sync]
20
20
  return unless workspaces_backend?
21
21
  logger.info "Syncing to Terraform Cloud: #{@mod.name} => #{workspace_name}"
22
22
  @api = Terraspace::Terraform::Api.new(@mod, remote)
@@ -1,4 +1,4 @@
1
- module Terraspace::Terraform::Cloud
1
+ module Terraspace::Terraform::Tfc
2
2
  class Syncer < Terraspace::CLI::Base
3
3
  extend Memoist
4
4
  include Terraspace::Compiler::DirsConcern
@@ -1,4 +1,4 @@
1
- module Terraspace::Terraform::Cloud
1
+ module Terraspace::Terraform::Tfc
2
2
  class Workspace < Terraspace::CLI::Base
3
3
  extend Memoist
4
4
  include Terraspace::Util::Logging
@@ -21,7 +21,7 @@ module Terraspace::Terraform::Cloud
21
21
  end
22
22
 
23
23
  def init
24
- Terraspace::CLI::Init.new(@options.merge(calling_command: "cloud-setup")).run
24
+ Terraspace::CLI::Init.new(@options).run
25
25
  end
26
26
 
27
27
  def create
@@ -72,4 +72,3 @@ module Terraspace::Terraform::Cloud
72
72
  end
73
73
  end
74
74
  end
75
-
@@ -12,7 +12,8 @@ module Terraspace::Util
12
12
  end
13
13
 
14
14
  def pretty_path(path)
15
- ENV['TS_TEST'] ? path : path.sub("#{Terraspace.root}/",'')
15
+ return path if ENV['TS_TEST']
16
+ path.sub("#{Terraspace.root}/",'').sub(ENV['HOME'], '~')
16
17
  end
17
18
  end
18
19
  end
@@ -1,3 +1,3 @@
1
1
  module Terraspace
2
- VERSION = "0.5.12"
2
+ VERSION = "0.6.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terraspace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.12
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-27 00:00:00.000000000 Z
11
+ date: 2021-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -462,6 +462,7 @@ files:
462
462
  - lib/terraspace/all/summary.rb
463
463
  - lib/terraspace/app.rb
464
464
  - lib/terraspace/app/hooks.rb
465
+ - lib/terraspace/app/inits.rb
465
466
  - lib/terraspace/autoloader.rb
466
467
  - lib/terraspace/booter.rb
467
468
  - lib/terraspace/builder.rb
@@ -478,8 +479,6 @@ files:
478
479
  - lib/terraspace/cli/clean/base.rb
479
480
  - lib/terraspace/cli/clean/cache.rb
480
481
  - lib/terraspace/cli/clean/logs.rb
481
- - lib/terraspace/cli/cloud.rb
482
- - lib/terraspace/cli/cloud/runs.rb
483
482
  - lib/terraspace/cli/commander.rb
484
483
  - lib/terraspace/cli/completer.rb
485
484
  - lib/terraspace/cli/completer/script.rb
@@ -502,11 +501,6 @@ files:
502
501
  - lib/terraspace/cli/help/clean/all.md
503
502
  - lib/terraspace/cli/help/clean/cache.md
504
503
  - lib/terraspace/cli/help/clean/logs.md
505
- - lib/terraspace/cli/help/cloud/destroy.md
506
- - lib/terraspace/cli/help/cloud/list.md
507
- - lib/terraspace/cli/help/cloud/runs/list.md
508
- - lib/terraspace/cli/help/cloud/runs/prune.md
509
- - lib/terraspace/cli/help/cloud/sync.md
510
504
  - lib/terraspace/cli/help/completion.md
511
505
  - lib/terraspace/cli/help/completion_script.md
512
506
  - lib/terraspace/cli/help/console.md
@@ -536,6 +530,11 @@ files:
536
530
  - lib/terraspace/cli/help/show.md
537
531
  - lib/terraspace/cli/help/summary.md
538
532
  - lib/terraspace/cli/help/test.md
533
+ - lib/terraspace/cli/help/tfc/destroy.md
534
+ - lib/terraspace/cli/help/tfc/list.md
535
+ - lib/terraspace/cli/help/tfc/runs/list.md
536
+ - lib/terraspace/cli/help/tfc/runs/prune.md
537
+ - lib/terraspace/cli/help/tfc/sync.md
539
538
  - lib/terraspace/cli/help/up.md
540
539
  - lib/terraspace/cli/help/validate.md
541
540
  - lib/terraspace/cli/info.rb
@@ -562,8 +561,11 @@ files:
562
561
  - lib/terraspace/cli/new/stack.rb
563
562
  - lib/terraspace/cli/new/test.rb
564
563
  - lib/terraspace/cli/seed.rb
564
+ - lib/terraspace/cli/state.rb
565
565
  - lib/terraspace/cli/summary.rb
566
566
  - lib/terraspace/cli/test.rb
567
+ - lib/terraspace/cli/tfc.rb
568
+ - lib/terraspace/cli/tfc/runs.rb
567
569
  - lib/terraspace/cli/tfc_concern.rb
568
570
  - lib/terraspace/cli/up.rb
569
571
  - lib/terraspace/command.rb
@@ -626,6 +628,7 @@ files:
626
628
  - lib/terraspace/hooks/concern.rb
627
629
  - lib/terraspace/hooks/dsl.rb
628
630
  - lib/terraspace/hooks/runner.rb
631
+ - lib/terraspace/layering.rb
629
632
  - lib/terraspace/logger.rb
630
633
  - lib/terraspace/logger/formatter.rb
631
634
  - lib/terraspace/mod.rb
@@ -634,6 +637,7 @@ files:
634
637
  - lib/terraspace/plugin/backend/interface.rb
635
638
  - lib/terraspace/plugin/config/interface.rb
636
639
  - lib/terraspace/plugin/decorator/interface.rb
640
+ - lib/terraspace/plugin/expander/friendly.rb
637
641
  - lib/terraspace/plugin/expander/generic.rb
638
642
  - lib/terraspace/plugin/expander/interface.rb
639
643
  - lib/terraspace/plugin/finder.rb
@@ -665,14 +669,9 @@ files:
665
669
  - lib/terraspace/terraform/args/default.rb
666
670
  - lib/terraspace/terraform/args/dsl.rb
667
671
  - lib/terraspace/terraform/args/shorthands.rb
668
- - lib/terraspace/terraform/cloud/runs.rb
669
- - lib/terraspace/terraform/cloud/runs/base.rb
670
- - lib/terraspace/terraform/cloud/runs/item_presenter.rb
671
- - lib/terraspace/terraform/cloud/runs/lister.rb
672
- - lib/terraspace/terraform/cloud/runs/pruner.rb
673
- - lib/terraspace/terraform/cloud/sync.rb
674
- - lib/terraspace/terraform/cloud/syncer.rb
675
- - lib/terraspace/terraform/cloud/workspace.rb
672
+ - lib/terraspace/terraform/ihooks/after/plan.rb
673
+ - lib/terraspace/terraform/ihooks/base.rb
674
+ - lib/terraspace/terraform/ihooks/before/plan.rb
676
675
  - lib/terraspace/terraform/remote_state/fetcher.rb
677
676
  - lib/terraspace/terraform/remote_state/marker/output.rb
678
677
  - lib/terraspace/terraform/remote_state/marker/pretty_tracer.rb
@@ -680,6 +679,14 @@ files:
680
679
  - lib/terraspace/terraform/remote_state/unresolved.rb
681
680
  - lib/terraspace/terraform/runner.rb
682
681
  - lib/terraspace/terraform/runner/retryer.rb
682
+ - lib/terraspace/terraform/tfc/runs.rb
683
+ - lib/terraspace/terraform/tfc/runs/base.rb
684
+ - lib/terraspace/terraform/tfc/runs/item_presenter.rb
685
+ - lib/terraspace/terraform/tfc/runs/lister.rb
686
+ - lib/terraspace/terraform/tfc/runs/pruner.rb
687
+ - lib/terraspace/terraform/tfc/sync.rb
688
+ - lib/terraspace/terraform/tfc/syncer.rb
689
+ - lib/terraspace/terraform/tfc/workspace.rb
683
690
  - lib/terraspace/tester.rb
684
691
  - lib/terraspace/tester/finder.rb
685
692
  - lib/terraspace/tester/meta.rb