ruby-terraform 0.64.0 → 0.65.0.pre.5

Sign up to get free protection for your applications and to get access to all the features.
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