ruby-terraform 0.64.0 → 0.65.0.pre.5

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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +102 -29
  3. data/README.md +29 -9
  4. data/Rakefile +60 -42
  5. data/bin/console +3 -3
  6. data/lib/ruby-terraform.rb +1 -1
  7. data/lib/ruby_terraform.rb +20 -55
  8. data/lib/ruby_terraform/command_line/builder.rb +55 -0
  9. data/lib/ruby_terraform/command_line/option/base.rb +24 -0
  10. data/lib/ruby_terraform/command_line/option/boolean.rb +16 -0
  11. data/lib/ruby_terraform/command_line/option/boolean_value.rb +29 -0
  12. data/lib/ruby_terraform/command_line/option/flag.rb +16 -0
  13. data/lib/ruby_terraform/command_line/option/standard.rb +40 -0
  14. data/lib/ruby_terraform/command_line/option/switch.rb +43 -0
  15. data/lib/ruby_terraform/command_line/options_factory.rb +79 -0
  16. data/lib/ruby_terraform/commands/apply.rb +18 -40
  17. data/lib/ruby_terraform/commands/base.rb +56 -20
  18. data/lib/ruby_terraform/commands/clean.rb +2 -2
  19. data/lib/ruby_terraform/commands/destroy.rb +17 -38
  20. data/lib/ruby_terraform/commands/format.rb +8 -20
  21. data/lib/ruby_terraform/commands/get.rb +11 -10
  22. data/lib/ruby_terraform/commands/import.rb +17 -36
  23. data/lib/ruby_terraform/commands/init.rb +12 -28
  24. data/lib/ruby_terraform/commands/output.rb +13 -21
  25. data/lib/ruby_terraform/commands/plan.rb +13 -36
  26. data/lib/ruby_terraform/commands/refresh.rb +13 -32
  27. data/lib/ruby_terraform/commands/remote_config.rb +9 -17
  28. data/lib/ruby_terraform/commands/show.rb +9 -16
  29. data/lib/ruby_terraform/commands/validate.rb +13 -29
  30. data/lib/ruby_terraform/commands/workspace.rb +14 -14
  31. data/lib/ruby_terraform/errors/execution_error.rb +1 -1
  32. data/lib/ruby_terraform/output.rb +15 -12
  33. data/lib/ruby_terraform/version.rb +1 -1
  34. metadata +105 -13
