terraspace 0.4.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/lib/templates/base/arg/terraform.rb.tt +3 -0
  4. data/lib/templates/base/helper/%name%_helper.rb.tt +2 -0
  5. data/lib/templates/base/hook/%kind%.rb.tt +7 -0
  6. data/lib/terraspace.rb +4 -3
  7. data/lib/terraspace/all/base.rb +0 -1
  8. data/lib/terraspace/app.rb +1 -0
  9. data/lib/terraspace/autoloader.rb +20 -3
  10. data/lib/terraspace/cli/bundle.rb +0 -1
  11. data/lib/terraspace/cli/clean/base.rb +0 -1
  12. data/lib/terraspace/cli/clean/cache.rb +0 -1
  13. data/lib/terraspace/cli/help/new/arg.md +19 -0
  14. data/lib/terraspace/cli/help/new/helper.md +39 -0
  15. data/lib/terraspace/cli/help/new/hook.md +25 -0
  16. data/lib/terraspace/cli/help/new/test.md +34 -0
  17. data/lib/terraspace/cli/new.rb +22 -16
  18. data/lib/terraspace/cli/new/arg.rb +62 -0
  19. data/lib/terraspace/cli/new/helper.rb +44 -12
  20. data/lib/terraspace/cli/new/helpers.rb +22 -0
  21. data/lib/terraspace/cli/new/helpers/plugin_gem.rb +25 -0
  22. data/lib/terraspace/cli/new/hook.rb +70 -0
  23. data/lib/terraspace/cli/new/module.rb +0 -11
  24. data/lib/terraspace/cli/new/plugin.rb +4 -4
  25. data/lib/terraspace/cli/new/plugin/helper.rb +1 -1
  26. data/lib/terraspace/cli/new/project.rb +16 -7
  27. data/lib/terraspace/cli/new/sequence.rb +3 -10
  28. data/lib/terraspace/cli/new/source/core.rb +1 -1
  29. data/lib/terraspace/cli/new/stack.rb +1 -12
  30. data/lib/terraspace/cli/new/test.rb +50 -0
  31. data/lib/terraspace/cli/summary.rb +0 -1
  32. data/lib/terraspace/command.rb +16 -0
  33. data/lib/terraspace/compiler/builder.rb +2 -0
  34. data/lib/terraspace/compiler/dsl/mod.rb +2 -0
  35. data/lib/terraspace/compiler/dsl/syntax/mod.rb +2 -0
  36. data/lib/terraspace/compiler/dsl/syntax/mod/backend.rb +1 -1
  37. data/lib/terraspace/compiler/erb/context.rb +2 -0
  38. data/lib/terraspace/compiler/helper_extender.rb +27 -0
  39. data/lib/terraspace/core.rb +0 -6
  40. data/lib/terraspace/ext/core/module.rb +16 -0
  41. data/lib/terraspace/hooks/builder.rb +6 -7
  42. data/lib/terraspace/hooks/concern.rb +2 -2
  43. data/lib/terraspace/logger.rb +6 -0
  44. data/lib/terraspace/mod.rb +0 -1
  45. data/lib/terraspace/plugin.rb +8 -4
  46. data/lib/terraspace/plugin/config/interface.rb +2 -2
  47. data/lib/terraspace/plugin/helper/interface.rb +31 -0
  48. data/lib/terraspace/terraform/args/custom.rb +2 -3
  49. data/lib/terraspace/terraform/runner/retryer.rb +7 -3
  50. data/lib/terraspace/version.rb +1 -1
  51. data/spec/terraspace/terraform/args/custom_spec.rb +6 -4
  52. data/terraspace.gemspec +4 -4
  53. metadata +27 -21
  54. data/lib/terraspace/cli/help/new/bootstrap_test.md +0 -8
  55. data/lib/terraspace/cli/help/new/module_test.md +0 -12
  56. data/lib/terraspace/cli/help/new/project_test.md +0 -8
  57. data/lib/terraspace/cli/new/helper/plugin_gem.rb +0 -12
  58. data/lib/terraspace/cli/new/test/base.rb +0 -17
  59. data/lib/terraspace/cli/new/test/bootstrap.rb +0 -18
  60. data/lib/terraspace/cli/new/test/module.rb +0 -15
  61. data/lib/terraspace/cli/new/test/project.rb +0 -15
