terraspace 0.2.3 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  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 +5 -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 +31 -9
  14. data/lib/terraspace/booter.rb +9 -0
  15. data/lib/terraspace/builder.rb +59 -22
  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 +17 -5
  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 +1 -8
  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 +46 -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/backend.rb +10 -0
  39. data/lib/terraspace/compiler/builder.rb +5 -4
  40. data/lib/terraspace/compiler/cleaner.rb +1 -1
  41. data/lib/terraspace/compiler/cleaner/backend_change.rb +21 -7
  42. data/lib/terraspace/compiler/commands_concern.rb +18 -0
  43. data/lib/terraspace/compiler/dirs_concern.rb +47 -0
  44. data/lib/terraspace/compiler/dsl/syntax/helpers/common.rb +26 -1
  45. data/lib/terraspace/core.rb +11 -2
  46. data/lib/terraspace/dependency/graph.rb +139 -0
  47. data/lib/terraspace/dependency/node.rb +38 -0
  48. data/lib/terraspace/dependency/registry.rb +11 -0
  49. data/lib/terraspace/logger.rb +6 -18
  50. data/lib/terraspace/logger/formatter.rb +13 -0
  51. data/lib/terraspace/mod.rb +7 -1
  52. data/lib/terraspace/seeder/where.rb +6 -2
  53. data/lib/terraspace/shell.rb +97 -0
  54. data/lib/terraspace/terraform/api.rb +7 -45
  55. data/lib/terraspace/terraform/api/base.rb +7 -0
  56. data/lib/terraspace/terraform/api/client.rb +23 -3
  57. data/lib/terraspace/terraform/api/http.rb +14 -34
  58. data/lib/terraspace/terraform/api/http/concern.rb +10 -0
  59. data/lib/terraspace/terraform/api/runs.rb +28 -0
  60. data/lib/terraspace/terraform/api/token.rb +65 -0
  61. data/lib/terraspace/terraform/api/var.rb +20 -6
  62. data/lib/terraspace/terraform/api/vars.rb +2 -1
  63. data/lib/terraspace/terraform/api/workspace.rb +98 -0
  64. data/lib/terraspace/terraform/args/default.rb +48 -21
  65. data/lib/terraspace/terraform/cloud/runs.rb +13 -0
  66. data/lib/terraspace/terraform/cloud/runs/base.rb +33 -0
  67. data/lib/terraspace/terraform/cloud/runs/item_presenter.rb +37 -0
  68. data/lib/terraspace/terraform/cloud/runs/lister.rb +22 -0
  69. data/lib/terraspace/terraform/cloud/runs/pruner.rb +109 -0
  70. data/lib/terraspace/terraform/cloud/sync.rb +41 -0
  71. data/lib/terraspace/terraform/cloud/syncer.rb +52 -0
  72. data/lib/terraspace/terraform/cloud/workspace.rb +10 -21
  73. data/lib/terraspace/terraform/hooks/builder.rb +1 -1
  74. data/lib/terraspace/terraform/remote_state/fetcher.rb +143 -0
  75. data/lib/terraspace/terraform/remote_state/marker/output.rb +39 -0
  76. data/lib/terraspace/terraform/remote_state/marker/pretty_tracer.rb +37 -0
  77. data/lib/terraspace/terraform/remote_state/output_proxy.rb +29 -0
  78. data/lib/terraspace/terraform/runner.rb +24 -14
  79. data/lib/terraspace/util.rb +1 -5
  80. data/lib/terraspace/util/pretty.rb +18 -0
  81. data/lib/terraspace/version.rb +1 -1
  82. data/spec/fixtures/fetcher/c1.json +37 -0
  83. data/spec/fixtures/parser/cache_dirs/all/01-test.auto.tfvars +5 -0
  84. data/spec/fixtures/parser/cache_dirs/depends_on/01-test.auto.tfvars +2 -0
  85. data/spec/fixtures/parser/cache_dirs/output/01-test.auto.tfvars +2 -0
  86. data/spec/fixtures/summary/down.log +12 -0
  87. data/spec/fixtures/summary/output.log +5 -0
  88. data/spec/fixtures/summary/plan/error.log +20 -0
  89. data/spec/fixtures/summary/plan/success.log +17 -0
  90. data/spec/fixtures/summary/show.log +22 -0
  91. data/spec/fixtures/summary/up/error.log +13 -0
  92. data/spec/fixtures/summary/up/success.log +63 -0
  93. data/spec/fixtures/summary/validate/error.log +13 -0
  94. data/spec/fixtures/summary/validate/success.log +5 -0
  95. data/spec/terraspace/all/grapher_spec.rb +38 -0
  96. data/spec/terraspace/all/runner_spec.rb +48 -0
  97. data/spec/terraspace/all/summary_spec.rb +93 -0
  98. data/spec/terraspace/dependency/graph_spec.rb +162 -0
  99. data/spec/terraspace/seeder_spec.rb +0 -1
  100. data/spec/terraspace/terraform/remote_state/fetcher_spec.rb +52 -0
  101. data/terraspace.gemspec +5 -1
  102. metadata +138 -5
  103. data/lib/terraspace/terraform/cloud.rb +0 -25
  104. data/lib/terraspace/util/sh.rb +0 -19