@@ -0,0 +1,55 @@
1
+ require 'lino'
2
+
3
+ module RubyTerraform
4
+ module CommandLine
5
+ class Builder
6
+ def initialize(binary:, sub_commands:, options:, arguments:)
7
+ @builder = instantiate_builder(binary)
8
+ @sub_commands = array_of(sub_commands)
9
+ @options = array_of(options)
10
+ @arguments = array_of(arguments)
11
+ end
12
+
13
+ def build
14
+ configure_builder
15
+ builder.build
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :builder, :sub_commands, :options, :arguments
21
+
22
+ def configure_builder
23
+ add_subcommands_and_options
24
+ add_arguments
25
+ end
26
+
27
+ def add_subcommands_and_options
28
+ sub_commands[0...-1].each do |command|
29
+ @builder = builder.with_subcommand(command)
30
+ end
31
+ @builder = builder.with_subcommand(sub_commands.last) do |sub|
32
+ options.inject(sub) do |sub_command, option|
33
+ option.add_to_subcommand(sub_command)
34
+ end
35
+ end
36
+ end
37
+
38
+ def add_arguments
39
+ @builder = builder.with_arguments(arguments)
40
+ end
41
+
42
+ def instantiate_builder(binary)
43
+ Lino::CommandLineBuilder
44
+ .for_command(binary)
45
+ .with_option_separator('=')
46
+ end
47
+
48
+ def array_of(value)
49
+ return value if value.respond_to?(:each)
50
+
51
+ value.nil? ? [] : [value]
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,24 @@
1
+ module RubyTerraform
2
+ module CommandLine
3
+ module Option
4
+ class Base
5
+ def initialize(switch, value)
6
+ @switch = switch
7
+ coerce_value(value)
8
+ end
9
+
10
+ def add_to_subcommand(_sub)
11
+ raise 'not implemented'
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :switch, :value
17
+
18
+ def coerce_value(value)
19
+ @value = value
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'boolean_value'
2
+ require_relative 'base'
3
+
4
+ module RubyTerraform
5
+ module CommandLine
6
+ module Option
7
+ class Boolean < Base
8
+ include BooleanValue
9
+
10
+ def add_to_subcommand(sub)
11
+ sub.with_option(switch, value)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ module RubyTerraform
2
+ module CommandLine
3
+ module Option
4
+ module BooleanValue
5
+ def coerce_value(value)
6
+ @value = boolean_val(value)
7
+ end
8
+
9
+ private
10
+
11
+ def boolean_val(value)
12
+ return nil if value.nil?
13
+ return value if a_boolean?(value)
14
+ return true if true_as_string?(value)
15
+
16
+ false
17
+ end
18
+
19
+ def a_boolean?(value)
20
+ value.is_a?(TrueClass) || value.is_a?(FalseClass)
21
+ end
22
+
23
+ def true_as_string?(value)
24
+ value.respond_to?(:downcase) && value.downcase == 'true'
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'boolean_value'
2
+ require_relative 'base'
3
+
4
+ module RubyTerraform
5
+ module CommandLine
6
+ module Option
7
+ class Flag < Base
8
+ include BooleanValue
9
+
10
+ def add_to_subcommand(sub)
11
+ value ? sub.with_flag(switch) : sub
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,40 @@
1
+ require 'json'
2
+ require_relative 'base'
3
+
4
+ module RubyTerraform
5
+ module CommandLine
6
+ module Option
7
+ class Standard < Base
8
+ def add_to_subcommand(sub)
9
+ if value.respond_to?(:keys)
10
+ add_hash_to_subcommand(sub)
11
+ elsif value.respond_to?(:each)
12
+ add_array_to_subcommand(sub)
13
+ else
14
+ sub.with_option(switch, value)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def add_hash_to_subcommand(sub)
21
+ sub.with_repeated_option(
22
+ switch,
23
+ value.map do |hash_key, hash_value|
24
+ "'#{hash_key}=#{as_string(hash_value)}'"
25
+ end,
26
+ separator: ' '
27
+ )
28
+ end
29
+
30
+ def add_array_to_subcommand(sub)
31
+ sub.with_repeated_option(switch, value)
32
+ end
33
+
34
+ def as_string(value)
35
+ value.is_a?(String) ? value : JSON.generate(value)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,43 @@
1
+ module RubyTerraform
2
+ module CommandLine
3
+ module Option
4
+ class Switch
5
+ def initialize(switch)
6
+ @switch_without_prefix = switch[0] == '-' ? switch[1..] : switch
7
+ end
8
+
9
+ def to_s
10
+ "-#{switch_without_prefix}"
11
+ end
12
+
13
+ def as_key
14
+ snake_case.to_sym
15
+ end
16
+
17
+ def as_plural_key
18
+ "#{snake_case}s".to_sym
19
+ end
20
+
21
+ def ==(other)
22
+ to_s == other
23
+ end
24
+
25
+ def eql?(other)
26
+ to_s == other
27
+ end
28
+
29
+ def hash
30
+ to_s.hash
31
+ end
32
+
33
+ private
34
+
35
+ attr_reader :switch_without_prefix
36
+
37
+ def snake_case
38
+ switch_without_prefix.gsub('-', '_')
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,79 @@
1
+ require_relative 'option/standard'
2
+ require_relative 'option/flag'
3
+ require_relative 'option/boolean'
4
+ require_relative 'option/switch'
5
+
6
+ module RubyTerraform
7
+ module CommandLine
8
+ class OptionsFactory
9
+ PLURAL_SWITCHES = Set.new(
10
+ %w[-var -target -var-file]
11
+ ).freeze
12
+ BOOLEAN_SWITCHES = Set.new(
13
+ %w[-auto-approve -backend -get -get-plugins -input -list -lock
14
+ -refresh -upgrade -verify-plugins -write]
15
+ ).freeze
16
+ FLAG_SWITCHES = Set.new(
17
+ %w[-allow-missing -allow-missing-config -check -compact-warnings
18
+ -destroy -detailed-exitcode -diff -draw-cycles -force -force-copy
19
+ -ignore-remote-version -json -no-color -raw -reconfigure -recursive
20
+ -update]
21
+ ).freeze
22
+ OVERRIDE_SWITCHES = {
23
+ config: :directory,
24
+ out: :plan
25
+ }.freeze
26
+
27
+ def self.from(values, switches)
28
+ new(values, switches).from
29
+ end
30
+
31
+ private_class_method :new
32
+
33
+ def initialize(values, switches)
34
+ @switches = switches.map { |switch| Option::Switch.new(switch) }
35
+ @values = values
36
+ end
37
+
38
+ def from
39
+ switches.each_with_object([]) do |switch, options|
40
+ options.append(*options_from_switch(switch))
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ attr_reader :switches, :values
47
+
48
+ def options_from_switch(switch)
49
+ return plural_options(switch) if PLURAL_SWITCHES.include?(switch)
50
+ return boolean_option(switch) if BOOLEAN_SWITCHES.include?(switch)
51
+ return flag_option(switch) if FLAG_SWITCHES.include?(switch)
52
+ return override_option(switch) if OVERRIDE_SWITCHES.key?(switch.as_key)
53
+
54
+ standard_option(switch, switch.as_key)
55
+ end
56
+
57
+ def boolean_option(switch)
58
+ [Option::Boolean.new(switch.to_s, values[switch.as_key])]
59
+ end
60
+
61
+ def flag_option(switch)
62
+ [Option::Flag.new(switch.to_s, values[switch.as_key])]
63
+ end
64
+
65
+ def standard_option(switch, hash_key)
66
+ [Option::Standard.new(switch.to_s, values[hash_key])]
67
+ end
68
+
69
+ def override_option(switch)
70
+ standard_option(switch, OVERRIDE_SWITCHES[switch.as_key])
71
+ end
72
+
73
+ def plural_options(switch)
74
+ standard_option(switch.to_s, switch.as_key) +
75
+ standard_option(switch.to_s, switch.as_plural_key)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -1,49 +1,27 @@
1
- require 'json'
2
- require 'lino'
3
1
  require_relative 'base'
