terraspace 0.2.4 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/.cody/aws/bin/build.sh +2 -0
  3. data/.cody/azurerm/bin/build.sh +2 -0
  4. data/.cody/google/bin/build.sh +2 -0
  5. data/CHANGELOG.md +39 -1
  6. data/README.md +14 -1
  7. data/lib/templates/base/git_hook/hook.sh +1 -1
  8. data/lib/templates/base/project/.gitignore +1 -0
  9. data/lib/templates/base/project/README.md +17 -0
  10. data/lib/terraspace.rb +6 -0
  11. data/lib/terraspace/all/base.rb +8 -0
  12. data/lib/terraspace/all/grapher.rb +129 -0
  13. data/lib/terraspace/all/preview.rb +43 -0
  14. data/lib/terraspace/all/runner.rb +169 -0
  15. data/lib/terraspace/all/summary.rb +119 -0
  16. data/lib/terraspace/app.rb +31 -9
  17. data/lib/terraspace/booter.rb +9 -0
  18. data/lib/terraspace/builder.rb +59 -22
  19. data/lib/terraspace/cli.rb +60 -33
  20. data/lib/terraspace/cli/all.rb +63 -0
  21. data/lib/terraspace/cli/build/placeholder.rb +2 -5
  22. data/lib/terraspace/cli/bundle.rb +1 -1
  23. data/lib/terraspace/cli/check_setup.rb +5 -0
  24. data/lib/terraspace/cli/cloud.rb +16 -6
  25. data/lib/terraspace/cli/cloud/runs.rb +22 -0
  26. data/lib/terraspace/cli/commander.rb +1 -8
  27. data/lib/terraspace/cli/down.rb +20 -0
  28. data/lib/terraspace/cli/help/all/down.md +32 -0
  29. data/lib/terraspace/cli/help/all/graph.md +21 -0
  30. data/lib/terraspace/cli/help/all/output.md +22 -0
  31. data/lib/terraspace/cli/help/all/plan.md +25 -0
  32. data/lib/terraspace/cli/help/all/providers.md +21 -0
  33. data/lib/terraspace/cli/help/all/refresh.md +17 -0
  34. data/lib/terraspace/cli/help/all/show.md +21 -0
  35. data/lib/terraspace/cli/help/all/up.md +27 -0
  36. data/lib/terraspace/cli/help/all/validate.md +21 -0
  37. data/lib/terraspace/cli/help/build.md +6 -0
  38. data/lib/terraspace/cli/help/bundle.md +9 -5
  39. data/lib/terraspace/cli/help/check_setup.md +9 -0
  40. data/lib/terraspace/cli/help/clean.md +5 -0
  41. data/lib/terraspace/cli/help/cloud/destroy.md +16 -0
  42. data/lib/terraspace/cli/help/cloud/list.md +7 -0
  43. data/lib/terraspace/cli/help/cloud/runs/list.md +36 -0
  44. data/lib/terraspace/cli/help/cloud/runs/prune.md +25 -0
  45. data/lib/terraspace/cli/help/cloud/sync.md +43 -0
  46. data/lib/terraspace/cli/help/console.md +8 -0
  47. data/lib/terraspace/cli/help/down.md +26 -0
  48. data/lib/terraspace/cli/help/info.md +43 -0
  49. data/lib/terraspace/cli/help/init.md +37 -0
  50. data/lib/terraspace/cli/help/list.md +20 -0
  51. data/lib/terraspace/cli/help/log.md +48 -0
  52. data/lib/terraspace/cli/help/logs/remove.md +5 -0
  53. data/lib/terraspace/cli/help/logs/truncate.md +5 -0
  54. data/lib/terraspace/cli/help/new/bootstrap_test.md +8 -0
  55. data/lib/terraspace/cli/help/new/example.md +8 -0
  56. data/lib/terraspace/cli/help/new/git_hook.md +6 -0
  57. data/lib/terraspace/cli/help/new/module.md +9 -0
  58. data/lib/terraspace/cli/help/new/module_test.md +12 -0
  59. data/lib/terraspace/cli/help/new/plugin.md +49 -0
  60. data/lib/terraspace/cli/help/new/project.md +40 -0
  61. data/lib/terraspace/cli/help/new/project_test.md +8 -0
  62. data/lib/terraspace/cli/help/new/shim.md +21 -0
  63. data/lib/terraspace/cli/help/new/stack.md +9 -0
  64. data/lib/terraspace/cli/help/output.md +6 -0
  65. data/lib/terraspace/cli/help/plan.md +29 -0
  66. data/lib/terraspace/cli/help/providers.md +18 -0
  67. data/lib/terraspace/cli/help/refresh.md +11 -0
  68. data/lib/terraspace/cli/help/seed.md +7 -0
  69. data/lib/terraspace/cli/help/show.md +36 -0
  70. data/lib/terraspace/cli/help/summary.md +11 -0
  71. data/lib/terraspace/cli/help/test.md +35 -0
  72. data/lib/terraspace/cli/help/up.md +30 -0
  73. data/lib/terraspace/cli/help/validate.md +9 -0
  74. data/lib/terraspace/cli/info.rb +4 -16
  75. data/lib/terraspace/cli/init.rb +35 -7
  76. data/lib/terraspace/cli/list.rb +14 -1
  77. data/lib/terraspace/cli/log.rb +112 -0
  78. data/lib/terraspace/cli/log/concern.rb +24 -0
  79. data/lib/terraspace/cli/logs.rb +15 -0
  80. data/lib/terraspace/cli/logs/tasks.rb +32 -0
  81. data/lib/terraspace/cli/new.rb +18 -18
  82. data/lib/terraspace/cli/new/git_hook.rb +5 -2
  83. data/lib/terraspace/cli/new/project.rb +1 -1
  84. data/lib/terraspace/cli/summary.rb +2 -2
  85. data/lib/terraspace/cli/tfc_concern.rb +14 -0
  86. data/lib/terraspace/cli/up.rb +32 -0
  87. data/lib/terraspace/command.rb +1 -1
  88. data/lib/terraspace/compiler/backend.rb +10 -0
  89. data/lib/terraspace/compiler/builder.rb +5 -4
  90. data/lib/terraspace/compiler/cleaner.rb +1 -1
  91. data/lib/terraspace/compiler/cleaner/backend_change.rb +21 -7
  92. data/lib/terraspace/compiler/commands_concern.rb +18 -0
  93. data/lib/terraspace/compiler/dirs_concern.rb +47 -0
  94. data/lib/terraspace/compiler/dsl/syntax/helpers/common.rb +26 -1
  95. data/lib/terraspace/core.rb +11 -2
  96. data/lib/terraspace/dependency/graph.rb +140 -0
  97. data/lib/terraspace/dependency/node.rb +38 -0
  98. data/lib/terraspace/dependency/registry.rb +11 -0
  99. data/lib/terraspace/logger.rb +6 -18
  100. data/lib/terraspace/logger/formatter.rb +13 -0
  101. data/lib/terraspace/mod.rb +7 -1
  102. data/lib/terraspace/plugin/summary/interface.rb +1 -1
  103. data/lib/terraspace/seeder/where.rb +6 -2
  104. data/lib/terraspace/shell.rb +107 -0
  105. data/lib/terraspace/terraform/api.rb +7 -45
  106. data/lib/terraspace/terraform/api/base.rb +7 -0
  107. data/lib/terraspace/terraform/api/client.rb +23 -3
  108. data/lib/terraspace/terraform/api/http.rb +14 -34
  109. data/lib/terraspace/terraform/api/http/concern.rb +10 -0
  110. data/lib/terraspace/terraform/api/runs.rb +28 -0
  111. data/lib/terraspace/terraform/api/token.rb +65 -0
  112. data/lib/terraspace/terraform/api/var.rb +20 -6
  113. data/lib/terraspace/terraform/api/vars.rb +2 -1
  114. data/lib/terraspace/terraform/api/workspace.rb +98 -0
  115. data/lib/terraspace/terraform/args/default.rb +48 -21
  116. data/lib/terraspace/terraform/cloud/runs.rb +13 -0
  117. data/lib/terraspace/terraform/cloud/runs/base.rb +33 -0
  118. data/lib/terraspace/terraform/cloud/runs/item_presenter.rb +37 -0
  119. data/lib/terraspace/terraform/cloud/runs/lister.rb +20 -0
  120. data/lib/terraspace/terraform/cloud/runs/pruner.rb +109 -0
  121. data/lib/terraspace/terraform/cloud/sync.rb +41 -0
  122. data/lib/terraspace/terraform/cloud/syncer.rb +52 -0
  123. data/lib/terraspace/terraform/cloud/workspace.rb +10 -30
  124. data/lib/terraspace/terraform/hooks/builder.rb +1 -1
  125. data/lib/terraspace/terraform/remote_state/fetcher.rb +143 -0
  126. data/lib/terraspace/terraform/remote_state/marker/output.rb +39 -0
  127. data/lib/terraspace/terraform/remote_state/marker/pretty_tracer.rb +37 -0
  128. data/lib/terraspace/terraform/remote_state/output_proxy.rb +29 -0
  129. data/lib/terraspace/terraform/runner.rb +24 -14
  130. data/lib/terraspace/util.rb +1 -5
  131. data/lib/terraspace/util/pretty.rb +18 -0
  132. data/lib/terraspace/version.rb +1 -1
  133. data/spec/fixtures/fetcher/c1.json +37 -0
  134. data/spec/fixtures/parser/cache_dirs/all/01-test.auto.tfvars +5 -0
  135. data/spec/fixtures/parser/cache_dirs/depends_on/01-test.auto.tfvars +2 -0
  136. data/spec/fixtures/parser/cache_dirs/output/01-test.auto.tfvars +2 -0
  137. data/spec/fixtures/summary/down.log +12 -0
  138. data/spec/fixtures/summary/output.log +5 -0
  139. data/spec/fixtures/summary/plan/error.log +20 -0
  140. data/spec/fixtures/summary/plan/success.log +17 -0
  141. data/spec/fixtures/summary/show.log +22 -0
  142. data/spec/fixtures/summary/up/error.log +13 -0
  143. data/spec/fixtures/summary/up/success.log +63 -0
  144. data/spec/fixtures/summary/validate/error.log +13 -0
  145. data/spec/fixtures/summary/validate/success.log +5 -0
  146. data/spec/terraspace/all/grapher_spec.rb +38 -0
  147. data/spec/terraspace/all/runner_spec.rb +48 -0
  148. data/spec/terraspace/all/summary_spec.rb +93 -0
  149. data/spec/terraspace/dependency/graph_spec.rb +162 -0
  150. data/spec/terraspace/seeder_spec.rb +0 -1
  151. data/spec/terraspace/terraform/remote_state/fetcher_spec.rb +52 -0
  152. data/terraspace.gemspec +5 -1
  153. metadata +179 -6
  154. data/lib/terraspace/cli/help/update.md +0 -5
  155. data/lib/terraspace/terraform/cloud.rb +0 -25
  156. data/lib/terraspace/util/sh.rb +0 -19
