ruby-terraform 0.65.0.pre.11 → 1.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +25 -17
  3. data/README.md +148 -414
  4. data/Rakefile +25 -0
  5. data/lib/ruby_terraform.rb +1371 -42
  6. data/lib/ruby_terraform/commands.rb +0 -2
  7. data/lib/ruby_terraform/commands/apply.rb +78 -4
  8. data/lib/ruby_terraform/commands/base.rb +21 -15
  9. data/lib/ruby_terraform/commands/destroy.rb +71 -4
  10. data/lib/ruby_terraform/commands/force_unlock.rb +33 -3
  11. data/lib/ruby_terraform/commands/format.rb +45 -2
  12. data/lib/ruby_terraform/commands/get.rb +35 -2
  13. data/lib/ruby_terraform/commands/graph.rb +48 -2
  14. data/lib/ruby_terraform/commands/import.rb +98 -3
  15. data/lib/ruby_terraform/commands/init.rb +84 -3
  16. data/lib/ruby_terraform/commands/login.rb +26 -2
  17. data/lib/ruby_terraform/commands/logout.rb +23 -2
  18. data/lib/ruby_terraform/commands/output.rb +36 -6
  19. data/lib/ruby_terraform/commands/plan.rb +72 -3
  20. data/lib/ruby_terraform/commands/providers.rb +30 -2
  21. data/lib/ruby_terraform/commands/providers_lock.rb +72 -3
  22. data/lib/ruby_terraform/commands/providers_mirror.rb +44 -2
  23. data/lib/ruby_terraform/commands/providers_schema.rb +21 -2
  24. data/lib/ruby_terraform/commands/refresh.rb +70 -3
  25. data/lib/ruby_terraform/commands/show.rb +26 -3
  26. data/lib/ruby_terraform/commands/state_list.rb +54 -3
  27. data/lib/ruby_terraform/commands/state_move.rb +64 -6
  28. data/lib/ruby_terraform/commands/state_pull.rb +24 -2
  29. data/lib/ruby_terraform/commands/state_push.rb +49 -3
  30. data/lib/ruby_terraform/commands/state_remove.rb +55 -7
  31. data/lib/ruby_terraform/commands/state_replace_provider.rb +39 -6
  32. data/lib/ruby_terraform/commands/state_show.rb +26 -2
  33. data/lib/ruby_terraform/commands/taint.rb +63 -2
  34. data/lib/ruby_terraform/commands/untaint.rb +55 -2
  35. data/lib/ruby_terraform/commands/validate.rb +51 -6
  36. data/lib/ruby_terraform/commands/workspace_delete.rb +29 -7
  37. data/lib/ruby_terraform/commands/workspace_list.rb +21 -6
  38. data/lib/ruby_terraform/commands/workspace_new.rb +28 -7
  39. data/lib/ruby_terraform/commands/workspace_select.rb +23 -7
  40. data/lib/ruby_terraform/commands/workspace_show.rb +17 -2
  41. data/lib/ruby_terraform/options.rb +26 -4
  42. data/lib/ruby_terraform/options/definition.rb +174 -0
  43. data/lib/ruby_terraform/options/definitions.rb +112 -0
  44. data/lib/ruby_terraform/options/factory.rb +10 -102
  45. data/lib/ruby_terraform/options/{common.rb → global.rb} +2 -1
  46. data/lib/ruby_terraform/options/name.rb +11 -19
  47. data/lib/ruby_terraform/options/types.rb +26 -0
  48. data/lib/ruby_terraform/options/types/flag.rb +8 -6
  49. data/lib/ruby_terraform/options/types/standard.rb +17 -29
  50. data/lib/ruby_terraform/options/values.rb +38 -0
  51. data/lib/ruby_terraform/options/values/base.rb +15 -0
  52. data/lib/ruby_terraform/options/values/boolean.rb +13 -11
  53. data/lib/ruby_terraform/options/values/complex.rb +19 -0
  54. data/lib/ruby_terraform/options/values/key_value.rb +21 -0
  55. data/lib/ruby_terraform/options/values/string.rb +17 -0
  56. data/lib/ruby_terraform/version.rb +1 -1
  57. data/ruby_terraform.gemspec +3 -1
  58. metadata +43 -11
  59. data/lib/ruby_terraform/commands/clean.rb +0 -26
  60. data/lib/ruby_terraform/commands/remote_config.rb +0 -25
  61. data/lib/ruby_terraform/options/types/base.rb +0 -26
  62. data/lib/ruby_terraform/options/types/boolean.rb +0 -18