@@ -51,11 +51,5 @@ module Terraspace
51
51
  def logger=(v)
52
52
  @@logger = v
53
53
  end
54
-
55
- def check_project!
56
- return if File.exist?("#{Terraspace.root}/config/app.rb")
57
- logger.error "ERROR: It doesnt look like this is a terraspace project. Are you sure you are in a terraspace project?".color(:red)
58
- ENV['TS_TEST'] ? raise : exit(1)
59
- end
60
54
  end
61
55
  end
@@ -16,4 +16,20 @@ class Module
16
16
  include klass.constantize
17
17
  end
18
18
  end
19
+
20
+ def include_project_level_helpers
21
+ full_dir = "#{Terraspace.root}/config/helpers"
22
+ Dir.glob("#{full_dir}/**/*").each do |path|
23
+ regexp = Regexp.new(".*/config/helpers/")
24
+ klass = path.sub(regexp, '').sub('.rb','').camelize
25
+ klass = "Terraspace::Project::#{klass}"
26
+ include klass.constantize
27
+ end
28
+ end
29
+
30
+ def include_plugin_helpers
31
+ Terraspace::Plugin.helper_classes.each do |klass|
32
+ include klass # IE: TerraspacePluginAws::Interfaces::Helper
33
+ end
34
+ end
19
35
  end
@@ -7,14 +7,14 @@ module Terraspace::Hooks
7
7
 
8
8
  # IE: dsl_file: config/hooks/terraform.rb
9
9
  attr_accessor :name
10
- def initialize(mod, dsl_file, name)
11
- @mod, @dsl_file, @name = mod, dsl_file, name
10
+ def initialize(mod, file, name)
11
+ @mod, @file, @name = mod, file, name
12
12
  @hooks = {before: {}, after: {}}
13
13
  end
14
14
 
15
15
  def build
16
- return @hooks unless File.exist?(@dsl_file)
17
- evaluate_file(@dsl_file)
16
+ evaluate_file("#{Terraspace.root}/config/hooks/#{@file}")
17
+ evaluate_file("#{@mod.root}/config/hooks/#{@file}")
18
18
  @hooks.deep_stringify_keys!
19
19
  end
20
20
  memoize :build
@@ -37,11 +37,10 @@ module Terraspace::Hooks
37
37
  def run_hook(type, hook)
38
38
  return unless run?(hook)
39
39
 
40
- command = File.basename(@dsl_file).sub('.rb','') # IE: kubes, kubectl, docker
40
+ command = File.basename(@file).sub('.rb','') # IE: terraform or terraspace
41
41
  id = "#{command} #{type} #{@name}"
42
42
  label = " label: #{hook["label"]}" if hook["label"]
43
- logger.info "Running #{id} hook.#{label}"
44
- logger.debug "Hook options: #{hook}"
43
+ logger.info "Hook: Running #{id} hook.#{label}".color(:cyan)
45
44
  Runner.new(@mod, hook).run
46
45
  end
47
46
 
@@ -1,7 +1,7 @@
1
1
  module Terraspace::Hooks
2
2
  module Concern
3
- def run_hooks(dsl_file, name, &block)
4
- hooks = Builder.new(@mod, "#{Terraspace.root}/config/hooks/#{dsl_file}", name)
3
+ def run_hooks(file, name, &block)
4
+ hooks = Builder.new(@mod, file, name)
5
5
  hooks.build # build hooks
6
6
  hooks.run_hooks(&block)
7
7
  end
@@ -2,6 +2,12 @@ require 'logger'
2
2
 
3
3
  module Terraspace
4
4
  class Logger < ::Logger