@@ -0,0 +1,40 @@
1
+ ## Example
2
+
3
+ $ terraspace new project infra --plugin aws --examples
4
+ => Creating new project called infra.
5
+ create infra
6
+ create infra/.gitignore
7
+ create infra/Gemfile
8
+ create infra/README.md
9
+ create infra/Terrafile
10
+ create infra/config/app.rb
11
+ exist infra
12
+ create infra/config/terraform/backend.tf
13
+ create infra/config/terraform/provider.tf
14
+ => Creating test for new module: example
15
+ create infra/app/modules/example
16
+ create infra/app/modules/example/main.tf
17
+ create infra/app/modules/example/outputs.tf
18
+ create infra/app/modules/example/variables.tf
19
+ => Creating new stack called demo.
20
+ create infra/app/stacks/demo
21
+ create infra/app/stacks/demo/main.tf
22
+ create infra/app/stacks/demo/outputs.tf
23
+ create infra/app/stacks/demo/variables.tf
24
+ => Creating test bootstrap structure
25
+ exist infra
26
+ create infra/.rspec
27
+ create infra/spec/spec_helper.rb
28
+ => Installing dependencies with: bundle install
29
+ Bundle complete! 3 Gemfile dependencies, 88 gems now installed.
30
+ Use `bundle info [gemname]` to see where a bundled gem is installed.
31
+ ================================================================
32
+ Congrats! You have successfully created a terraspace project.
33
+ Check out the created files. Adjust to the examples and then deploy with:
34
+
35
+ cd infra
36
+ terraspace up demo -y # to deploy
37
+ terraspace down demo -y # to destroy
38
+
39
+ More info: https://terraspace.cloud/
40
+ $
@@ -0,0 +1,8 @@
1
+ ## Example
2
+
3
+ $ terraspace new project_test demo
4
+ => Creating project test: demo
5
+ exist
6
+ create spec/fixtures/tfvars/demo.tfvars
7
+ create spec/stacks/demo/main_spec.rb
8
+ $
@@ -0,0 +1,21 @@
1
+ ## Example
2
+
3
+ $ terraspace new shim
4
+ A terraspace shim as been generated at /usr/local/bin/terraspace
5
+ Please make sure that it is found in the $PATH.
6
+
7
+ You can double check with:
8
+
9
+ which terraspace
10
+
11
+ You should see
12
+
13
+ $ which terraspace
14
+ /usr/local/bin/terraspace
15
+
16
+ If you do not, please add /usr/local/bin to your PATH.
17
+ You can usually do so by adding this line to ~/.bash_profile and opening a new terminal to check.
18
+
19
+ export PATH=/usr/local/bin:/$PATH
20
+
21
+ $
@@ -0,0 +1,9 @@
1
+ ## Example
2
+
3
+ $ terraspace new stack demo
4
+ => Creating new stack called demo.
5
+ create app/stacks/demo
6
+ create app/stacks/demo/main.tf
7
+ create app/stacks/demo/outputs.tf
8
+ create app/stacks/demo/variables.tf
9
+ $
@@ -0,0 +1,6 @@
1
+ ## Example
2
+
3
+ $ terraspace output demo
4
+ => terraform output
5
+ bucket_name = bucket-fond-sheep
6
+ $
@@ -0,0 +1,29 @@
1
+ ## Example
2
+
3
+ $ terraspace plan demo
4
+ => terraform plan
5
+ Refreshing Terraform state in-memory prior to plan...
6
+ The refreshed state will be used to calculate this plan, but will not be
7
+ persisted to local or remote state storage.
8
+
9
+ random_pet.this: Refreshing state... [id=fond-sheep]
10
+ module.bucket.aws_s3_bucket.this: Refreshing state... [id=bucket-fond-sheep]
11
+
12
+ ------------------------------------------------------------------------
13
+
14
+ An execution plan has been generated and is shown below.
15
+ Resource actions are indicated with the following symbols:
16
+ -/+ destroy and then create replacement
17
+ ...
18
+ Plan: 2 to add, 0 to change, 2 to destroy.
19
+
20
+ Changes to Outputs:
21
+ ~ bucket_name = "bucket-fond-sheep" -> (known after apply)
22
+
23
+ ------------------------------------------------------------------------
24
+
25
+ Note: You didn't specify an "-out" parameter to save this plan, so Terraform
26
+ can't guarantee that exactly these actions will be performed if
27
+ "terraform apply" is subsequently run.
28
+
29
+ $
@@ -0,0 +1,18 @@
1
+ ## Example
2
+
3
+ $ terraspace providers demo
4
+ => terraform providers
5
+
6
+ Providers required by configuration:
7
+ .
8
+ ├── provider[registry.terraform.io/hashicorp/random]
9
+ └── module.bucket
10
+ └── provider[registry.terraform.io/hashicorp/aws]
11
+
12
+ Providers required by state:
13
+
14
+ provider[registry.terraform.io/hashicorp/aws]
15
+
16
+ provider[registry.terraform.io/hashicorp/random]
17
+
18
+ $
@@ -0,0 +1,11 @@
1
+ ## Example
2
+
3
+ $ terraspace refresh demo
4
+ => terraform refresh
5
+ random_pet.this: Refreshing state... [id=fond-sheep]
6
+ module.bucket.aws_s3_bucket.this: Refreshing state... [id=bucket-fond-sheep]
7
+
8
+ Outputs:
9
+
10
+ bucket_name = bucket-fond-sheep
11
+ $
@@ -0,0 +1,7 @@
1
+ ## Example
2
+
3
+ $ terraspace seed demo
4
+ Seeding tfvar files for demo
5
+ Reading: .terraspace-cache/us-west-2/dev/stacks/demo/variables.tf
6
+ create app/stacks/demo/tfvars/dev.tfvars
7
+ $
@@ -0,0 +1,36 @@
1
+ ## Example
2
+
3
+ $ terraspace show demo
4
+ => terraform show
5
+ # random_pet.this:
6
+ resource "random_pet" "this" {
7
+ id = "fond-sheep"
8
+ length = 2
9
+ separator = "-"
10
+ }
11
+
12
+ # module.bucket.aws_s3_bucket.this:
13
+ resource "aws_s3_bucket" "this" {
14
+ acl = "private"
15
+ arn = "arn:aws:s3:::bucket-fond-sheep"
16
+ bucket = "bucket-fond-sheep"
17
+ bucket_domain_name = "bucket-fond-sheep.s3.amazonaws.com"
18
+ bucket_regional_domain_name = "bucket-fond-sheep.s3.us-west-2.amazonaws.com"
19
+ force_destroy = false
20
+ hosted_zone_id = "Z3BJ6K6RIION7M"
21
+ id = "bucket-fond-sheep"
22
+ region = "us-west-2"
23
+ request_payer = "BucketOwner"
24
+ tags = {}
25
+
26
+ versioning {
27
+ enabled = false
28
+ mfa_delete = false
29
+ }
30
+ }
31
+
32
+
33
+ Outputs:
34
+
35
+ bucket_name = "bucket-fond-sheep"
36
+ $
@@ -0,0 +1,11 @@
1
+ ## Example
2
+
3
+ $ terraspace summary
4
+ Summary of resources based on backend storage statefiles
5
+ Downloading statefiles to /tmp/terraspace/statefiles/terraform-state-111111111111-us-west-2-dev/us-west-2/dev/
6
+ stacks/demo/terraform.tfstate
7
+ random_pet this: sunny-chicken
8
+ aws_s3_bucket this: bucket-sunny-chicken
9
+ $
10
+
11
+ Also, check out `terraspace all show`.
@@ -0,0 +1,35 @@
1
+ ## Example
2
+
3
+ Terraspace test just calls the configured test framework, by default, rspec.
4
+ Here's an example with output cleaned up to reduce noise:
5
+
6
+ $ terraspace test
7
+ => rspec
8
+
9
+ main
10
+ Building test harness...
11
+ ...
12
+ Test harness built: /tmp/terraspace/test-harnesses/demo-harness
13
+ => terraspace up demo -y
14
+ Building .terraspace-cache/us-west-2/test/stacks/demo
15
+ Built in .terraspace-cache/us-west-2/test/stacks/demo
16
+ Current directory: .terraspace-cache/us-west-2/test/stacks/demo
17
+ => terraform init -get >> /tmp/terraspace/log/init/demo.log
18
+ => terraform plan -out /tmp/terraspace/plans/demo-20200920160313.plan
19
+ ...
20
+ => terraform apply -auto-approve /tmp/terraspace/plans/demo-20200920160313.plan
21
+ ...
22
+ => terraform destroy -auto-approve
23
+ random_pet.this: Refreshing state... [id=hopelessly-outgoing-serval]
24
+ module.bucket.aws_s3_bucket.this: Refreshing state... [id=bucket-hopelessly-outgoing-serval]
25
+ module.bucket.aws_s3_bucket.this: Destroying... [id=bucket-hopelessly-outgoing-serval]
26
+ module.bucket.aws_s3_bucket.this: Destruction complete after 0s
27
+ random_pet.this: Destroying... [id=hopelessly-outgoing-serval]
28
+ random_pet.this: Destruction complete after 0s
29
+
30
+ Destroy complete! Resources: 2 destroyed.
31
+ Time took: 5s
32
+
33
+ Finished in 22.08 seconds (files took 0.48602 seconds to load)
34
+ 1 example, 0 failures
35
+ $
@@ -0,0 +1,30 @@
1
+ ## Example
2
+
3
+ $ terraspace up demo
4
+ Building .terraspace-cache/us-west-2/dev/stacks/demo
5
+ Built in .terraspace-cache/us-west-2/dev/stacks/demo
6
+ Current directory: .terraspace-cache/us-west-2/dev/stacks/demo
7
+ => terraform apply
8
+ ...
9
+ Plan: 2 to add, 0 to change, 0 to destroy.
10
+
11
+ Changes to Outputs:
12
+ + bucket_name = (known after apply)
13
+
14
+ Do you want to perform these actions?
15
+ Terraform will perform the actions described above.
16
+ Only 'yes' will be accepted to approve.
17
+ Enter a value: yes
18
+
19
+ random_pet.this: Creating...
20
+ random_pet.this: Creation complete after 0s [id=trusty-marmoset]
21
+ module.bucket.aws_s3_bucket.this: Creating...
22
+ module.bucket.aws_s3_bucket.this: Creation complete after 2s [id=bucket-trusty-marmoset]
23
+
24
+ Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
25
+
26
+ Outputs:
27
+
28
+ bucket_name = bucket-trusty-marmoset
29
+ Time took: 39s
30
+ $
@@ -0,0 +1,9 @@
1
+ ## Example
2
+
3
+ $ terraspace validate demo
4
+ Building .terraspace-cache/us-west-2/dev/stacks/demo
5
+ Built in .terraspace-cache/us-west-2/dev/stacks/demo
6
+ Current directory: .terraspace-cache/us-west-2/dev/stacks/demo
7
+ => terraform validate
8
+ Success! The configuration is valid.
9
+ $
@@ -3,26 +3,14 @@ class Terraspace::CLI
3
3
  extend Memoist