@@ -1,23 +1,39 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'base'
4
- require_relative '../options/common'
4
+ require_relative '../options/global'
5
5
 
6
6
  module RubyTerraform
7
7
  module Commands
8
+ # Wraps the +terraform workspace select+ command which selects a workspace.
9
+ #
10
+ # For options accepted on construction, see {#initialize}.
11
+ #
12
+ # When executing an instance of {WorkspaceSelect} via {#execute}, the
13
+ # following options are supported:
14
+ #
15
+ # * +:name+: the name of the workspace to select; required.
16
+ # * +:directory+: the path to a directory containing terraform configuration
17
+ # (deprecated in terraform 0.14, removed in terraform 0.15, use +:chdir+
18
+ # instead).
19
+ # * +:chdir+: the path of a working directory to switch to before executing
20
+ # the given subcommand.
21
+ #
22
+ # @example BasicInvocation
23
+ # RubyTerraform::Commands::WorkspaceSelect.new.execute(
24
+ # name: 'example')
25
+ #
8
26
  class WorkspaceSelect < Base
9
- include RubyTerraform::Options::Common
27
+ include RubyTerraform::Options::Global
10
28
 
29
+ # @!visibility private
11
30
  def subcommands
12
31
  %w[workspace select]
13
32
  end
14
33
 
34
+ # @!visibility private
15
35
  def arguments(parameters)
16
- [parameters[:workspace], parameters[:directory]]
17
- end
18
-
19
- def parameter_defaults(_parameters)
20
- { directory: nil }
36
+ [parameters[:name], parameters[:directory]]
21
37
  end
22
38
  end
23
39
  end
@@ -1,13 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'base'
4
- require_relative '../options/common'
4
+ require_relative '../options/global'
5
5
 
6
6
  module RubyTerraform
7
7
  module Commands
8
+ # Wraps the +terraform workspace show+ command which shows the name of the
9
+ # current workspace.
10
+ #
11
+ # For options accepted on construction, see {#initialize}.
12
+ #
13
+ # When executing an instance of {WorkspaceSelect} via {#execute}, the
14
+ # following options are supported:
15
+ #
16
+ # * +:chdir+: the path of a working directory to switch to before executing
17
+ # the given subcommand.
18
+ #
19
+ # @example Basic Invocation
20
+ # RubyTerraform::Commands::WorkspaceShow.new.execute
21
+ #
8
22
  class WorkspaceShow < Base
9
- include RubyTerraform::Options::Common
23
+ include RubyTerraform::Options::Global
10
24
 
25
+ # @!visibility private
11
26
  def subcommands
12
27
  %w[workspace show]
13
28
  end
@@ -1,8 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'options/name'
4
- require_relative 'options/types/flag'
5
- require_relative 'options/types/boolean'
6
- require_relative 'options/types/standard'
4
+ require_relative 'options/types'
5
+ require_relative 'options/values'
6
+ require_relative 'options/definition'
7
7
  require_relative 'options/factory'