4
2
 
5
3
  module RubyTerraform
6
4
  module Commands
7
5
  class Apply < Base
8
- def configure_command(builder, opts)
9
- directory = opts[:directory]
10
- plan = opts[:plan]
11
- vars = opts[:vars] || {}
12
- var_file = opts[:var_file]
13
- var_files = opts[:var_files] || []
14
- target = opts[:target]
15
- targets = opts[:targets] || []
16
- state = opts[:state]
17
- input = opts[:input]
18
- auto_approve = opts[:auto_approve]
19
- no_backup = opts[:no_backup]
20
- backup = no_backup ? '-' : opts[:backup]
21
- no_color = opts[:no_color]
6
+ def sub_commands(_values)
7
+ 'apply'
8
+ end
9
+
10
+ def switches
11
+ %w[-backup -lock -lock-timeout -input -auto-approve -no-color -state
12
+ -target -var -var-file]
13
+ end
14
+
15
+ def arguments(values)
16
+ values[:plan] || values[:directory]
17
+ end
18
+
19
+ def option_default_values(_opts)
20
+ { vars: {}, var_files: [], targets: [] }
21
+ end
22
22
 
23
- builder
24
- .with_subcommand('apply') do |sub|
25
- vars.each do |key, value|
26
- var_value = value.is_a?(String) ? value : JSON.generate(value)
27
- sub = sub.with_option(
28
- '-var', "'#{key}=#{var_value}'", separator: ' ')
29
- end
30
- sub = sub.with_option('-var-file', var_file) if var_file
31
- var_files.each do |file|
32
- sub = sub.with_option('-var-file', file)
33
- end
34
- sub = sub.with_option('-target', target) if target
35
- targets.each do |file|
36
- sub = sub.with_option('-target', file)
37
- end
38
- sub = sub.with_option('-state', state) if state
39
- sub = sub.with_option('-input', input) if input
40
- sub = sub.with_option('-auto-approve', auto_approve) unless
41
- auto_approve.nil?
42
- sub = sub.with_option('-backup', backup) if backup
43
- sub = sub.with_flag('-no-color') if no_color
44
- sub
45
- end
46
- .with_argument(plan || directory)
23
+ def option_override_values(opts)
24
+ { backup: opts[:no_backup] ? '-' : opts[:backup] }
47
25
  end