4
4
 
5
5
  def run
6
- format = @options[:format] || "text"
7
- send("#{format}_output")
8
- end
9
-
10
- def json_output
11
- puts JSON.pretty_generate(info)
12
- end
13
-
14
- def text_output
6
+ presenter = CliFormat::Presenter.new(@options)
7
+ presenter.header = %w[Name Value]
15
8
  info.each do |k,v|
16
- k = "%-#{rpad}s" % k
17
- puts "#{k} #{v}"
9
+ presenter.rows << [k, v]
18
10
  end
11
+ presenter.show
19
12
  end
20
13
 
21
- def rpad
22
- info.keys.map(&:size).max
23
- end
24
- memoize :rpad
25
-
26
14
  def info
27
15
  @mod.to_info
28
16
  end
@@ -10,13 +10,14 @@ class Terraspace::CLI
10
10
  end
11
11
 
12
12
  def run
13
- init if init?
14
- build_remote_dependencies # runs after terraform init, which downloads remote modules
13
+ init
14
+ # build_remote_dependencies # runs after terraform init, which downloads remote modules
15
15
  sync_cloud
16
16
  end
17
17
 
18
18
  # Note the init will always create the Terraform Cloud Workspace
19
19
  def init
20
+ return unless run_init? # check here because RemoteState::Fetcher#pull calls init directly
20
21
  # default init timeout is pretty generous in case of slow internet to download the provider plugins
