terraspace 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -1
  3. data/README.md +14 -1
  4. data/lib/templates/base/git_hook/hook.sh +1 -1
  5. data/lib/templates/base/project/.gitignore +1 -0
  6. data/lib/templates/base/project/README.md +17 -0
  7. data/lib/terraspace.rb +4 -0
  8. data/lib/terraspace/all/base.rb +8 -0
  9. data/lib/terraspace/all/grapher.rb +129 -0
  10. data/lib/terraspace/all/preview.rb +43 -0
  11. data/lib/terraspace/all/runner.rb +169 -0
  12. data/lib/terraspace/all/summary.rb +99 -0
  13. data/lib/terraspace/app.rb +30 -9
  14. data/lib/terraspace/booter.rb +9 -0
  15. data/lib/terraspace/builder.rb +51 -23
  16. data/lib/terraspace/cli.rb +39 -12
  17. data/lib/terraspace/cli/all.rb +63 -0
  18. data/lib/terraspace/cli/build/placeholder.rb +2 -5
  19. data/lib/terraspace/cli/bundle.rb +1 -1
  20. data/lib/terraspace/cli/check_setup.rb +5 -0
  21. data/lib/terraspace/cli/cloud.rb +18 -2
  22. data/lib/terraspace/cli/cloud/runs.rb +24 -0
  23. data/lib/terraspace/cli/commander.rb +6 -3
  24. data/lib/terraspace/cli/down.rb +20 -0
  25. data/lib/terraspace/cli/help/cloud/runs/list.md +36 -0
  26. data/lib/terraspace/cli/help/cloud/runs/prune.md +25 -0
  27. data/lib/terraspace/cli/help/cloud/sync.md +19 -0
  28. data/lib/terraspace/cli/help/log.md +42 -0
  29. data/lib/terraspace/cli/init.rb +35 -7
  30. data/lib/terraspace/cli/list.rb +14 -1
  31. data/lib/terraspace/cli/log.rb +112 -0
  32. data/lib/terraspace/cli/log/concern.rb +24 -0
  33. data/lib/terraspace/cli/logs.rb +15 -0
  34. data/lib/terraspace/cli/logs/tasks.rb +32 -0
  35. data/lib/terraspace/cli/new/git_hook.rb +1 -1
  36. data/lib/terraspace/cli/tfc_concern.rb +14 -0
  37. data/lib/terraspace/cli/up.rb +32 -0
  38. data/lib/terraspace/compiler/builder.rb +3 -3
  39. data/lib/terraspace/compiler/cleaner.rb +1 -1
  40. data/lib/terraspace/compiler/cleaner/backend_change.rb +21 -7
  41. data/lib/terraspace/compiler/dirs_concern.rb +47 -0
  42. data/lib/terraspace/compiler/dsl/syntax/helpers/common.rb +26 -1
  43. data/lib/terraspace/core.rb +11 -2
  44. data/lib/terraspace/dependency/graph.rb +139 -0
  45. data/lib/terraspace/dependency/node.rb +38 -0
  46. data/lib/terraspace/dependency/registry.rb +11 -0
  47. data/lib/terraspace/logger.rb +6 -18
  48. data/lib/terraspace/logger/formatter.rb +13 -0
  49. data/lib/terraspace/mod.rb +7 -1
  50. data/lib/terraspace/seeder/where.rb +6 -2
  51. data/lib/terraspace/shell.rb +79 -0
  52. data/lib/terraspace/terraform/api.rb +7 -45
  53. data/lib/terraspace/terraform/api/base.rb +7 -0
  54. data/lib/terraspace/terraform/api/client.rb +23 -3
  55. data/lib/terraspace/terraform/api/http.rb +14 -34
  56. data/lib/terraspace/terraform/api/http/concern.rb +10 -0
  57. data/lib/terraspace/terraform/api/runs.rb +28 -0
  58. data/lib/terraspace/terraform/api/token.rb +65 -0
  59. data/lib/terraspace/terraform/api/var.rb +20 -6
  60. data/lib/terraspace/terraform/api/vars.rb +2 -1
  61. data/lib/terraspace/terraform/api/workspace.rb +98 -0
  62. data/lib/terraspace/terraform/args/default.rb +48 -21
  63. data/lib/terraspace/terraform/cloud/runs.rb +13 -0
  64. data/lib/terraspace/terraform/cloud/runs/base.rb +33 -0
  65. data/lib/terraspace/terraform/cloud/runs/item_presenter.rb +37 -0
  66. data/lib/terraspace/terraform/cloud/runs/lister.rb +22 -0
  67. data/lib/terraspace/terraform/cloud/runs/pruner.rb +109 -0
  68. data/lib/terraspace/terraform/cloud/sync.rb +41 -0
  69. data/lib/terraspace/terraform/cloud/syncer.rb +52 -0
  70. data/lib/terraspace/terraform/cloud/workspace.rb +10 -21
  71. data/lib/terraspace/terraform/hooks/builder.rb +1 -1
  72. data/lib/terraspace/terraform/remote_state/fetcher.rb +122 -0
  73. data/lib/terraspace/terraform/remote_state/marker/output.rb +39 -0
  74. data/lib/terraspace/terraform/remote_state/marker/pretty_tracer.rb +37 -0
  75. data/lib/terraspace/terraform/remote_state/output_proxy.rb +29 -0
  76. data/lib/terraspace/terraform/runner.rb +24 -14
  77. data/lib/terraspace/util.rb +1 -5
  78. data/lib/terraspace/util/pretty.rb +18 -0
  79. data/lib/terraspace/version.rb +1 -1
  80. data/spec/fixtures/fetcher/c1.json +37 -0
  81. data/spec/fixtures/parser/cache_dirs/all/01-test.auto.tfvars +5 -0
  82. data/spec/fixtures/parser/cache_dirs/depends_on/01-test.auto.tfvars +2 -0
  83. data/spec/fixtures/parser/cache_dirs/output/01-test.auto.tfvars +2 -0
  84. data/spec/fixtures/summary/down.log +12 -0
  85. data/spec/fixtures/summary/output.log +5 -0
  86. data/spec/fixtures/summary/plan/error.log +20 -0
  87. data/spec/fixtures/summary/plan/success.log +17 -0
  88. data/spec/fixtures/summary/show.log +22 -0
  89. data/spec/fixtures/summary/up/error.log +13 -0
  90. data/spec/fixtures/summary/up/success.log +63 -0
  91. data/spec/fixtures/summary/validate/error.log +13 -0
  92. data/spec/fixtures/summary/validate/success.log +5 -0
  93. data/spec/terraspace/all/grapher_spec.rb +38 -0
  94. data/spec/terraspace/all/runner_spec.rb +48 -0
  95. data/spec/terraspace/all/summary_spec.rb +93 -0
  96. data/spec/terraspace/dependency/graph_spec.rb +162 -0
  97. data/spec/terraspace/seeder_spec.rb +0 -1
  98. data/spec/terraspace/terraform/remote_state/fetcher_spec.rb +52 -0
  99. data/terraspace.gemspec +5 -1
  100. metadata +137 -5
  101. data/lib/terraspace/terraform/cloud.rb +0 -25
  102. data/lib/terraspace/util/sh.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7bd8fdab16c165766aaf3ab1d6cb3fdf2011d8ed02ac7bf713bc7dd51de862ea
