terraspace 0.6.2 → 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02ed3895b8039e7424e31139ce9f8e20c5d4a60142e8d3da64b5a68ce9e52004
4
- data.tar.gz: 14617bab09a51e8229a209536585b5ff460355ac2c13cef26dd067b37a878cc0
3
+ metadata.gz: 790cbc55c399a3130eaaaa9e1e3af636a2b182cb28c2ca008e14a48d75883e47
4
+ data.tar.gz: 72d05ffb527f163d2b3be47542b77764ddbc599858e6dde6381058e992bc531c
5
5
  SHA512:
6
- metadata.gz: 742c92857e31d85b66e7e232b14facd1745d9a35347e4634732670bd0b011937e4e46bcc7157e83cd9db10025a325004a6b391d21688b1e86c3bacf1ff8e429b
7
- data.tar.gz: c3010333589ed88a15541a563cde963ae6d9e500acf519911966636563dadb9c698db9cb933945bf243d838d45b8c1fdf151f0602c887d9cbea09250069c3fa5
6
+ metadata.gz: a598f6c5e693d42c113a5aac0f4d2e63c41821a2414095ed65415fa6b11ab1636ce48d6a98ada24557c6b685642f1ac420fc9850544bd1cbda80e3de91036d48
7
+ data.tar.gz: f0a0955bbc1f7846e855141514a69b0aaffc81283081a5a90384fb85e4ec7946a65f19fa1dc3ff5df0e7c9f656ac5563fecca2c8a1a1959c83fa29d9daeae4bd
data/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
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.6.7] - 2021-05-05
7
+ - [#108](https://github.com/boltops-tools/terraspace/pull/108) provide runner context to terraspace hook
8
+
9
+ ## [0.6.6] - 2021-04-15
10
+ - [#101](https://github.com/boltops-tools/terraspace/pull/101) terraspace force-unlock command
11
+ - [#102](https://github.com/boltops-tools/terraspace/pull/102) fix terraspace all summarized logging
12
+ - [#103](https://github.com/boltops-tools/terraspace/pull/103) config.build.pass_files with default files use pass strategy
13
+
14
+ ## [0.6.5] - 2021-03-24
15
+ - [#96](https://github.com/boltops-tools/terraspace/pull/96) terraspace fmt: ability to specific module or stack
16
+
17
+ ## [0.6.4] - 2021-03-22
18
+ - [#94](https://github.com/boltops-tools/terraspace/pull/94) terraspace fmt command
19
+
20
+ ## [0.6.3] - 2021-03-12
21
+ - [#91](https://github.com/boltops-tools/terraspace/pull/91) Camelcase
22
+ - [#92](https://github.com/boltops-tools/terraspace/pull/92) disable terraform.plugin_cache by default
23
+ - skip build config/helpers
24
+
6
25
  ## [0.6.2] - 2021-03-05
7
26
  - [#90](https://github.com/boltops-tools/terraspace/pull/90) Boot hooks: new and improved boot hooks interface
8
27
  - remove old config.hooks.on_boot
@@ -104,7 +104,7 @@ module Terraspace::All
104
104
  def run_terraspace(mod_name)
105
105
  set_log_path!(mod_name)
106
106
  name = command_map(@command)
107
- o = @options.merge(mod: mod_name, yes: true, build: false, input: false)
107
+ o = @options.merge(mod: mod_name, yes: true, build: false, input: false, log_to_stderr: true)
108
108
  o.merge!(quiet: false) if @command == "init" # noisy so can filter and summarize output
109
109
  case @command
110
110
  when "up"
@@ -27,6 +27,8 @@ module Terraspace
27
27
  config.build.cache_dir = ":CACHE_ROOT/:REGION/:ENV/:BUILD_DIR"
28
28
  config.build.cache_root = nil # defaults to /full/path/to/.terraspace-cache
29
29
  config.build.clean_cache = nil # defaults to /full/path/to/.terraspace-cache
30
+ config.build.default_pass_files = ["/files/"]
31
+ config.build.pass_files = []
30
32
  config.bundle = ActiveSupport::OrderedOptions.new
31
33
  config.bundle.logger = ts_logger
32
34
  config.init = ActiveSupport::OrderedOptions.new
@@ -45,7 +47,7 @@ module Terraspace
45
47
  config.terraform = ActiveSupport::OrderedOptions.new
46
48
  config.terraform.plugin_cache = ActiveSupport::OrderedOptions.new
47
49
  config.terraform.plugin_cache.dir = ENV['TF_PLUGIN_CACHE_DIR'] || "#{Terraspace.tmp_root}/plugin_cache"
48
- config.terraform.plugin_cache.enabled = true
50
+ config.terraform.plugin_cache.enabled = false
49
51
  config.terraform.plugin_cache.purge_on_error = true
50
52
  config.test_framework = "rspec"
51
53
  config.tfc = ActiveSupport::OrderedOptions.new
@@ -27,6 +27,9 @@ module Terraspace
27
27
  reconfigure_option = Proc.new {
28
28
  option :reconfigure, type: :boolean, desc: "Add terraform -reconfigure option"
29
29
  }
30
+ type_option = Proc.new {
31
+ option :type, default: "stack", aliases: %w[t], desc: "Type: stack, module, or all"
32
+ }
30
33
 
31
34
  desc "all SUBCOMMAND", "all subcommands"
32
35
  long_desc Help.text(:all)
@@ -82,6 +85,20 @@ module Terraspace
82
85
  Down.new(options.merge(mod: mod)).run
83
86
  end
84
87
 
88
+ desc "force_unlock", "Calls terrform force-unlock"
89
+ long_desc Help.text(:force_unlock)
90
+ instance_option.call
91
+ def force_unlock(mod, lock_id)
92
+ Commander.new("force-unlock", options.merge(mod: mod, lock_id: lock_id)).run
93
+ end
94
+
95
+ desc "fmt", "Run terraform fmt"
96
+ long_desc Help.text(:fmt)
97
+ type_option.call
98
+ def fmt(mod=nil)
99
+ Fmt.new(options.merge(mod: mod)).run
100
+ end
101
+
85
102
  desc "info STACK", "Get info about stack."
86
103
  long_desc Help.text(:info)
87
104
  instance_option.call
@@ -100,7 +117,7 @@ module Terraspace
100
117
 
101
118
  desc "list", "List stacks and modules."
102
119
  long_desc Help.text(:list)
103
- option :type, default: "stack", aliases: %w[t], desc: "Type: stack, module, or all"
120
+ type_option.call
104
121
  def list
105
122
  List.new(options).run
106
123
  end
@@ -0,0 +1,13 @@
1
+ module Terraspace::CLI::Concerns
2
+ module SourceDirs
3
+ # used by list
4
+ def source_dirs
5
+ Dir.glob("{app,vendor}/{modules,stacks}/*").select { |p| File.directory?(p) }.sort
6
+ end
7
+
8
+ # dont include vendor: used by fmt
9
+ def app_source_dirs
10
+ Dir.glob("{app}/{modules,stacks}/*").select { |p| File.directory?(p) }.sort
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,40 @@
1
+ class Terraspace::CLI
2
+ class Fmt
3
+ include Concerns::SourceDirs
4
+ include Terraspace::Util::Logging
5
+
6
+ def initialize(options={})
7
+ @options = options
8
+ @mod_name = options[:mod]
9
+ end
10
+
11
+ def run
12
+ logger.info "Formating terraform files"
13
+ dirs.each do |dir|
14
+ format(dir)
15
+ end
16
+ end
17
+
18
+ def format(dir)
19
+ Runner.new(dir).format!
20
+ end
21
+
22
+ private
23
+ def dirs
24
+ if @mod_name
25
+ type_dirs.select { |p| p.include?(@mod_name) }
26
+ else
27
+ type_dirs
28
+ end
29
+ end
30
+
31
+ def type_dirs
32
+ type = @options[:type]
33
+ if type
34
+ app_source_dirs.select { |p| p.include?("/#{type.pluralize}/") }
35
+ else
36
+ app_source_dirs
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,64 @@
1
+ class Terraspace::CLI::Fmt
2
+ class Runner
3
+ include Terraspace::CLI::Concerns::SourceDirs
4
+ include Terraspace::Util::Logging
5
+ SKIP_PATTERN = /\.skip$/
6
+
7
+ def initialize(dir)
8
+ @dir = dir
9
+ end
10
+
11
+ def format!
12
+ logger.info @dir.color(:green)
13
+ Dir.chdir(@dir) do
14
+ skip_rename
15
+ begin
16
+ terraform_fmt
17
+ ensure
18
+ restore_rename
19
+ end
20
+ end
21
+ end
22
+
23
+ def skip_rename
24
+ tf_files.each do |path|
25
+ if !skip?(path) && erb?(path)
26
+ FileUtils.mv(path, "#{path}.skip")
27
+ end
28
+ end
29
+ end
30
+
31
+ def terraform_fmt
32
+ sh "terraform fmt"
33
+ end
34
+
35
+ def sh(command)
36
+ logger.debug("=> #{command}")
37
+ success = system(command)
38
+ return if success
39
+ logger.info "WARN: There were some errors running terraform fmt for files in #{@dir}:".color(:yellow)
40
+ logger.info "The errors are shown above"
41
+ end
42
+
43
+ def restore_rename
44
+ tf_files.each do |path|
45
+ if skip?(path) && erb?(path)
46
+ FileUtils.mv(path, path.sub(SKIP_PATTERN, '')) # original name
47
+ end
48
+ end
49
+ end
50
+
51
+ private
52
+ def skip?(path)
53
+ !!(path =~ SKIP_PATTERN)
54
+ end
55
+
56
+ def erb?(path)
57
+ IO.readlines(path).detect { |l| l.include?('<%') }
58
+ end
59
+
60
+ def tf_files
61
+ Dir.glob("#{Terraspace.root}/#{@dir}/**/*.{tf,skip}").select { |p| File.file?(p) }
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,22 @@
1
+ ## Example
2
+
3
+ Format all source files.
4
+
5
+ $ terraspace fmt
6
+ Formating terraform files
7
+ app/modules/example
8
+ main.tf
9
+ outputs.tf
10
+ variables.tf
11
+ app/stacks/demo
12
+ main.tf
13
+
14
+ Format specific module or stack.
15
+
16
+ $ terraspace fmt stack1
17
+ $ terraspace fmt module1
18
+
19
+ Format scoping to module or stack types. In case there's a module and stack with the same name.
20
+
21
+ $ terraspace fmt example -t module
22
+ $ terraspace fmt demo -t stacke
@@ -0,0 +1,7 @@
1
+ ## Example
2
+
3
+ terraspace force_unlock demo ab7f3469-2a5f-07b9-29c5-dec1537ec8b0
4
+
5
+ Instance option:
6
+
7
+ terraspace force_unlock demo -i 2 ab7f3469-2a5f-07b9-29c5-dec1537ec8b0
@@ -1,13 +1,14 @@
1
1
  class Terraspace::CLI
2
2
  class List
3
+ include Concerns::SourceDirs
4
+
3
5
  def initialize(options={})
4
6
  @options = options
5
7
  @type_dir = normalized_type
6
8
  end
7
9
 
8
10
  def run
9
- dirs = Dir.glob("{app,vendor}/{modules,stacks}/*").select { |p| File.directory?(p) }
10
- dirs.sort.each do |path|
11
+ source_dirs.each do |path|
11
12
  if @type_dir
12
13
  puts path if path.include?("/#{@type_dir}/")
13
14
  else
@@ -26,9 +26,9 @@ class Terraspace::CLI::New
26
26
 
27
27
  def helper_class
28
28
  if type == "project"
29
- "Terraspace::#{type.camelize}::#{name.camelize}Helper"
29
+ "Terraspace::#{type.camelcase}::#{name.camelcase}Helper"
30
30
  else
31
- "Terraspace::#{type.camelize}::#{stack.camelize}::#{name.camelize}Helper"
31
+ "Terraspace::#{type.camelcase}::#{stack.camelcase}::#{name.camelcase}Helper"
32
32
  end
33
33
  end
34
34
 
@@ -74,10 +74,11 @@ module Terraspace::Compiler
74
74
  def skip?(src_path)
75
75
  return true unless File.file?(src_path)
76
76
  # certain folders will be skipped
77
- src_path.include?("#{@mod.root}/tfvars") ||
78
77
  src_path.include?("#{@mod.root}/config/args") ||
78
+ src_path.include?("#{@mod.root}/config/helpers") ||
79
79
  src_path.include?("#{@mod.root}/config/hooks") ||
80
- src_path.include?("#{@mod.root}/test")
80
+ src_path.include?("#{@mod.root}/test") ||
81
+ src_path.include?("#{@mod.root}/tfvars")
81
82
  end
82
83
  end
83
84
  end
@@ -5,7 +5,7 @@ module Terraspace::Compiler
5
5
  full_dir = "#{@mod.root}/config/helpers"
6
6
  Dir.glob("#{full_dir}/**/*").each do |path|
7
7
  regexp = Regexp.new(".*/helpers/")
8
- klass = path.sub(regexp, '').sub('.rb','').camelize
8
+ klass = path.sub(regexp, '').sub('.rb','').camelcase
9
9
  klass = "#{mod_namespace}::#{klass}"
10
10
  require path # able to use require instead of load since each helper has unique namespace
11
11
  send :extend, klass.constantize
@@ -15,8 +15,8 @@ module Terraspace::Compiler
15
15
  # IE: mod_namespace = Terraspace::Module::Demo
16
16
  # Use separate namespaces scope with module name so custom helper methods from different modules are isolated.
17
17
  def mod_namespace
18
- mod_name = @mod.name.camelize
19
- ns = "Terraspace::#{@mod.type.camelize}".constantize # IE: Terraspace::Module or Terraspace::Stack
18
+ mod_name = @mod.name.camelcase
19
+ ns = "Terraspace::#{@mod.type.camelcase}".constantize # IE: Terraspace::Module or Terraspace::Stack
20
20
  if ns.const_defined?(mod_name.to_sym)
21
21
  "#{ns}::#{mod_name}".constantize
22
22
  else
@@ -1,14 +1,15 @@
1
1
  module Terraspace::Compiler::Strategy
2
2
  class Mod < AbstractBase
3
3
  def run
4
- ext = File.extname(@src_path).sub('.','')
5
- klass = strategy_class(ext)
4
+ klass = strategy_class(@src_path)
6
5
  strategy = klass.new(@mod, @src_path) # IE: Terraspace::Compiler::Strategy::Mod::Rb.new
7
6
  strategy.run
8
7
  end
9
8
 
10
- def strategy_class(ext)
9
+ def strategy_class(path)
10
+ ext = File.extname(path).sub('.','')
11
11
  return Mod::Pass if ext.empty? # infinite loop without this
12
+ return Mod::Pass if Terraspace.pass_file?(path)
12
13
  "Terraspace::Compiler::Strategy::Mod::#{ext.camelize}".constantize rescue Mod::Pass
13
14
  end
14
15
  end
@@ -10,11 +10,17 @@ module Terraspace::Compiler
10
10
  end
11
11
 
12
12
  def dest_path
13
- name = @dest_name || @src_path.sub('.rb','.tf.json')
13
+ name = get_name
14
14
  name = basename(name)
15
15
  "#{dest_dir}/#{name}"
16
16
  end
17
17
 
18
+ def get_name
19
+ return @dest_name if @dest_name
20
+ return @src_path if Terraspace.pass_file?(@src_path)
21
+ @src_path.sub('.rb','.tf.json')
22
+ end
23
+
18
24
  def dest_dir
19
25
  if @mod.is_a?(Terraspace::Mod::Remote)
20
26
  File.dirname(@src_path) # for Mod::Remote src is dest
@@ -51,5 +51,12 @@ module Terraspace
51
51
  def logger=(v)
52
52
  @@logger = v
53
53
  end
54
+
55
+ def pass_file?(path)
56
+ pass_files = config.build.pass_files + config.build.default_pass_files
57
+ pass_files.uniq.detect do |i|
58
+ i.is_a?(Regexp) ? path =~ i : path.include?(i)
59
+ end
60
+ end
54
61
  end
55
62
  end
@@ -1,2 +1,3 @@
1
1
  require_relative "ext/bundler"
2
2
  require_relative "ext/core/module"
3
+ require_relative "ext/core/string"
@@ -0,0 +1,5 @@
1
+ class String
2
+ def camelcase
3
+ self.underscore.camelize
4
+ end
5
+ end
@@ -2,6 +2,17 @@ module Terraspace::Hooks
2
2
  class Runner
3
3
  include Terraspace::Util
4
4
 
5
+ # exposing mod and hook so terraspace hooks have access to them via runner context. IE:
6
+ #
7
+ # class EnvExporter
8
+ # def call(runner)
9
+ # puts "runner.hook #{runner.hook}"
10
+ # end
11
+ # end
12
+ #
13
+ # Docs: http://terraspace.cloud/docs/config/hooks/ruby/#method-argument
14
+ #
15
+ attr_reader :mod, :hook
5
16
  def initialize(mod, hook)
6
17
  @mod, @hook = mod, hook
7
18
  @execute = @hook["execute"]
@@ -12,12 +23,24 @@ module Terraspace::Hooks
12
23
  when String
13
24
  Terraspace::Shell.new(@mod, @execute, exit_on_fail: @hook["exit_on_fail"]).run
14
25
  when -> (e) { e.respond_to?(:public_instance_methods) && e.public_instance_methods.include?(:call) }
15
- @execute.new.call
26
+ executor = @execute.new
16
27
  when -> (e) { e.respond_to?(:call) }
17
- @execute.call
28
+ executor = @execute
18
29
  else
19
30
  logger.warn "WARN: execute option not set for hook: #{@hook.inspect}"
20
31
  end
32
+
33
+ if executor
34
+ meth = executor.method(:call)
35
+ case meth.arity
36
+ when 0
37
+ executor.call # backwards compatibility
38
+ when 1
39
+ executor.call(self)
40
+ else
41
+ raise "The #{executor} call method definition has been more than 1 arguments and is not supported"
42
+ end
43
+ end
21
44
  end
22
45
  end
23
46
  end
@@ -3,7 +3,7 @@ require "tempfile"
3
3
  module Terraspace::Terraform::Args
4
4
  class Default
5
5
  def initialize(mod, name, options={})
6
- @mod, @name, @options = mod, name, options
6
+ @mod, @name, @options = mod, name.underscore, options
7
7
  @quiet = @options[:quiet].nil? ? true : @options[:quiet]
8
8
  end
9
9
 
@@ -11,14 +11,18 @@ module Terraspace::Terraform::Args
11
11
  # https://terraspace.cloud/docs/ci-automation/
12
12
  ENV['TF_IN_AUTOMATION'] = '1' if @options[:auto]
13
13
 
14
- if %w[apply destroy init output plan show].include?(@name)
15
- meth = "#{@name}_args"
16
- send(meth)
14
+ args_meth = "#{@name}_args"
15
+ if respond_to?(args_meth)
16
+ send(args_meth)
17
17
  else
18
18
  []
19
19
  end
20
20
  end
21
21
 
22
+ def force_unlock_args
23
+ [" -force #{@options[:lock_id]}"]
24
+ end
25
+
22
26
  def apply_args
23
27
  args = auto_approve_arg
24
28
  var_files = @options[:var_files]
@@ -1,3 +1,3 @@
1
1
  module Terraspace
2
- VERSION = "0.6.2"
2
+ VERSION = "0.6.7"
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.6.2
4
+ version: 0.6.7
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-03-05 00:00:00.000000000 Z
11
+ date: 2021-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -482,7 +482,10 @@ files:
482
482
  - lib/terraspace/cli/completer.rb
483
483
  - lib/terraspace/cli/completer/script.rb
484
484
  - lib/terraspace/cli/completer/script.sh
485
+ - lib/terraspace/cli/concerns/source_dirs.rb
485
486
  - lib/terraspace/cli/down.rb
487
+ - lib/terraspace/cli/fmt.rb
488
+ - lib/terraspace/cli/fmt/runner.rb
486
489
  - lib/terraspace/cli/help.rb
487
490
  - lib/terraspace/cli/help/all/down.md
488
491
  - lib/terraspace/cli/help/all/graph.md
@@ -504,6 +507,8 @@ files:
504
507
  - lib/terraspace/cli/help/completion_script.md
505
508
  - lib/terraspace/cli/help/console.md
506
509
  - lib/terraspace/cli/help/down.md
510
+ - lib/terraspace/cli/help/fmt.md
511
+ - lib/terraspace/cli/help/force_unlock.md
507
512
  - lib/terraspace/cli/help/info.md
508
513
  - lib/terraspace/cli/help/init.md
509
514
  - lib/terraspace/cli/help/list.md
@@ -623,6 +628,7 @@ files:
623
628
  - lib/terraspace/ext.rb
624
629
  - lib/terraspace/ext/bundler.rb
625
630
  - lib/terraspace/ext/core/module.rb
631
+ - lib/terraspace/ext/core/string.rb
626
632
  - lib/terraspace/hooks/builder.rb
627
633
  - lib/terraspace/hooks/concern.rb
628
634
  - lib/terraspace/hooks/dsl.rb