21
22
  init_timeout = Integer(ENV['TS_INIT_TIMEOUT'] || 600)
22
23
  Timeout::timeout(init_timeout) do
@@ -28,7 +29,7 @@ class Terraspace::CLI
28
29
  end
29
30
 
30
31
  def sync_cloud
31
- Terraspace::Terraform::Cloud.new(@options).run if %w[apply plan destroy cloud-setup].include?(@calling_command)
32
+ Terraspace::Terraform::Cloud::Sync.new(@options).run if %w[apply plan destroy cloud-setup].include?(@calling_command)
32
33
  end
33
34
 
34
35
  # Currently only handles remote modules only one-level deep.
@@ -47,8 +48,8 @@ class Terraspace::CLI
47
48
  return if local_source?(meta["Source"])
48
49
  return if meta['Dir'] == '.' # root is already built
49
50
 
50
- remote_mod = Mod::Remote.new(meta, @mod)
51
- Compiler::Builder.new(remote_mod).build
51
+ remote_mod = Terraspace::Mod::Remote.new(meta, @mod)
52
+ Terraspace::Compiler::Builder.new(remote_mod).build
52
53
  end
53
54
 
54
55
  def auto?
@@ -60,8 +61,35 @@ class Terraspace::CLI
60
61
  s =~ %r{^\.} || s =~ %r{^/}