48
26
  end
49
27
  end
@@ -1,30 +1,24 @@
1
- require 'lino'
2
1
  require_relative '../errors'
2
+ require_relative '../command_line/builder'
3
+ require_relative '../command_line/options_factory'
3
4
 
4
5
  module RubyTerraform
5
6
  module Commands
6
7
  class Base
7
8
  def initialize(
8
- binary: nil, logger: nil, stdin: nil, stdout: nil, stderr: nil)
9
+ binary: nil, logger: nil, stdin: nil, stdout: nil, stderr: nil
10
+ )
9
11
  @binary = binary || RubyTerraform.configuration.binary
10
12
  @logger = logger || RubyTerraform.configuration.logger
11
13
  @stdin = stdin || RubyTerraform.configuration.stdin
12
14
  @stdout = stdout || RubyTerraform.configuration.stdout
13
15
  @stderr = stderr || RubyTerraform.configuration.stderr
16
+ initialize_command
14
17
  end
15
18
 
16
19
  def execute(opts = {})
17
- builder = instantiate_builder
18
-
19
20
  do_before(opts)
20
- command = configure_command(builder, opts).build
21
- logger.debug("Running '#{command.to_s}'.")
22
-
23
- command.execute(
24
- stdin: stdin,
25
- stdout: stdout,
26
- stderr: stderr
27
- )
21
+ build_and_execute_command(opts)
28
22
  do_after(opts)
29
23
  rescue Open4::SpawnError
30
24
  message = "Failed while running '#{command_name}'."
@@ -36,23 +30,65 @@ module RubyTerraform
36
30
 
37
31
  attr_reader :binary, :logger, :stdin, :stdout, :stderr
38
32
 
33
+ def build_and_execute_command(opts)
34
+ command = build_command(opts)
35
+ logger.debug("Running '#{command}'.")
36
+ command.execute(
37
+ stdin: stdin,
38
+ stdout: stdout,
39
+ stderr: stderr
40
+ )
41
+ end
42
+
39
43
  def command_name
40
- self.class.to_s.split("::")[-1].downcase
44
+ self.class.to_s.split('::')[-1].downcase
45
+ end
46
+
47
+ def do_before(_opts); end
48
+
49
+ def do_after(_opts); end
50
+
51
+ private
52
+
53
+ def initialize_command; end
54
+
55
+ def build_command(opts)
56
+ values = apply_option_defaults_and_overrides(opts)
57
+ RubyTerraform::CommandLine::Builder.new(
58
+ binary: @binary,
59
+ sub_commands: sub_commands(values),
60
+ options: options(values),
61
+ arguments: arguments(values)
62
+ ).build
63
+ end
64
+
65
+ def apply_option_defaults_and_overrides(opts)
66
+ option_default_values(opts).merge(opts)
67
+ .merge(option_override_values(opts))
68
+ end
69
+
70
+ def option_default_values(_values)
71
+ {}
72
+ end
73
+
74
+ def option_override_values(_values)
75
+ {}
41
76
  end
42
77
 
43
- def instantiate_builder
44
- Lino::CommandLineBuilder
45
- .for_command(binary)
46
- .with_option_separator('=')
78
+ def sub_commands(_values)
79
+ []
47
80
  end
48
81
 
49
- def do_before(opts)
82
+ def options(values)
83
+ RubyTerraform::CommandLine::OptionsFactory.from(values, switches)
50
84
  end
51
85
 
52
- def configure_command(builder, opts)
86
+ def switches
87
+ []
53
88
  end
54
89
 
55
- def do_after(opts)
90
+ def arguments(_values)
91
+ []
56
92
  end
57
93
  end
58
94
  end