5
+ def initialize(*args)
6
+ super
7
+ self.formatter = Formatter.new
8
+ self.level = :info
9
+ end
10
+
5
11
  def format_message(severity, datetime, progname, msg)
6
12
  line = if @logdev.dev == $stdout || @logdev.dev == $stderr
7
13
  msg # super simple format if stdout
@@ -31,7 +31,6 @@ module Terraspace
31
31
  end
32
32
 
33
33
  def check_exist!
34
- Terraspace.check_project!
35
34
  return if root
36
35
 
37
36
  pretty_paths = paths.map { |p| Terraspace::Util.pretty_path(p) }.join(", ")
@@ -16,14 +16,18 @@ module Terraspace
16
16
  @@meta
17
17
  end
18
18
 
19
- def layer_classes
20
- @@meta.map { |plugin, data| data[:layer_class] }.compact
21
- end
22
-
23
19
  def config_classes
24
20
  @@meta.map { |plugin, data| data[:config_class] }.compact
25
21
  end
26
22
 
23
+ def helper_classes
24
+ @@meta.map { |plugin, data| data[:helper_class] }.compact
25
+ end
26
+
27
+ def layer_classes
28
+ @@meta.map { |plugin, data| data[:layer_class] }.compact
29
+ end
30
+
27
31
  # The resource map can be used to customized the mapping from the resource "first word" to the plugin.
28
32
  #
29
33
  # resource map is in meta structure.
@@ -16,8 +16,8 @@ module Terraspace::Plugin::Config
16
16
  end
17
17
 
18
18
  def load_project_config
19
- project_config = "#{Terraspace.root}/config/plugins/#{provider}.rb"
20
- evaluate_file(project_config)
19
+ evaluate_file("#{Terraspace.root}/config/plugins/#{provider}.rb")
20
+ evaluate_file("#{Terraspace.root}/config/plugins/#{provider}/#{Terraspace.env}.rb")
21
21
  end
22
22
 
23
23
  def configure
@@ -0,0 +1,31 @@
1
+ module Terraspace::Plugin::Helper
2
+ module Interface
3
+ extend ActiveSupport::Concern
4
+
5
+ # Useful for plugin helpers. Can check this only run logic after dependency resolution.
6
+ def resolved?
7
+ !!@mod.resolved
8
+ end
9
+
10
+ class_methods do
11
+ @@helper_cache = {}
12
+ # This method is useful to avoid double call of heavy processing logic for tfvars,
13
+ # since the tfvars files get evaluated twice.
14
+ # Note: Not setting any cache or doing any logic unless resolved.
15
+ def cache_helper(meth)
16
+ uncached_meth = "uncached_#{meth}"
17
+ alias_method(uncached_meth, meth)
18
+ define_method(meth) do |*args|
19
+ return unless resolved? # return nil in first unresolved pass
20
+ id = Marshal.dump([meth] + args)
21
+ exist = @@helper_cache.key?(id)
22
+ if exist
23
+ @@helper_cache[id]
24
+ else
25
+ @@helper_cache[id] = send(uncached_meth, *args)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -7,13 +7,12 @@ module Terraspace::Terraform::Args
7
7
  attr_accessor :name
8
8
  def initialize(mod, name)
9
9
  @mod, @name = mod, name
10
- @file = "#{Terraspace.root}/config/args/terraform.rb"
11
10
  @commands = {}
12
11
  end
13
12
 
14
13
  def build
15
- return @commands unless File.exist?(@file)
16
- evaluate_file(@file)
14
+ evaluate_file("#{Terraspace.root}/config/args/terraform.rb")
15
+ evaluate_file("#{@mod.root}/config/args/terraform.rb")
17
16
  @commands.deep_stringify_keys!
18
17
  end
19
18
  memoize :build
@@ -9,7 +9,7 @@ class Terraspace::Terraform::Runner
9
9
  end
10
10
 
11
11
  def retry?
12
- if @retries <= 3
12
+ if @retries <= 3 && !@stop_retrying
13
13
  true # will retry
14
14
  else