61
62
  end
62
63
 
63
- def init?
64
- %w[apply console destroy output plan providers refresh show validate cloud-setup].include?(@calling_command)
64
+ def run_init?
65
+ commands = %w[apply console destroy output plan providers refresh show validate cloud-setup]
66
+ return false unless commands.include?(@calling_command)
67
+ mode = ENV['TS_INIT_MODE'] || Terraspace.config.init.mode
68
+ case mode.to_sym
69
+ when :auto
70
+ !already_initialized?
71
+ when :always
72
+ true
73
+ when :never
74
+ false
75
+ end
76
+ end
77
+
78
+ # Would like to improve this detection
79
+ #
80
+ # Traverse symlink dirs also: linux_amd64 is a symlink
81
+ # plugins/registry.terraform.io/hashicorp/google/3.39.0/linux_amd64/terraform-provider-google_v3.39.0_x5
82
+ #
83
+ # Check modules/modules.json also because during the tfvars dependency pass main.tf modules are not built.
84
+ # So init happens again during the second pass.
85
+ #
86
+ def already_initialized?
87
+ terraform = "#{@mod.cache_dir}/.terraform"
88
+ provider = Dir.glob("#{terraform}/**{,/*/**}/*").find do |path|
89
+ path.include?("terraform-provider-")
90
+ end
91
+ modules = File.exist?("#{terraform}/modules/modules.json")
92
+ !!(provider && modules)
65
93
  end