8
- require_relative 'options/common'
8
+ require_relative 'options/global'
9
+
10
+ module RubyTerraform
11
+ module Options
12
+ def self.name(name)
13
+ Name.new(name)
14
+ end
15
+
16
+ def self.definition(opts)
17
+ Definition.new(opts)
18
+ end
19
+
20
+ def self.types
21
+ Types
22
+ end
23
+
24
+ def self.values
25
+ Values
26
+ end
27
+ end
28
+ end
29
+
30
+ require_relative 'options/definitions'
@@ -0,0 +1,174 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'immutable-struct'
4
+
5
+ require_relative 'name'
6
+ require_relative 'types'
7
+ require_relative 'values'
8
+
9
+ module RubyTerraform
10
+ module Options
11
+ # rubocop:disable Metrics/ClassLength
12
+ class Definition < ImmutableStruct.new(
13
+ :name,
14
+ :option_type,
15
+ :value_type,
16
+ :override_keys,
17
+ :extra_keys,
18
+ :separator,
19
+ :placement,
20
+ :repeatable?
21
+ )
22
+ # rubocop:disable Metrics/MethodLength
23
+ def initialize(opts)
24
+ raise 'Missing name.' unless opts[:name]
25
+
26
+ super(
27
+ name: Name.new(opts[:name]),
28
+ option_type: Types.resolve(opts[:option_type]) || Types::Standard,
29
+ value_type: Values.resolve(opts[:value_type]) || Values::String,
30
+ repeatable: opts[:repeatable] || false,
31
+ separator: opts[:separator],
32
+ placement: opts[:placement],
33
+ extra_keys:
34
+ { singular: [], plural: [] }
35
+ .merge(opts[:extra_keys] || {}),
36
+ override_keys:
37
+ { singular: nil, plural: nil }
38
+ .merge(opts[:override_keys] || {})
39
+ )
40
+ end
41
+ # rubocop:enable Metrics/MethodLength
42
+
43
+ def matches?(name)
44
+ @name == Name.new(name)
45
+ end
46
+
47
+ def build(parameters)
48
+ build_singular_options(parameters) + build_plural_options(parameters)
49
+ end
50
+
51
+ private
52
+
53
+ def resolved_singular_key
54
+ if override_keys[:singular] == false
55
+ nil
56
+ else
57
+ override_keys[:singular] || name.as_singular_key
58
+ end
59
+ end
60
+
61
+ def all_singular_keys
62
+ ([resolved_singular_key] + extra_keys[:singular]).compact
63
+ end
64
+
65
+ def resolved_plural_key
66
+ if override_keys[:plural] == false
67
+ nil
68
+ else
69
+ override_keys[:plural] || name.as_plural_key
70
+ end
71
+ end
72
+
73
+ def all_plural_keys
74
+ ([resolved_plural_key] + extra_keys[:plural]).compact
75
+ end
76
+
77
+ def too_many_values?(values)
78
+ !repeatable? && values.length > 1
79
+ end
80
+
81
+ def values(parameters, keys)
82
+ keys.map { |k| parameters[k] }.compact
83
+ end
84
+
85
+ def needs_plural?(value)
86
+ repeatable? && !value.nil?
87
+ end
88
+
89
+ def only_singular?(value)
90
+ !needs_plural?(value)
91
+ end
92
+
93
+ def key_valued?(value)
94
+ value.respond_to?(:keys)
95
+ end
96
+
97
+ def multi_valued?(value)
98
+ value.respond_to?(:each)
99
+ end
100
+
101
+ def build_option(value)
102
+ option_type.new(name, value, separator: separator, placement: placement)
103
+ end
104
+
105
+ def build_value(value)
106
+ value_type.new(value)
107
+ end
108
+
109
+ def build_key_value(key, value)
110
+ Values::KeyValue.new(key, build_value(value))
111
+ end
112
+
113
+ def build_singular(value)
114
+ build_single_option(value)
115
+ end
116
+
117
+ def build_singulars(values)
118
+ values.map { |p| build_singular(p) }.flatten
119
+ end
120
+
121
+ def build_singular_options(parameters)
122
+ keys = all_singular_keys
123
+ values = values(parameters, keys)
124
+
125
+ if too_many_values?(values)
126
+ raise "Multiple values provided for '#{name}' " \
127
+ "(with keys #{keys}) and option not repeatable."
128
+ end
129
+
130
+ build_singulars(values)
131
+ end
132
+
133
+ def build_plural(value)
134
+ if only_singular?(value)
135
+ build_no_options
136
+ elsif key_valued?(value)
137
+ build_key_value_options(value)
138
+ elsif multi_valued?(value)
139
+ build_multiple_options(value)
140
+ else
141
+ build_single_option(value)
142
+ end
143
+ end
144
+
145
+ def build_plurals(values)
146
+ values.map { |p| build_plural(p) }.flatten
147
+ end
148
+
149
+ def build_plural_options(parameters)
150
+ keys = all_plural_keys
151
+ values = values(parameters, keys)
152
+
153
+ build_plurals(values)
154
+ end
155
+
156
+ def build_key_value_options(value)
157
+ value.map { |k, v| build_option(build_key_value(k, v)) }
158
+ end
159
+
160
+ def build_multiple_options(value)
161
+ value.map { |v| build_option(build_value(v)) }
162
+ end
163
+
164
+ def build_single_option(value)
165
+ [build_option(build_value(value))]
166
+ end
167
+
168
+ def build_no_options
169
+ []
170
+ end
171
+ end
172
+ # rubocop:enable Metrics/ClassLength
173
+ end
174
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyTerraform
4
+ module Options
5
+ DEFINITIONS =
6
+ [
7
+ # complex repeatable options with space separator
8
+ %w[-var].map do |o|
9
+ definition(
10
+ name: o, option_type: :standard, value_type: :complex,
11
+ repeatable: true, separator: ' '
12
+ )
13
+ end,
14
+
15
+ # complex repeatable options with default separator
16
+ %w[-backend-config].map do |o|
17
+ definition(
18
+ name: o, option_type: :standard, value_type: :complex,
19
+ repeatable: true,
20
+ override_keys: { singular: false, plural: :backend_config }
21
+ )
22
+ end,
23
+
24
+ # string repeatable options
25
+ %w[-var-file -target -platform -plugin-dir].map do |o|
26
+ definition(
27
+ name: o, option_type: :standard, value_type: :string,
28
+ repeatable: true
29
+ )
30
+ end,
31
+
32
+ # boolean options
33
+ %w[
34
+ -auto-approve
35
+ -backend
36
+ -get
37
+ -get-plugins
38
+ -input
39
+ -list
40
+ -lock
41
+ -refresh
42
+ -upgrade
43
+ -verify-plugins
44
+ -write
45
+ ].map do |o|
46
+ definition(name: o, option_type: :standard, value_type: :boolean)
47
+ end,
48
+
49
+ # flag options
50
+ %w[
51
+ -allow-missing
52
+ -allow-missing-config
53
+ -check
54
+ -compact-warnings
55
+ -destroy
56
+ -detailed-exitcode
57
+ -diff
58
+ -draw-cycles
59
+ -dry-run
60
+ -force
61
+ -force-copy
62
+ -ignore-remote-version
63
+ -json
64
+ -no-color
65
+ -raw
66
+ -reconfigure
67
+ -recursive
68
+ -update
69
+ ].map do |o|
70
+ definition(name: o, option_type: :flag, value_type: :boolean)
71
+ end,
72
+
73
+ # string options
74
+ %w[
75
+ -backup
76
+ -backup-out
77
+ -from-module
78
+ -fs-mirror
79
+ -id
80
+ -lock-timeout
81
+ -lockfile
82
+ -module-depth
83
+ -net-mirror
84
+ -parallelism
85
+ -plan
86
+ -provider
87
+ -state
88
+ -state-out
89
+ -type
90
+ ].map do |o|
91
+ definition(name: o, option_type: :standard, value_type: :string)
92
+ end,
93
+
94
+ # string options with extra keys
95
+ definition(
96
+ name: '-config', option_type: :standard, value_type: :string,
97
+ extra_keys: { singular: %i[directory] }
98
+ ),
99
+ definition(
100
+ name: '-out', option_type: :standard, value_type: :string,
101
+ extra_keys: { singular: %i[plan] }
102
+ ),
103
+
104
+ # global options
105
+ definition(
106
+ name: '-chdir', option_type: :standard, value_type: :string,
107
+ placement: :after_command,
108
+ extra_keys: { singular: %i[working_directory] }
109
+ )
110
+ ].flatten.freeze
111
+ end
112
+ end
@@ -1,118 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'name'
4
- require_relative 'types/boolean'
5
- require_relative 'types/flag'
6
- require_relative 'types/standard'
7
4
 