4
- data.tar.gz: b6364f9921e3330096b6a3276d6e35cf5ad26a27d70f911afac3dc33e2c4287e
3
+ metadata.gz: b6c5d0afc0bdc18ff6f10c79369d60f8a722ecede426ce37880993e5f9676860
4
+ data.tar.gz: 3abc9b03ef0a7766491116747fa0d0b6a0fe7d41fc67098e8d2d08a8c30e4a0f
5
5
  SHA512:
6
- metadata.gz: 2066770e8e6d31dc93986d3684f065f1b9f087e1b266cd01b999ad9f4d878bd497fce0efe656586d7b3fafa94ce859d7c8c4112be034d63a30393e46c0307d9c
7
- data.tar.gz: b65e842ae15a0a08f6fa64c440155ac9961f8ed52a6f1ecb4d020806943b2860cb7c7073cd344a2e33ebe5984f2c05abdea2f75e2cb2da4f9323d799920f6ee8
6
+ metadata.gz: 680b8fed8c8487b85b27007750106944aad12606aa5a3bcffef40c249312b03a957867e8bf4c42a6ba4f332b498db031d48ae63875623c436b0fd89ab73fe8f7
7
+ data.tar.gz: 7fc9f978acf6d5759a892530e57ea42839f10201a5cbf14d5db46256d382a1b1b2c86744f4b47f930ee20a2944dff30c58d7d9c406d810e93fc9f73535f1bc9c
@@ -3,9 +3,27 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [0.3.0]
7
+ * All commands: Dependency graph calculated and deployed in proper order
8
+ * All commands: `terraspace all up`, `terraspace all build`, `terraspace all down`, etc. `terraspace all -h`
9
+ * Terraspace log: view and tail log files
10
+ * Terraspace logs management commands: `terraspace logs truncate` and `terraspace logs remove`
11
+ * TFC/TFE: Improve support. `config.cloud.vars`, `config.cloud.workspace.attrs`
12
+ * TFC commands: terraspace cloud runs list, terraspace cloud runs prune
13
+ * TFC VCS also sync as part of deploy. Also separate `terraspace cloud sync` command
14
+ * Logger improvements: configurable formatter, log to stderr by default
15
+ * Rename: `cloud.relative_root` to `cloud.working_dir_prefix`
16
+ * Run a plan to capture the diff as part of `-y` option. IE: `terraspace up demo -y`
17
+ * Run plan -destroy as part of down -y
18
+ * Rename update cli to up. Only support the shorthand.
19
+ * Config options: config.all.concurrency, config.all.exit_on_fail, etc
20
+ * TFC: cloud.auto_sync option
21
+ * Improve terraform version check
22
+ * Terraform init: auto mode will retry initializing up to 3 times
23
+ * Terraspace seed: fix instance option
24
+
6
25
  ## [0.2.4]