66
94
  end
67
95
  end
@@ -2,11 +2,24 @@ class Terraspace::CLI
2
2
  class List
3
3
  def initialize(options={})
4
4
  @options = options
5
+ @type_dir = normalized_type
5
6
  end
6
7
 
7
8
  def run
8
9
  Dir.glob("{app,vendor}/{modules,stacks}/*").sort.each do |path|
9
- puts path
10
+ if @type_dir
11
+ puts path if path.include?("/#{@type_dir}/")
12
+ else
13
+ puts path
14
+ end
15
+ end
16
+ end
17
+
18
+ private
19
+ def normalized_type
20
+ type = @options[:type]
21
+ if %w[stack module].include?(type)
22
+ type.pluralize
10
23
  end
11
24
  end
12
25
  end
@@ -0,0 +1,112 @@
1
+ require "eventmachine"
2
+ require "eventmachine-tail"
3
+
4
+ class Terraspace::CLI
5
+ class Log < Base
6
+ include Log::Concern
7
+
8
+ def initialize(options={})
9
+ super
10
+ @action, @stack = options[:action], options[:stack]
11
+ @action ||= '**'
12
+ @stack ||= '*'
13
+ end
14
+
15
+ def run
16
+ check_logs!
17
+ if @options[:follow]
18
+ follow_logs
19
+ else
20
+ all_log_paths.each { |path| show_log(path) }
21
+ end
22
+ end
23
+
24
+ def follow_logs
25
+ glob_path = "#{Terraspace.log_root}/#{@action}/#{@stack}.log"
26
+ Dir.glob(glob_path).each do |path|
27
+ puts "Following #{pretty(path)}".color(:purple)
28
+ end
29
+ EventMachine.run do
30
+ interval = Integer(ENV['TS_LOG_GLOB_INTERNAL'] || 1)
31
+ EventMachine::FileGlobWatchTail.new(glob_path, nil, interval) do |filetail, line|
32
+ puts line # always show timestamp in follow mode
33
+ end
34
+ end
35
+ end
36
+
37
+ def show_log(path)
38
+ report_log(path)
39
+ lines = readlines(path)
40
+ lines = apply_limit(lines)
41
+ lines.each do |line|
42
+ puts format(line)
43
+ end
44
+ end
45
+
46
+ def report_log(path)
47
+ pretty_path = pretty(path)
48
+ if File.exist?(path)
49
+ puts "Showing: #{pretty_path}".color(:purple)
50
+ end
51
+ end
52
+
53
+ def format(line)
54
+ if timestamps
55
+ line
56
+ else
57
+ line.sub(/.*\]: /,'')
58
+ end
59
+ end
60
+
61
+ def all_log_paths
62
+ Dir.glob("#{Terraspace.log_root}/#{@action}/#{@stack}.log")
63
+ end
64
+
65
+ def check_logs!
66
+ return unless all_log_paths.empty?
67
+ puts "WARN: No logs found".color(:yellow)
68
+ end
69
+
70
+ # Only need to check if both action and stack are provided. Otherwise the Dir.globs are used to discover the files
71
+ def check_log!
72
+ return unless single_log?
73
+ path = "#{Terraspace.log_root}/#{@action}/#{@stack}.log"
74
+ return if File.exist?(path)
75
+ puts "ERROR: Log file was not found: #{pretty(path)}".color(:red)
76
+ exit 1
77
+ end
78
+
79
+ def single_log?
80
+ @action != '**' && @stack != '*'
81
+ end
82
+
83
+ def apply_limit(lines)
84
+ return lines if all
85
+ left = limit * -1
86
+ lines[left..-1] || []
87
+ end
88
+
89
+ def all
90
+ if single_log?
91
+ @options[:all].nil? ? true : @options[:all]
92
+ else # multiple
93
+ @options[:all].nil? ? false : @options[:all]
94
+ end
95
+ end
96
+
97
+ def limit
98
+ @options[:limit].nil? ? 10 : @options[:limit]
99
+ end
100
+
101
+ def timestamps
102
+ if single_log?
103
+ @options[:timestamps].nil? ? false : @options[:timestamps]
104
+ else
105
+ @options[:timestamps].nil? ? true : @options[:timestamps]
106
+ end
107
+ end
108
+ def pretty(path)
109
+ Terraspace::Util.pretty_path(path)
110
+ end
111
+ end
112
+ end