15
15
  logger.info "ERROR: #{@exception.message}"
@@ -36,8 +36,12 @@ class Terraspace::Terraform::Runner
36
36
  logger.debug "Retry attempt: #{@retries}"
37
37
  logger.debug "#{@exception.class}"
38
38
  logger.debug "#{@exception.message}"
39
- purge_caches # Purging the cache "fixes" this terraform bug
40
- reinit
39
+ if Terraspace.config.terraform.plugin_cache.purge_on_error # Purging the cache "fixes" this terraform bug
40
+ purge_caches
41
+ reinit
42
+ else
43
+ @stop_retrying = true
44
+ end
41
45
  end
42
46
 
43
47
  def init_required_error
@@ -1,3 +1,3 @@
1
1
  module Terraspace
2
- VERSION = "0.4.4"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -10,17 +10,18 @@ describe Terraspace::Terraform::Args::Custom do
10
10
  let(:file) { fixture("terraform/args/single.rb") }
11
11
  let(:name) { "apply" }
12
12
  it "build creates the @commands structure" do
13
+ custom.evaluate_file(file)
13
14
  commands = custom.build
14
15
  expect(commands.keys).to include("apply")
15
16
  end
16
17
 
17
18
  it "args" do
18
- custom.build
19
+ custom.evaluate_file(file)
19
20
  expect(custom.args).to eq(["-lock-timeout=20m"])
20
21
  end
21
22
 
22
23
  it "var_files" do
23
- custom.build
24
+ custom.evaluate_file(file)
24
25
  allow(custom).to receive(:var_file_exist?).and_return(true)
25
26
  expect(custom.var_files).to eq(["-var-file=a.tfvars", "-var-file=b.tfvars"])
26
27
  end
@@ -30,17 +31,18 @@ describe Terraspace::Terraform::Args::Custom do
30
31
  let(:file) { fixture("terraform/args/multiple.rb") }
31
32
  let(:name) { "apply" }
32
33
  it "build creates the @commands structure" do
34
+ custom.evaluate_file(file)
33
35
  commands = custom.build
34
36
  expect(commands.keys).to include("apply")
35
37
  end
36
38
 
37
39
  it "args" do
38
- custom.build
40
+ custom.evaluate_file(file)
39
41
  expect(custom.args).to eq(["-lock-timeout=20m"])
40
42
  end
41
43
 
42
44
  it "var_files" do
43
- custom.build
45
+ custom.evaluate_file(file)
44
46
  allow(custom).to receive(:var_file_exist?).and_return(true)
45
47
  expect(custom.var_files).to eq([])
46
48
  end
@@ -34,10 +34,10 @@ Gem::Specification.new do |spec|
34
34
  spec.add_dependency "zeitwerk"
35
35
 
36
36
  # core baseline plugins
37
- spec.add_dependency "terraspace_plugin_aws", "~> 0.2.0"
38
- spec.add_dependency "terraspace_plugin_azurerm", "~> 0.2.0"
39
- spec.add_dependency "terraspace_plugin_google", "~> 0.2.0"
40
- spec.add_dependency "rspec-terraspace"
37
+ spec.add_dependency "terraspace_plugin_aws", "~> 0.3.0"
38
+ spec.add_dependency "terraspace_plugin_azurerm", "~> 0.3.0"
39
+ spec.add_dependency "terraspace_plugin_google", "~> 0.3.0"
40
+ spec.add_dependency "rspec-terraspace", "~> 0.2.0"
41
41
 
42
42
  spec.add_development_dependency "bundler"
43
43
  spec.add_development_dependency "byebug"
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.4.4
4
+ version: 0.5.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: 2020-11-02 00:00:00.000000000 Z
11
+ date: 2020-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -212,56 +212,56 @@ dependencies:
212
212
  requirements:
213
213
  - - "~>"
214
214
  - !ruby/object:Gem::Version
215
- version: 0.2.0
215
+ version: 0.3.0
216
216
  type: :runtime
217
217
  prerelease: false
218
218
  version_requirements: !ruby/object:Gem::Requirement