7
26
  - fix version check for some versions of terraform
8
-
9
27
  ## [0.2.3]
10
28
  * #37 config.clean_cache option
11
29
 
data/README.md CHANGED
@@ -71,13 +71,26 @@ Destroy infrastructure:
71
71
  Destroy complete! Resources: 2 destroyed.
72
72
  $
73
73
 
74
+ ## Deploy Multiple Stacks
75
+
76
+ To deploy all the infrastructure stacks:
77
+
78
+ terraspace all up
79
+
80
+ To choose multiple stacks to deploy
81
+
82
+ terraspace all up instance vpc
83
+
84
+ When you use the all command, the dependency graph is calculated and the stacks are deployed in the right order. To learn more: [Deploy Multiple Stacks](https://terraspace.cloud/docs/dependencies/deploy-all/).
85
+
74
86
  ## Features
75
87
 
76
88
  * [Config Structure](https://terraspace.cloud/docs/config/): A common config structure that gets materializes with the deployed module. Configs can be dynamically controlled to keep your code DRY. You can override the settings if needed, like for using existing backends. See: [Existing Backends](https://terraspace.cloud/docs/state/existing/).
77
89
  * [Generators](https://terraspace.cloud/docs/generators/): Built-in generators to quickly create the starter module. Focus on code instead of boilerplate structure.
78
90
  * [Tfvars](https://terraspace.cloud/docs/tfvars/) & [Layering](https://terraspace.cloud/docs/tfvars/layering/): Use the same code with different tfvars to create multiple environments. Terraspace conventionally loads tfvars from the `tfvars` folder. Rich layering support allows you to build different environments like dev and prod with the same code. Examples are in [Full Layering](https://terraspace.cloud/docs/tfvars/full-layering/).
79
- * [Testing](https://terraspace.cloud/docs/testing/): A testing framework that allows you to create test harnesses, deploy real-resources, and have higher confidence that your code works.
91
+ * [Deploy Multiple Stacks](https://terraspace.cloud/docs/dependencies/deploy-all/): The ability to deploy multiple stacks with a single command. Terraspace calculates the [dependency graph](https://terraspace.cloud/docs/dependencies/) and deploys stacks in the right order. You can also target specific stacks and deploy [subgraphs](https://terraspace.cloud/docs/dependencies/subgraphs/).
80
92
  * [Configurable CLI](https://terraspace.cloud/docs/cli/): Configurable [CLI Hooks](https://terraspace.cloud/docs/cli/hooks/) and [CLI Args](https://terraspace.cloud/docs/cli/args/) allow you to adjust the underlying terraform command.
93
+ * [Testing](https://terraspace.cloud/docs/testing/): A testing framework that allows you to create test harnesses, deploy real-resources, and have higher confidence that your code works.
81
94
  * [Terraform Cloud and Terraform Enterprise Support](https://terraspace.cloud/docs/cloud/): TFC and TFE are both supported. Terraspace adds additional conveniences to make working with Terraform Cloud Workspaces easier.
82
95
 
83
96
  For more info: [terraspace.cloud](https://terraspace.cloud)
@@ -1,5 +1,5 @@
1
1
  #!/bin/bash -ex
2
- echo "Running: terraspace build placeholder"
2
+ echo "Running: terraspace build"
3
3
  <%= terraspace_build_commands %>
4
4
  git add .terraspace-cache
5
5
  git commit -m 'update .terraspace-cache' || true
@@ -23,6 +23,7 @@ terraform.tfvars
23
23
  /Gemfile.lock
24
24
  /InstalledFiles
25
25
  /lib/bundler/man
26
+ /log
26
27
  /output
27
28
  /pkg
28
29
  /rdoc
@@ -0,0 +1,17 @@
1
+ # Terraspace Project
2
+
3
+ This is a Terraspace project. It contains code to provision Cloud infrastructure built with [Terraform](https://www.terraform.io/) and the [Terraspace Framework](https://terraspace.cloud/).
4
+
5
+ ## Deploy
6
+
7
+ To deploy all the infrastructure stacks:
8
+
9
+ terraspace all up
10
+
11
+ To deploy individual stacks:
12
+
13
+ terraspace up demo # where demo is app/stacks/demo
14
+
15
+ ## Terrafile
16
+
17
+ To add more modules for use, you can add them to the [Terrafile](https://terraspace.cloud/docs/terrafile/).
@@ -1,16 +1,19 @@
1
1
  $stdout.sync = true unless ENV["TS_STDOUT_SYNC"] == "0"
2
2
 
3
3
  $:.unshift(File.expand_path("../", __FILE__))
4
+ require "active_support/concern"
4
5
  require "active_support/core_ext/class"
5
6
  require "active_support/core_ext/hash"
6
7
  require "active_support/core_ext/string"
7
8
  require "active_support/ordered_options"
9
+ require "deep_merge/rails_compat"
8
10
  require "dsl_evaluator"
9
11
  require "fileutils"
10
12
  require "json"
11
13
  require "memoist"
12
14
  require "rainbow/ext/string"
13
15
  require "render_me_pretty"
16
+ require "set"
14
17
  require "terraspace/ext"
15
18
  require "terraspace/version"
16
19
 
@@ -22,6 +25,7 @@ DslEvaluator.backtrace_reject = "lib/terraspace"
22
25
  module Terraspace
23
26
  extend Core # for Terraspace.root
24
27
  class Error < StandardError; end
28
+ class InitRequiredError < Error; end
25
29
  end
26
30
 
27
31
  Terraspace::Booter.boot
@@ -0,0 +1,8 @@
1
+ module Terraspace::All
2
+ class Base
3
+ def initialize(options={})
4
+ @options = options
5
+ Terraspace.check_project! unless ENV['TS_TEST']
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,129 @@
1
+ require "graph"
2
+ require "tty-tree"
3
+
4
+ module Terraspace::All
5
+ class Grapher < Base
6
+ include Terraspace::Util::Logging
7
+
8
+ def run
9
+ check_graphviz!
10
+ logger.info "Building graph..."
11
+ builder = Terraspace::Builder.new(@options.merge(mod: "placeholder", quiet: true, draw_full_graph: draw_full_graph))
12
+ builder.run
13
+ graph = builder.graph
14
+ if @options[:format] == "text"
15
+ text(graph.top_nodes)
16
+ else
17
+ draw(graph.nodes)
18
+ end
19
+ end
20
+
21
+ def text(nodes)
22
+ Rainbow.enabled = false unless @options[:full]
23
+ data = build_tree_data(nodes)
24
+ Rainbow.enabled = true unless @options[:full]
25
+ tree = TTY::Tree.new(data)
26
+ logger.info tree.render
27
+ end
28
+
29
+ def build_tree_data(nodes)
30
+ if nodes.size == 1
31
+ tree_data(nodes.first)
32
+ else
33
+ root = Terraspace::Dependency::Node.new('.')
34
+ nodes.each { |node| node.parent!(root) }
35
+ tree_data(root)
36
+ end
37
+ end
38
+
39
+ def tree_data(parent, data={})
40
+ parent_name = text_name(parent)
41
+ data[parent_name] ||= []
42
+ parent.children.each do |child|
43
+ child_name = text_name(child)
44
+ if child.children.empty? # leaf node
45
+ data[parent_name] << child_name
46
+ else
47
+ next_data = { child_name => [] }
48
+ data[parent_name] << tree_data(child, next_data)
49
+ end
50
+ end
51
+ data
52
+ end
53
+
54
+ def text_name(node)
55
+ node.highlighted? ? node.name.bright : node.name
56
+ end
57
+
58
+ def draw(nodes)
59
+ path, filename = nil, filename() # outside block to capture value
60
+ digraph do
61
+ node_attribs << color('"#b6d7a8"') << filled << fontcolor("white")
62
+ edge_attribs << color('"#999999"') << filled
63
+ nodes.each do |parent|
64
+ if parent.highlighted?
65
+ node(parent.name)
66
+ else
67
+ node(parent.name).attributes << color('"#A4C2F4"')
68
+ end
69
+ parent.children.each do |child|
70
+ edge(parent.name, child.name)
71
+ end
72
+ end
73
+ FileUtils.mkdir_p(File.dirname(filename))
74
+ save(filename, "png")
75
+ path = "#{filename}.png"
76
+ end
77
+
78
+ logger.info "Graph saved to #{Terraspace::Util.pretty_path(path)}"
79
+ open(path)
80
+ end
81
+
82
+ private
83
+ def draw_full_graph
84
+ if @options[:format] == "text"
85
+ @options[:full].nil? ? false : @options[:full]
86
+ else
87
+ @options[:full].nil? ? true : @options[:full]
88
+ end
89
+ end
90
+
91
+
92
+ def filename
93
+ name = "#{Terraspace.cache_root}/graph/dependencies" # dont include extension
94
+ unless ENV['TS_GRAPH_TS'] == '0'
95
+ @@timestamp ||= Time.now.utc.strftime("%Y%m%d%H%M%S")
96
+ name += "-#{@@timestamp}"
97
+ end
98
+ name
99
+ end
100
+
101
+ def open(path)
102
+ command = command("c9") || command("open")
103
+ system("#{command} #{path}") if command
104
+ end
105
+
106
+ def command(name)
107
+ name if system("type #{name} > /dev/null 2>&1") # c9 = cloud9, open = macosx
108
+ end
109
+
110
+ # Check if Graphiz is installed and prints a user friendly message if it is not installed.
111
+ def check_graphviz!
112
+ installed = system("type dot > /dev/null 2>&1") # dot is a command that is part of the graphviz package
113
+ return if installed
114
+ logger.error "ERROR: It appears that the Graphviz is not installed. Please install it to use the graph command.".color(:red)
115
+ if RUBY_PLATFORM =~ /darwin/
116
+ logger.error "You can install Graphviz with homebrew:"
117
+ logger.error " brew install graphviz"
118
+ end
119
+ logger.info <<~EOL
120
+ Also consider:
121
+
122
+ terraspace all graph --format text
123
+
124
+ Which will print out the graph in text form.
125
+ EOL
126
+ exit 1
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,43 @@
1
+ module Terraspace::All
2
+ class Preview
3
+ extend Memoist
4
+ include Terraspace::Util::Logging
5
+ include Terraspace::Compiler::DirsConcern
6
+
7
+ def initialize(command, batches, options={})
8
+ @command, @batches, @options = command, batches, options
9
+ end
10
+
11
+ def show
12
+ logger.info header
13
+ logger.info preview
14
+ end
15
+
16
+ def header
17
+ %w[up down].include?(@command) && !@options[:yes] ? "Will run:" : "Running:"
18
+ end
19
+
20
+ def preview
21
+ i = 0
22
+ @batches.map do |batch|
23
+ i += 1
24
+ batch.map do |stack|
25
+ command = " terraspace #{@command}"
26
+ ljust = command.size + max_name_size + 1
27
+ command = "#{command} #{stack.name}"
28
+ command.ljust(ljust, ' ') + " # batch #{i}"
29
+ end
30
+ end.join("\n")
31
+ end
32
+
33
+ def max_name_size
34
+ @batches.inject(0) do |max,batch|
35
+ batch.each do |node|
36
+ max = node.name.size if node.name.size > max
37
+ end
38
+ max
39
+ end
40
+ end
41
+ memoize :max_name_size
42
+ end
43
+ end
@@ -0,0 +1,169 @@
1
+ module Terraspace::All
2
+ class Runner < Base
3
+ include Terraspace::Util
4
+
5
+ def initialize(command, options={})
6
+ @command, @options = command, options
7
+ super(options)
8
+ end
9
+
10
+ def run
11
+ time_took do
12
+ @batches = build_batches
13
+ preview
14
+ are_you_sure?
15
+ deploy_batches
16
+ end
17
+ end
18
+
19
+ def preview
20
+ Preview.new(@command, @batches, @options).show
21
+ end
22
+
23
+ def build_batches
24
+ @batches = run_builder(quiet: false)
25
+ @batches.reverse! if @command == "down"
26
+ @batches
27
+ end
28
+
29
+ def deploy_batches
30
+ truncate_logs if ENV['TS_TRUNCATE_LOGS']
31
+ @batches.each_with_index do |batch,i|
32
+ logger.info "Batch Run #{i+1}:"
33
+ run_builder unless i == 0 # already handled by build_batches the first time
34
+ deploy_batch(batch)
35
+ end
36
+ end
37
+
38
+ # Should run after each batch run. run_builder also calls replace_outputs.
39
+ # Important: rebuild from source so placeholders are in place.
40
+ def run_builder(quiet: true)
41
+ Terraspace::Builder.new(@options.merge(mod: "placeholder", quiet: quiet)).run
42
+ end
43
+
44
+ def deploy_batch(batch)
45
+ @pids = {} # stores child processes pids. map of pid to mod_name, reset this list on each batch run
46
+ concurrency = Terraspace.config.all.concurrency
47
+ batch.sort_by(&:name).each_slice(concurrency) do |slice|
48
+ slice.each do |node|
49
+ pid = fork do
50
+ run_terraspace(node.name)
51
+ end
52
+ @pids[pid] = node.name # store mod_name mapping
53
+ end
54
+ end
55
+ wait_for_child_proccess
56
+ summarize # also reports lower-level error info
57
+ report_errors # reports finall errors and possibly exit
58
+ end
59
+
60
+ def wait_for_child_proccess
61
+ @errors = [] # stores child processes pids that errored
62
+ @pids.each do |pid, _|
63
+ pid, status = Process.wait2(pid)
64
+ success = status.exitstatus == 0
65
+ @errors << pid unless success
66
+ end
67
+ end
68
+
69
+ def report_errors
70
+ @errors.each do |pid|
71
+ mod_name = @pids[pid]
72
+ terraspace_command = terraspace_command(mod_name)
73
+ logger.error "Error running: #{terraspace_command}. Check logs and fix the error.".color(:red)
74
+ end
75
+ unless @errors.empty?
76
+ exit 2 if exit_on_fail?
77
+ end
78
+ end
79
+
80
+ # Precendence:
81
+ # 1. env var
82
+ # 2. cli
83
+ # 3. config/app.rb setting
84
+ def exit_on_fail?
85
+ return false if ENV['TS_EXIT_ON_FAIL'] == '0'
86
+ if @options[:exit_on_fail].nil?
87
+ Terraspace.config.all.exit_on_fail[@command]
88
+ else
89
+ @options[:exit_on_fail]
90
+ end
91
+ end
92
+
93
+ def summarize
94
+ @pids.each do |_, mod_name|
95
+ data = {
96
+ command: @command,
97
+ log_path: log_path(mod_name),
98
+ terraspace_command: terraspace_command(mod_name),
99
+ }
100
+ Summary.new(data).run
101
+ end
102
+ end
103
+
104
+ def run_terraspace(mod_name)
105
+ set_log_path!(mod_name)
106
+ name = command_map(@command)
107
+ o = @options.merge(mod: mod_name, yes: true, build: false, input: false)
108
+ case @command
109
+ when "up"
110
+ Terraspace::CLI::Up.new(o).run
111
+ when "down"
112
+ Terraspace::CLI::Down.new(o).run
113
+ else
114
+ Terraspace::CLI::Commander.new(name, o).run
115
+ end
116
+ end
117
+
118
+ def set_log_path!(mod_name)
119
+ command = terraspace_command(mod_name)
120
+ path = log_path(mod_name)
121
+ pretty_path = Terraspace::Util.pretty_path(path)
122
+ logger.info "Running: #{command.bright} Logs: #{pretty_path}"
123
+
124
+ FileUtils.mkdir_p(File.dirname(path))
125
+ logger = Terraspace::Logger.new(path)
126
+ logger.level = Terraspace.config.logger.level # match the level that user configured
127
+ logger.formatter = Terraspace.config.logger.formatter # match the level that user configured
128
+ logger.progname = command
129
+ Terraspace.logger = logger
130
+ end
131
+
132
+ def log_path(mod_name)
133
+ "#{Terraspace.config.log.root}/#{@command}/#{mod_name}.log"
134
+ end
135
+
136
+ def truncate_logs
137
+ logs = Terraspace::CLI::Log::Tasks.new(mute: true)
138
+ logs.truncate
139
+ end
140
+
141
+ def terraspace_command(name)
142
+ "terraspace #{@command} #{name}"
143
+ end
144
+
145
+ def command_map(name)
146
+ map = {
147
+ up: "apply",
148
+ down: "destroy",
149
+ }.stringify_keys
150
+ map[name] || name
151
+ end
152
+
153
+ def are_you_sure?
154
+ return true unless sure_command?
155
+ sure? # from Util
156
+ end
157
+
158
+ def sure_command?
159
+ %w[up down].include?(@command)
160
+ end
161
+
162
+ def time_took
163
+ t1 = Time.now
164
+ yield
165
+ t2 = Time.now
166
+ logger.info "Time took: #{pretty_time(t2-t1)}"
167
+ end
168
+ end
169
+ end