@@ -0,0 +1,37 @@
1
+ module Terraspace::Terraform::RemoteState::Marker
2
+ class PrettyTracer
3
+ def initialize(caller_line)
4
+ @caller_line = caller_line
5
+ end
6
+
7
+ # /full/path/to/app/stacks/a1/tfvars/dev.tfvars:4:in `__tilt_5560'
8
+ def source_code
9
+ line = @caller_line.sub(/:in `.*/,'')
10
+ path, error_line_number = line.split(':')
11
+ pretty_trace(path, error_line_number.to_i)
12
+ end
13
+
14
+ def pretty_trace(path, error_line_number)
15
+ io = StringIO.new
16
+ context = 5 # lines of context
17
+ top, bottom = [error_line_number-context-1, 0].max, error_line_number+context-1
18
+
19
+ io.puts "Here's the line in #{Terraspace::Util.pretty_path(path)} with the error:\n\n"
20
+
21
+ lines = IO.read(path).split("\n")
22
+ context = 5 # lines of context
23
+ top, bottom = [error_line_number-context-1, 0].max, error_line_number+context-1
24
+ spacing = lines.size.to_s.size
25
+ lines[top..bottom].each_with_index do |line_content, index|
26
+ line_number = top+index+1
27
+ if line_number == error_line_number
28
+ io.printf("%#{spacing}d %s\n".color(:red), line_number, line_content)
29
+ else
30
+ io.printf("%#{spacing}d %s\n", line_number, line_content)
31
+ end
32
+ end
33
+
34
+ io.string
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,29 @@
1
+ module Terraspace::Terraform::RemoteState
2
+ class OutputProxy
3
+ # raw: can be anything: String, Array, Hash, etc
4
+ # options: original options passed by user with terraform_output
5
+ attr_reader :raw, :options
6
+ def initialize(raw, options={})
7
+ @raw, @options = raw, options
8
+ @format = @options[:format]
9
+ end
10
+
11
+ # Should always return a String
12
+ def to_s
13
+ case @format
14
+ when "string"
15
+ content.to_s
16
+ else # "json"
17
+ content.to_json
18
+ end
19
+ end
20
+
21
+ def content
22
+ if @raw.nil?
23
+ @options[:mock] || @options[:error]
24
+ else
25
+ @raw
26
+ end
27
+ end
28
+ end
29
+ end
@@ -7,6 +7,7 @@ module Terraspace::Terraform
7
7
  def initialize(name, options={})
8
8
  @name = name
9
9
  super(options)
10
+ @retries = 1
10
11
  end
11
12
 
12
13
  def run
@@ -21,17 +22,37 @@ module Terraspace::Terraform
21
22
  params = args.flatten.join(' ')
22
23
  command = "terraform #{name} #{params}"
23
24
  run_hooks(name) do
24
- sh(command, env: custom.env_vars)
25
+ Terraspace::Shell.new(@mod, command, @options.merge(env: custom.env_vars)).run
26
+ end
27
+ rescue Terraspace::InitRequiredError => e
28
+ logger.info "Terraform reinitialization required detected. Will run `terraform init` and try again."
29
+ logger.debug "Retry attempt: #{@retries}"
30
+ logger.debug "#{e.class}"
31
+ Runner.new("init", @options).run
32
+ if @retries <= 3
33
+ backoff = 2 ** @retries # 2, 4, 8
34
+ logger.debug "Waiting #{backoff}s before retrying"
35
+ sleep(backoff)
36
+ @retries += 1
37
+ retry
38
+ else
39
+ logger.info "ERROR: #{e.message}"
40
+ exit 1
25
41
  end
26
42
  end
27
43
 
28
44
  @@current_dir_message_shown = false
29
45
  def current_dir_message
30
46
  return if @@current_dir_message_shown
31
- logger.info "Current directory: #{Terraspace::Util.pretty_path(@mod.cache_dir)}"
47
+ log "Current directory: #{Terraspace::Util.pretty_path(@mod.cache_dir)}"
32
48
  @@current_dir_message_shown = true
33
49
  end
34
50
 
51
+ def log(msg)
52
+ # quiet useful for RemoteState::Fetcher
53
+ @options[:quiet] ? logger.debug(msg) : logger.info(msg)
54
+ end
55
+
35
56
  def run_hooks(name, &block)
36
57
  hooks = Hooks::Builder.new(@mod, name)
37
58
  hooks.build # build hooks
@@ -59,18 +80,7 @@ module Terraspace::Terraform
59
80
  yield
60
81
  t2 = Time.now
61
82
  if %w[apply destroy].include?(@name)
62
- puts "Time took: #{pretty_time(t2-t1)}"
63
- end
64
- end
65
-
66
- # http://stackoverflow.com/questions/4175733/convert-duration-to-hoursminutesseconds-or-similar-in-rails-3-or-ruby
67
- def pretty_time(total_seconds)
68
- minutes = (total_seconds / 60) % 60
69
- seconds = total_seconds % 60
70
- if total_seconds < 60
71
- "#{seconds.to_i}s"
72
- else
73
- "#{minutes.to_i}m #{seconds.to_i}s"
83
+ logger.info "Time took: #{pretty_time(t2-t1)}"
74
84
  end
75
85
  end
76
86
  end
@@ -1,12 +1,8 @@
1
1
  module Terraspace
2
2
  module Util
3
3
  include Logging
4
- include Sh
5
4
  include Sure
6
-
7
- def pretty_path(path)
8
- ENV['TS_TEST'] ? path : path.sub("#{Terraspace.root}/",'')
9
- end
5
+ include Pretty
10
6
 
11
7
  extend self
12
8
  end
@@ -0,0 +1,18 @@
1
+ module Terraspace::Util
2
+ module Pretty
3
+ # http://stackoverflow.com/questions/4175733/convert-duration-to-hoursminutesseconds-or-similar-in-rails-3-or-ruby
4
+ def pretty_time(total_seconds)
5
+ minutes = (total_seconds / 60) % 60
6
+ seconds = total_seconds % 60
7
+ if total_seconds < 60
8
+ "#{seconds.to_i}s"
9
+ else
10
+ "#{minutes.to_i}m #{seconds.to_i}s"
11
+ end
12
+ end
13
+
14
+ def pretty_path(path)
15
+ ENV['TS_TEST'] ? path : path.sub("#{Terraspace.root}/",'')
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,3 @@
1
1
  module Terraspace
2
- VERSION = "0.2.3"
2
+ VERSION = "0.3.3"
3
3
  end
@@ -0,0 +1,37 @@
1
+ {
2
+ "version": 4,
3
+ "terraform_version": "0.13.1",
4
+ "serial": 30,
5
+ "lineage": "9b6b98f3-3bc7-362d-5232-71847ce6d86a",
6
+ "outputs": {
7
+ "length": {
8
+ "value": 1,
9
+ "type": "number"
10
+ },
11
+ "random_pet_id": {
12
+ "value": "valued-buzzard",
13
+ "type": "string"
14
+ }
15
+ },
16
+ "resources": [
17
+ {
18
+ "mode": "managed",
19
+ "type": "random_pet",
20
+ "name": "this",
21
+ "provider": "provider[\"registry.terraform.io/hashicorp/random\"]",
22
+ "instances": [
23
+ {
24
+ "schema_version": 0,
25
+ "attributes": {
26
+ "id": "valued-buzzard",
27
+ "keepers": null,
28
+ "length": 2,
29
+ "prefix": null,
30
+ "separator": "-"
31
+ },
32
+ "private": "bnVsbA=="
33
+ }
34
+ ]
35
+ }
36
+ ]
37
+ }
@@ -0,0 +1,5 @@
1
+
2
+ # MARKER_DEPENDS_ON:b1:c1 #
3
+
4
+ length1 = MARKER_OUTPUT:b1:c1.length #
5
+ length1 = MARKER_OUTPUT:b1:c2.length #
@@ -0,0 +1,2 @@
1
+
2
+ # MARKER_DEPENDS_ON:b1:c1 #
@@ -0,0 +1,2 @@
1
+
2
+ length1 = MARKER_OUTPUT:b1:c1.length #
@@ -0,0 +1,12 @@
1
+ # Logfile created on 2020-09-09 12:43:23 +0000 by logger.rb/v1.4.2
2
+ [2020-09-09T12:43:23 #18949 terraspace down a1]: Current directory: .terraspace-cache/us-west-2/dev/stacks/a1
3
+ [2020-09-09T12:43:23 #18949 terraspace down a1]: => terraform destroy -auto-approve
4
+ [2020-09-09T12:43:24 #18949 terraspace down a1]: random_pet.pet1: Refreshing state... [id=python]
5
+ [2020-09-09T12:43:24 #18949 terraspace down a1]: random_pet.pet2: Refreshing state... [id=hound]
6
+ [2020-09-09T12:43:24 #18949 terraspace down a1]: random_pet.pet2: Destroying... [id=hound]
7
+ [2020-09-09T12:43:24 #18949 terraspace down a1]: random_pet.pet1: Destroying... [id=python]
8
+ [2020-09-09T12:43:24 #18949 terraspace down a1]: random_pet.pet2: Destruction complete after 0s
9
+ [2020-09-09T12:43:24 #18949 terraspace down a1]: random_pet.pet1: Destruction complete after 0s
10
+ [2020-09-09T12:43:24 #18949 terraspace down a1]: 
11
+ [2020-09-09T12:43:24 #18949 terraspace down a1]: Destroy complete! Resources: 2 destroyed.
12
+ [2020-09-09T12:43:24 #18949 terraspace down a1]: Time took: 1s
@@ -0,0 +1,5 @@
1
+ # Logfile created on 2020-09-09 13:30:18 +0000 by logger.rb/v1.4.2
2
+ [2020-09-09T13:30:18 #20693 terraspace output a1]: Current directory: .terraspace-cache/us-west-2/dev/stacks/a1
3
+ [2020-09-09T13:30:18 #20693 terraspace output a1]: => terraform output
4
+ [2020-09-09T13:30:19 #20693 terraspace output a1]: pet1 = krill
5
+ [2020-09-09T13:30:19 #20693 terraspace output a1]: pet2 = sunfish
@@ -0,0 +1,20 @@
1
+ # Logfile created on 2020-09-09 12:49:43 +0000 by logger.rb/v1.4.2
2
+ [2020-09-09T12:49:43 #9022 terraspace plan a1]: Current directory: .terraspace-cache/us-west-2/dev/stacks/a1
3
+ [2020-09-09T12:49:43 #9022 terraspace plan a1]: => terraform plan
4
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]: 
5
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]: Error: Unbalanced parentheses
6
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]:
7
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]:  on 01-dev.auto.tfvars line 4:
8
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]: 4: length1 = (Output length was not found for the a1 tfvars file. Either b1 stack has not been deployed yet or it has no outputs)
9
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]: 
10
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]: Expected a closing parenthesis to terminate the expression.
11
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]: 
12
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]: 
13
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]: Error: Unbalanced parentheses
14
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]:
15
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]:  on 01-dev.auto.tfvars line 5:
16
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]: 5: length2 = (Output length was not found for the a1 tfvars file. Either b2 stack has not been deployed yet or it has no outputs)
17
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]: 
18
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]: Expected a closing parenthesis to terminate the expression.
19
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]: 
20
+ [2020-09-09T12:49:44 #9022 terraspace plan a1]: Error running command: terraform plan 
@@ -0,0 +1,17 @@
1
+ # Logfile created on 2020-09-09 12:55:02 +0000 by logger.rb/v1.4.2
2
+ [2020-09-09T12:55:02 #6599 terraspace plan a1]: Current directory: .terraspace-cache/us-west-2/dev/stacks/a1
3
+ [2020-09-09T12:55:02 #6599 terraspace plan a1]: => terraform plan
4
+ [2020-09-09T12:55:03 #6599 terraspace plan a1]: Refreshing Terraform state in-memory prior to plan...
5
+ [2020-09-09T12:55:03 #6599 terraspace plan a1]: The refreshed state will be used to calculate this plan, but will not be
6
+ [2020-09-09T12:55:03 #6599 terraspace plan a1]: persisted to local or remote state storage.
7
+ [2020-09-09T12:55:03 #6599 terraspace plan a1]: 
8
+ [2020-09-09T12:55:03 #6599 terraspace plan a1]: random_pet.pet1: Refreshing state... [id=krill]
9
+ [2020-09-09T12:55:03 #6599 terraspace plan a1]: random_pet.pet2: Refreshing state... [id=sunfish]
10
+ [2020-09-09T12:55:03 #6599 terraspace plan a1]:
11
+ [2020-09-09T12:55:03 #6599 terraspace plan a1]: ------------------------------------------------------------------------
12
+ [2020-09-09T12:55:03 #6599 terraspace plan a1]:
13
+ [2020-09-09T12:55:03 #6599 terraspace plan a1]: No changes. Infrastructure is up-to-date.
14
+ [2020-09-09T12:55:03 #6599 terraspace plan a1]:
15
+ [2020-09-09T12:55:03 #6599 terraspace plan a1]: This means that Terraform did not detect any differences between your
16
+ [2020-09-09T12:55:03 #6599 terraspace plan a1]: configuration and real physical resources that exist. As a result, no
17
+ [2020-09-09T12:55:03 #6599 terraspace plan a1]: actions need to be performed.
@@ -0,0 +1,22 @@
1
+ # Logfile created on 2020-09-09 13:31:26 +0000 by logger.rb/v1.4.2
2
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: Current directory: .terraspace-cache/us-west-2/dev/stacks/a1
3
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: => terraform show
4
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: # random_pet.pet1:
5
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: resource "random_pet" "pet1" {
6
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: id = "krill"
7
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: length = 1
8
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: separator = "-"
9
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: }
10
+ [2020-09-09T13:31:26 #32045 terraspace show a1]:
11
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: # random_pet.pet2:
12
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: resource "random_pet" "pet2" {
13
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: id = "sunfish"
14
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: length = 1
15
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: separator = "-"
16
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: }
17
+ [2020-09-09T13:31:26 #32045 terraspace show a1]:
18
+ [2020-09-09T13:31:26 #32045 terraspace show a1]:
19
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: Outputs:
20
+ [2020-09-09T13:31:26 #32045 terraspace show a1]:
21
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: pet1 = "krill"
22
+ [2020-09-09T13:31:26 #32045 terraspace show a1]: pet2 = "sunfish"
@@ -0,0 +1,13 @@
1
+ # Logfile created on 2020-09-09 13:36:29 +0000 by logger.rb/v1.4.2
2
+ [2020-09-09T13:36:29 #15895 terraspace up a1]: Current directory: .terraspace-cache/us-west-2/dev/stacks/a1
3
+ [2020-09-09T13:36:29 #15895 terraspace up a1]: => terraform plan -out /tmp/terraspace/plans/a1-20200909133629.plan
4
+ [2020-09-09T13:36:29 #15895 terraspace up a1]: 
5
+ [2020-09-09T13:36:29 #15895 terraspace up a1]: Error: Unsupported attribute
6
+ [2020-09-09T13:36:29 #15895 terraspace up a1]:
7
+ [2020-09-09T13:36:29 #15895 terraspace up a1]:  on outputs.tf line 8, in output "pet2":
8
+ [2020-09-09T13:36:29 #15895 terraspace up a1]: 8: value = random_pet.pet2.id2
9
+ [2020-09-09T13:36:29 #15895 terraspace up a1]: 
10
+ [2020-09-09T13:36:29 #15895 terraspace up a1]: This object has no argument, nested block, or exported attribute named "id2".
11
+ [2020-09-09T13:36:29 #15895 terraspace up a1]: Did you mean "id"?
12
+ [2020-09-09T13:36:29 #15895 terraspace up a1]: 
13
+ [2020-09-09T13:36:29 #15895 terraspace up a1]: Error running command: terraform plan -out /tmp/terraspace/plans/a1-20200909133629.plan
@@ -0,0 +1,63 @@
1
+ # Logfile created on 2020-09-09 12:43:06 +0000 by logger.rb/v1.4.2
2
+ [2020-09-09T12:43:06 #14973 terraspace up a1]: Current directory: .terraspace-cache/us-west-2/dev/stacks/a1
3
+ [2020-09-09T12:43:06 #14973 terraspace up a1]: => terraform plan -out /tmp/terraspace/plans/a1-20200909124306.plan
4
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: Refreshing Terraform state in-memory prior to plan...
5
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: The refreshed state will be used to calculate this plan, but will not be
6
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: persisted to local or remote state storage.
7
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: 
8
+ [2020-09-09T12:43:07 #14973 terraspace up a1]:
9
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: ------------------------------------------------------------------------
10
+ [2020-09-09T12:43:07 #14973 terraspace up a1]:
11
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: An execution plan has been generated and is shown below.
12
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: Resource actions are indicated with the following symbols:
13
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: + create
14
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: 
15
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: Terraform will perform the following actions:
16
+ [2020-09-09T12:43:07 #14973 terraspace up a1]:
17
+ [2020-09-09T12:43:07 #14973 terraspace up a1]:  # random_pet.pet1 will be created
18
+ [2020-09-09T12:43:07 #14973 terraspace up a1]:  + resource "random_pet" "pet1" {
19
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: + id = (known after apply)
20
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: + length = 1
21
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: + separator = "-"
22
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: }
23
+ [2020-09-09T12:43:07 #14973 terraspace up a1]:
24
+ [2020-09-09T12:43:07 #14973 terraspace up a1]:  # random_pet.pet2 will be created
25
+ [2020-09-09T12:43:07 #14973 terraspace up a1]:  + resource "random_pet" "pet2" {
26
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: + id = (known after apply)
27
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: + length = 1
28
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: + separator = "-"
29
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: }
30
+ [2020-09-09T12:43:07 #14973 terraspace up a1]:
31
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: Plan: 2 to add, 0 to change, 0 to destroy.
32
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: 
33
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: Changes to Outputs:
34
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: + pet1 = (known after apply)
35
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: + pet2 = (known after apply)
36
+ [2020-09-09T12:43:07 #14973 terraspace up a1]:
37
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: ------------------------------------------------------------------------
38
+ [2020-09-09T12:43:07 #14973 terraspace up a1]:
39
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: This plan was saved to: /tmp/terraspace/plans/a1-20200909124306.plan
40
+ [2020-09-09T12:43:07 #14973 terraspace up a1]:
41
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: To perform exactly these actions, run the following command to apply:
42
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: terraform apply "/tmp/terraspace/plans/a1-20200909124306.plan"
43
+ [2020-09-09T12:43:07 #14973 terraspace up a1]:
44
+ [2020-09-09T12:43:07 #14973 terraspace up a1]: => terraform apply -auto-approve /tmp/terraspace/plans/a1-20200909124306.plan
45
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: random_pet.pet2: Creating...
46
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: random_pet.pet1: Creating...
47
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: random_pet.pet2: Creation complete after 0s [id=hound]
48
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: random_pet.pet1: Creation complete after 0s [id=python]
49
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: 
50
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
51
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: 
52
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: The state of your infrastructure has been saved to the path
53
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: below. This state is required to modify and destroy your
54
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: infrastructure, so keep it safe. To inspect the complete state
55
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: use the `terraform show` command.
56
+ [2020-09-09T12:43:08 #14973 terraspace up a1]:
57
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: State path: terraform.tfstate
58
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: 
59
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: Outputs:
60
+ [2020-09-09T12:43:08 #14973 terraspace up a1]:
61
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: pet1 = python
62
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: pet2 = hound
63
+ [2020-09-09T12:43:08 #14973 terraspace up a1]: Time took: 0s
@@ -0,0 +1,13 @@
1
+ # Logfile created on 2020-09-09 13:34:25 +0000 by logger.rb/v1.4.2
2
+ [2020-09-09T13:34:25 #22695 terraspace validate a1]: Current directory: .terraspace-cache/us-west-2/dev/stacks/a1
3
+ [2020-09-09T13:34:25 #22695 terraspace validate a1]: => terraform validate
4
+ [2020-09-09T13:34:26 #22695 terraspace validate a1]: 
5
+ [2020-09-09T13:34:26 #22695 terraspace validate a1]: Error: Unsupported attribute
6
+ [2020-09-09T13:34:26 #22695 terraspace validate a1]:
7
+ [2020-09-09T13:34:26 #22695 terraspace validate a1]:  on outputs.tf line 8, in output "pet2":
8
+ [2020-09-09T13:34:26 #22695 terraspace validate a1]: 8: value = random_pet.pet2.id2
9
+ [2020-09-09T13:34:26 #22695 terraspace validate a1]: 
10
+ [2020-09-09T13:34:26 #22695 terraspace validate a1]: This object has no argument, nested block, or exported attribute named "id2".
11
+ [2020-09-09T13:34:26 #22695 terraspace validate a1]: Did you mean "id"?
12
+ [2020-09-09T13:34:26 #22695 terraspace validate a1]: 
13
+ [2020-09-09T13:34:26 #22695 terraspace validate a1]: Error running command: terraform validate 
@@ -0,0 +1,5 @@
1
+ # Logfile created on 2020-09-09 13:32:51 +0000 by logger.rb/v1.4.2
2
+ [2020-09-09T13:32:51 #11221 terraspace validate a1]: Current directory: .terraspace-cache/us-west-2/dev/stacks/a1
3
+ [2020-09-09T13:32:51 #11221 terraspace validate a1]: => terraform validate
4
+ [2020-09-09T13:32:52 #11221 terraspace validate a1]: Success! The configuration is valid.
5
+ [2020-09-09T13:32:52 #11221 terraspace validate a1]: 
@@ -0,0 +1,38 @@
1
+ describe Terraspace::All::Grapher do
2
+ Node = Terraspace::Dependency::Node
3
+
4
+ let(:grapher) do
5
+ grapher = described_class.new(format: "text")
6
+ allow(grapher).to receive(:logger).and_return(logger)
7
+ grapher
8
+ end
9
+ # To capture logger output for testing
10
+ let(:logger) do
11
+ @io = StringIO.new
12
+ Logger.new(@io)
13
+ end
14
+
15
+ context "nodes" do
16
+ it "text" do
17
+ a1 = Node.new("a1")
18
+ b1 = Node.new("b1")
19
+ b2 = Node.new("b2")
20
+ b1.parent!(a1)
21
+ b2.parent!(a1)
22
+ nodes = [a1,b1,b2]
23
+ grapher.text(nodes)
24
+ out = <<~EOL.chop # remove newline
25
+ ├── a1
26
+ │ ├── b1
27
+ │ └── b2
28
+ ├── b1
29
+ └── b2
30
+ EOL
31
+ # remove the top line which is
32
+ # +I, [2020-09-09T13:44:33.822100 #22549] INFO -- : .
33
+ actual = @io.string.split("\n")[1..-1].join("\n")
34
+ expect(actual).to eq(out)
35
+ end
36
+
37
+ end
38
+ end