8
5
  module RubyTerraform
9
6
  module Options
10
7
  class Factory
11
- PLURAL_OPTIONS =
12
- Set.new(
13
- %w[
14
- -var
15
- -target
16
- -var-file
17
- -platform
18
- ]
19
- ).freeze
20
-
21
- BOOLEAN_OPTIONS =
22
- Set.new(
23
- %w[
24
- -auto-approve
25
- -backend
26
- -get
27
- -get-plugins
28
- -input
29
- -list
30
- -lock
31
- -refresh
32
- -upgrade
33
- -verify-plugins
34
- -write
35
- ]
36
- ).freeze
37
-
38
- FLAG_OPTIONS =
39
- Set.new(
40
- %w[
41
- -allow-missing
42
- -allow-missing-config
43
- -check
44
- -compact-warnings
45
- -destroy
46
- -detailed-exitcode
47
- -diff
48
- -draw-cycles
49
- -force
50
- -force-copy
51
- -ignore-remote-version
52
- -json
53
- -no-color
54
- -raw
55
- -reconfigure
56
- -recursive
57
- -update
58
- ]
59
- ).freeze
60
-
61
- OVERRIDE_OPTIONS =
62
- {
63
- config: :directory,
64
- out: :plan
65
- }.freeze
66
-
67
- def self.from(names, parameters)
68
- new(names, parameters).from
69
- end
70
-
71
- private_class_method :new
72
-
73
- def initialize(names, parameters)
74
- @names = names.map { |name| Name.new(name) }
75
- @parameters = parameters
8
+ def initialize(definitions)
9
+ @definitions = definitions
76
10
  end