219
219
  requirements:
220
220
  - - "~>"
221
221
  - !ruby/object:Gem::Version
222
- version: 0.2.0
222
+ version: 0.3.0
223
223
  - !ruby/object:Gem::Dependency
224
224
  name: terraspace_plugin_azurerm
225
225
  requirement: !ruby/object:Gem::Requirement
226
226
  requirements:
227
227
  - - "~>"
228
228
  - !ruby/object:Gem::Version
229
- version: 0.2.0
229
+ version: 0.3.0
230
230
  type: :runtime
231
231
  prerelease: false
232
232
  version_requirements: !ruby/object:Gem::Requirement
233
233
  requirements:
234
234
  - - "~>"
235
235
  - !ruby/object:Gem::Version
236
- version: 0.2.0
236
+ version: 0.3.0
237
237
  - !ruby/object:Gem::Dependency
238
238
  name: terraspace_plugin_google
239
239
  requirement: !ruby/object:Gem::Requirement
240
240
  requirements:
241
241
  - - "~>"
242
242
  - !ruby/object:Gem::Version
243
- version: 0.2.0
243
+ version: 0.3.0
244
244
  type: :runtime
245
245
  prerelease: false
246
246
  version_requirements: !ruby/object:Gem::Requirement
247
247
  requirements:
248
248
  - - "~>"
249
249
  - !ruby/object:Gem::Version
250
- version: 0.2.0
250
+ version: 0.3.0
251
251
  - !ruby/object:Gem::Dependency
252
252
  name: rspec-terraspace
253
253
  requirement: !ruby/object:Gem::Requirement
254
254
  requirements:
255
- - - ">="
255
+ - - "~>"
256
256
  - !ruby/object:Gem::Version
257
- version: '0'
257
+ version: 0.2.0
258
258
  type: :runtime
259
259
  prerelease: false
260
260
  version_requirements: !ruby/object:Gem::Requirement
261
261
  requirements:
262
- - - ">="
262
+ - - "~>"
263
263
  - !ruby/object:Gem::Version
264
- version: '0'
264
+ version: 0.2.0
265
265
  - !ruby/object:Gem::Dependency
266
266
  name: bundler
267
267
  requirement: !ruby/object:Gem::Requirement
@@ -385,7 +385,10 @@ files:
385
385
  - README.md
386
386
  - Rakefile
387
387
  - exe/terraspace
388
+ - lib/templates/base/arg/terraform.rb.tt
388
389
  - lib/templates/base/git_hook/hook.sh
390
+ - lib/templates/base/helper/%name%_helper.rb.tt
391
+ - lib/templates/base/hook/%kind%.rb.tt
389
392
  - lib/templates/base/project/.gitignore
390
393
  - lib/templates/base/project/Gemfile.tt
391
394
  - lib/templates/base/project/README.md
@@ -510,16 +513,17 @@ files:
510
513
  - lib/terraspace/cli/help/logs.md
511
514
  - lib/terraspace/cli/help/logs/remove.md
512
515
  - lib/terraspace/cli/help/logs/truncate.md
513
- - lib/terraspace/cli/help/new/bootstrap_test.md
516
+ - lib/terraspace/cli/help/new/arg.md
514
517
  - lib/terraspace/cli/help/new/example.md
515
518
  - lib/terraspace/cli/help/new/git_hook.md
519
+ - lib/terraspace/cli/help/new/helper.md
520
+ - lib/terraspace/cli/help/new/hook.md
516
521
  - lib/terraspace/cli/help/new/module.md
517
- - lib/terraspace/cli/help/new/module_test.md
518
522
  - lib/terraspace/cli/help/new/plugin.md
519
523
  - lib/terraspace/cli/help/new/project.md
520
- - lib/terraspace/cli/help/new/project_test.md
521
524
  - lib/terraspace/cli/help/new/shim.md
522
525
  - lib/terraspace/cli/help/new/stack.md
526
+ - lib/terraspace/cli/help/new/test.md
523
527
  - lib/terraspace/cli/help/output.md
524
528
  - lib/terraspace/cli/help/plan.md
525
529
  - lib/terraspace/cli/help/providers.md
@@ -536,9 +540,12 @@ files:
536
540
  - lib/terraspace/cli/logs.rb
537
541
  - lib/terraspace/cli/logs/concern.rb
538
542
  - lib/terraspace/cli/new.rb
543
+ - lib/terraspace/cli/new/arg.rb
539
544
  - lib/terraspace/cli/new/git_hook.rb
540
545
  - lib/terraspace/cli/new/helper.rb
541
- - lib/terraspace/cli/new/helper/plugin_gem.rb
546
+ - lib/terraspace/cli/new/helpers.rb
547
+ - lib/terraspace/cli/new/helpers/plugin_gem.rb
548
+ - lib/terraspace/cli/new/hook.rb
542
549
  - lib/terraspace/cli/new/module.rb
543
550
  - lib/terraspace/cli/new/plugin.rb
544
551
  - lib/terraspace/cli/new/plugin/helper.rb
@@ -549,10 +556,7 @@ files:
549
556
  - lib/terraspace/cli/new/source/plugin.rb
550
557
  - lib/terraspace/cli/new/source/test.rb
551
558
  - lib/terraspace/cli/new/stack.rb
552
- - lib/terraspace/cli/new/test/base.rb
553
- - lib/terraspace/cli/new/test/bootstrap.rb
554
- - lib/terraspace/cli/new/test/module.rb
555
- - lib/terraspace/cli/new/test/project.rb
559
+ - lib/terraspace/cli/new/test.rb
556
560
  - lib/terraspace/cli/seed.rb
557
561
  - lib/terraspace/cli/summary.rb
558
562
  - lib/terraspace/cli/test.rb
@@ -590,6 +594,7 @@ files:
590
594
  - lib/terraspace/compiler/erb/helpers.rb
591
595
  - lib/terraspace/compiler/erb/render.rb
592
596
  - lib/terraspace/compiler/expander.rb
597
+ - lib/terraspace/compiler/helper_extender.rb
593
598
  - lib/terraspace/compiler/strategy/abstract_base.rb
594
599
  - lib/terraspace/compiler/strategy/mod.rb
595
600
  - lib/terraspace/compiler/strategy/mod/base.rb
@@ -630,6 +635,7 @@ files:
630
635
  - lib/terraspace/plugin/expander/generic.rb
631
636
  - lib/terraspace/plugin/expander/interface.rb
632
637
  - lib/terraspace/plugin/finder.rb
638
+ - lib/terraspace/plugin/helper/interface.rb
633
639
  - lib/terraspace/plugin/infer_provider.rb
634
640
  - lib/terraspace/plugin/layer/interface.rb
635
641
  - lib/terraspace/plugin/meta.rb
@@ -828,7 +834,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
828
834
  - !ruby/object:Gem::Version
829
835
  version: '0'
830
836
  requirements: []
831
- rubygems_version: 3.1.2
837
+ rubygems_version: 3.1.4
832
838
  signing_key:
833
839
  specification_version: 4
834
840
  summary: 'Terraspace: The Terraspace Framework'
@@ -1,8 +0,0 @@
1
- ## Example
2
-
3
- $ terraspace new bootstrap_test
4
- => Creating test bootstrap structure
5
- exist
6
- create .rspec
7
- create spec/spec_helper.rb
8
- $
@@ -1,12 +0,0 @@
1
- ## Example
2
-
3
- $ terraspace new module_test example
4
- => Creating module test: example
5
- exist app/modules/example
6
- create app/modules/example/test/.rspec
7
- create app/modules/example/test/Gemfile
8
- create app/modules/example/test/spec/fixtures/stack/main.tf
9
- create app/modules/example/test/spec/fixtures/stack/outputs.tf
10
- create app/modules/example/test/spec/main_spec.rb
11
- create app/modules/example/test/spec/spec_helper.rb
12
- $