77
11
 
78
- def from
79
- names.each_with_object([]) do |name, options|
80
- options.append(*options_from_name(name))
81
- end
12
+ def resolve(names, parameters)
13
+ names
14
+ .map { |name| Name.new(name) }
15
+ .inject([]) do |options, name|
16
+ options + resolve_name(name, parameters)
17
+ end
82
18
  end
83
19
 
84
20
  private
85
21
 
86
- attr_reader :names, :parameters
87
-
88
- def options_from_name(name)
89
- return plural_options(name) if PLURAL_OPTIONS.include?(name)
90
- return boolean_option(name) if BOOLEAN_OPTIONS.include?(name)
91
- return flag_option(name) if FLAG_OPTIONS.include?(name)
92
- return override_option(name) if OVERRIDE_OPTIONS.key?(name.as_key)
93
-
94
- standard_option(name, name.as_key)
95
- end
96
-
97
- def boolean_option(name)
98
- [Types::Boolean.new(name.to_s, parameters[name.as_key])]
99
- end
100
-
101
- def flag_option(name)
102
- [Types::Flag.new(name.to_s, parameters[name.as_key])]
103
- end
104
-
105
- def standard_option(name, hash_key)
106
- [Types::Standard.new(name.to_s, parameters[hash_key])]
107
- end
108
-
109
- def override_option(name)
110
- standard_option(name, OVERRIDE_OPTIONS[name.as_key])
111
- end
112
-
113
- def plural_options(name)
114
- standard_option(name.to_s, name.as_key) +
115
- standard_option(name.to_s, name.as_plural_key)
22
+ def resolve_name(name, parameters)
23
+ @definitions.find { |d| d.matches?(name) }.build(parameters)
116
24
  end
117
25
  end
118
26
  end