kitchen-terraform 1.0.2 → 2.0.0

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 (58) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +3 -3
  5. data/lib/kitchen/driver/terraform.rb +363 -221
  6. data/lib/kitchen/provisioner/terraform.rb +2 -3
  7. data/lib/kitchen/terraform.rb +3 -1
  8. data/lib/kitchen/terraform/clear_directory.rb +38 -0
  9. data/lib/kitchen/terraform/client/command.rb +168 -0
  10. data/lib/kitchen/terraform/client/options.rb +275 -0
  11. data/lib/kitchen/terraform/client_version_verifier.rb +57 -0
  12. data/lib/{terraform/debug_logger.rb → kitchen/terraform/config_attribute.rb} +7 -13
  13. data/lib/kitchen/terraform/config_attribute/backend_configurations.rb +53 -0
  14. data/lib/kitchen/terraform/config_attribute/color.rb +56 -0
  15. data/lib/kitchen/terraform/config_attribute/command_timeout.rb +52 -0
  16. data/lib/kitchen/terraform/config_attribute/directory.rb +54 -0
  17. data/lib/kitchen/terraform/config_attribute/groups.rb +96 -0
  18. data/lib/kitchen/terraform/config_attribute/lock_timeout.rb +52 -0
  19. data/lib/kitchen/terraform/config_attribute/parallelism.rb +53 -0
  20. data/lib/kitchen/terraform/config_attribute/plugin_directory.rb +55 -0
  21. data/lib/kitchen/terraform/config_attribute/state.rb +55 -0
  22. data/lib/kitchen/terraform/config_attribute/variable_files.rb +51 -0
  23. data/lib/kitchen/terraform/config_attribute/variables.rb +53 -0
  24. data/lib/kitchen/terraform/config_attribute/verify_plugins.rb +52 -0
  25. data/lib/kitchen/terraform/config_attribute_cacher.rb +44 -0
  26. data/lib/kitchen/terraform/config_attribute_definer.rb +66 -0
  27. data/lib/kitchen/terraform/config_predicates.rb +21 -0
  28. data/lib/kitchen/terraform/config_predicates/hash_of_symbols_and_strings.rb +72 -0
  29. data/lib/{terraform.rb → kitchen/terraform/config_schemas.rb} +4 -2
  30. data/lib/kitchen/terraform/config_schemas/array_of_hashes_of_symbols_and_strings.rb +47 -0
  31. data/lib/kitchen/terraform/config_schemas/array_of_strings.rb +31 -0
  32. data/lib/kitchen/terraform/config_schemas/boolean.rb +27 -0
  33. data/lib/kitchen/terraform/config_schemas/hash_of_symbols_and_strings.rb +32 -0
  34. data/lib/kitchen/terraform/config_schemas/integer.rb +27 -0
  35. data/lib/kitchen/terraform/config_schemas/optional_string.rb +31 -0
  36. data/lib/kitchen/terraform/config_schemas/string.rb +26 -0
  37. data/lib/kitchen/terraform/configurable.rb +75 -0
  38. data/lib/kitchen/terraform/file_path_config_attribute_definer.rb +48 -0
  39. data/lib/{terraform/project_version.rb → kitchen/terraform/version.rb} +3 -3
  40. data/lib/kitchen/verifier/terraform.rb +40 -129
  41. data/lib/kitchen/verifier/terraform/configure_inspec_runner_attributes.rb +7 -4
  42. data/lib/kitchen/verifier/terraform/enumerate_groups_and_hostnames.rb +2 -2
  43. metadata +69 -43
  44. metadata.gz.sig +0 -0
  45. data/lib/kitchen/driver/terraform/verify_client_version.rb +0 -44
  46. data/lib/kitchen/driver/terraform/workflow.rb +0 -90
  47. data/lib/kitchen/terraform/client/apply.rb +0 -38
  48. data/lib/kitchen/terraform/client/execute_command.rb +0 -56
  49. data/lib/kitchen/terraform/client/get.rb +0 -35
  50. data/lib/kitchen/terraform/client/output.rb +0 -50
  51. data/lib/kitchen/terraform/client/plan.rb +0 -42
  52. data/lib/kitchen/terraform/client/process_options.rb +0 -87
  53. data/lib/kitchen/terraform/client/validate.rb +0 -35
  54. data/lib/kitchen/terraform/client/version.rb +0 -48
  55. data/lib/kitchen/terraform/define_config_attribute.rb +0 -39
  56. data/lib/kitchen/terraform/define_integer_config_attribute.rb +0 -43
  57. data/lib/kitchen/terraform/define_string_config_attribute.rb +0 -43
  58. data/lib/terraform/configurable.rb +0 -42
@@ -15,7 +15,7 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require "kitchen"
18
- require "terraform/configurable"
18
+ require "kitchen/terraform/configurable"
19
19
 
20
20
  # The design of the provisioner is unconventional compared to other Test Kitchen provisioner plugins. Since Terraform
21
21
  # creates and provisions resources when applying an execution plan, managed by the driver, the provisioner simply
@@ -35,7 +35,7 @@ require "terraform/configurable"
35
35
  class ::Kitchen::Provisioner::Terraform < ::Kitchen::Provisioner::Base
36
36
  kitchen_provisioner_api_version 2
37
37
 
38
- include ::Terraform::Configurable
38
+ include ::Kitchen::Terraform::Configurable
39
39
 
40
40
  # Proxies the driver's create action.
41
41
  #
@@ -43,7 +43,6 @@ class ::Kitchen::Provisioner::Terraform < ::Kitchen::Provisioner::Base
43
43
  # `kitchen converge suite-name`
44
44
  # @param state [::Hash] the mutable instance and provisioner state.
45
45
  # @raise [::Kitchen::ActionFailed] if the result of the action is a failure.
46
- # @return [::Dry::Monads::Either] the result of the action.
47
46
  def call(state)
48
47
  instance.driver.create state
49
48
  end
@@ -14,7 +14,9 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
- require "kitchen"
17
+ # Dummy namespace for Test Kitchen to allow loading of Kitchen::Terraform::Version from gem specification.
18
+ module ::Kitchen
19
+ end
18
20
 
19
21
  # The namespace for kitchen-terraform.
20
22
  module ::Kitchen::Terraform
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2016 New Context Services, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require "dry/monads"
18
+ require "fileutils"
19
+ require "kitchen/terraform"
20
+
21
+ # Clears a directory on the filesystem of specified files.
22
+ module ::Kitchen::Terraform::ClearDirectory
23
+ extend ::Dry::Monads::Either::Mixin
24
+
25
+ # Invokes the function.
26
+ #
27
+ # @param directory ::String the path of the directory to clear.
28
+ # @param files [::Array<::String>, ::String] a list of files to clear from the directory.
29
+ # @return [::Dry::Monads::Either] the result of the function.
30
+ def self.call(directory:, files:)
31
+ ::FileUtils.safe_unlink(
32
+ files.map do |file|
33
+ ::Dir.glob ::File.join directory, file
34
+ end.flatten
35
+ )
36
+ Right "Cleared directory \"#{directory}\" of files #{files}"
37
+ end
38
+ end
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2016 New Context Services, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require "dry/monads"
18
+ require "kitchen/terraform/client"
19
+ require "mixlib/shellout"
20
+ require "kitchen/terraform/client/options"
21
+
22
+ # Represents the result of running a Terraform command.
23
+ #
24
+ # @see https://www.terraform.io/docs/commands/index.html Terraform commands
25
+ module ::Kitchen::Terraform::Client::Command
26
+ extend ::Dry::Monads::Either::Mixin
27
+
28
+ extend ::Dry::Monads::Try::Mixin
29
+
30
+ # Creates the apply command shell out.
31
+ #
32
+ # @param options [::Kitchen::Terraform::Client::Options] options for the command.
33
+ # @param working_directory[::String] the path to the directory in which to run the shell out.
34
+ # @return [::Dry::Monads::Either] the result of creating the shell out.
35
+ # @see https://www.terraform.io/docs/commands/apply.html Terraform Command: apply
36
+ def self.apply(options:, working_directory:)
37
+ create(
38
+ options: options,
39
+ subcommand: "apply",
40
+ working_directory: working_directory
41
+ )
42
+ end
43
+
44
+ #
45
+ # Creates the destroy command shell out.
46
+ #
47
+ # @param options [::Kitchen::Terraform::Client::Options] options for the command.
48
+ # @param working_directory[::String] the path to the directory in which to run the shell out.
49
+ # @return [::Dry::Monads::Either] the result of creating the shell out.
50
+ # @see https://www.terraform.io/docs/commands/destroy.html Terraform Command: destroy
51
+ def self.destroy(options:, working_directory:)
52
+ create(
53
+ options: options,
54
+ subcommand: "destroy",
55
+ working_directory: working_directory
56
+ )
57
+ end
58
+
59
+ # Creates the init command shell out.
60
+ #
61
+ # @param options [::Kitchen::Terraform::Client::Options] options for the command.
62
+ # @param working_directory[::String] the path to the directory in which to run the shell out.
63
+ # @return [::Dry::Monads::Either] the result of creating the shell out.
64
+ # @see https://www.terraform.io/docs/commands/destroy.html Terraform Command: init
65
+ def self.init(options:, working_directory:)
66
+ create(
67
+ options: options,
68
+ subcommand: "init",
69
+ working_directory: working_directory
70
+ )
71
+ end
72
+
73
+ # Creates the output command shell out.
74
+ #
75
+ # @param options [::Kitchen::Terraform::Client::Options] options for the command.
76
+ # @param working_directory[::String] the path to the directory in which to run the shell out.
77
+ # @return [::Dry::Monads::Either] the result of creating the shell out.
78
+ # @see https://www.terraform.io/docs/commands/destroy.html Terraform Command: output
79
+ def self.output(options:, working_directory:)
80
+ create(
81
+ options: options,
82
+ subcommand: "output",
83
+ working_directory: working_directory
84
+ )
85
+ end
86
+
87
+ # Runs a command shell out.
88
+ #
89
+ # @param logger [::Kitchen::Logger, ::Terraform::DebugLogger] a logger to capture the run output of the command.
90
+ # @param shell_out [::Mixlib::ShellOut] the shell out to run.
91
+ # @param timeout [::Integer] the number of seconds to wait for the command to finish.
92
+ # @return [::Dry::Monads::Either] the result of running the shell out.
93
+ def self.run(logger:, shell_out:, timeout:)
94
+ try_to_run(
95
+ logger: logger,
96
+ shell_out: shell_out,
97
+ timeout: timeout
98
+ )
99
+ .bind do
100
+ Right shell_out.stdout
101
+ end
102
+ .or do |error|
103
+ Left error.to_s
104
+ end
105
+ end
106
+
107
+ # Creates the validate command shell out.
108
+ #
109
+ # @param options [::Kitchen::Terraform::Client::Options] options for the command.
110
+ # @param working_directory[::String] the path to the directory in which to run the shell out.
111
+ # @return [::Dry::Monads::Either] the result of creating the shell out.
112
+ # @see https://www.terraform.io/docs/commands/destroy.html Terraform Command: validate
113
+ def self.validate(options:, working_directory:)
114
+ create(
115
+ options: options,
116
+ subcommand: "validate",
117
+ working_directory: working_directory
118
+ )
119
+ end
120
+
121
+ # Creates the version command shell out.
122
+ #
123
+ # @param options [::Kitchen::Terraform::Client::Options] options for the command.
124
+ # @param working_directory[::String] the path to the directory in which to run the shell out.
125
+ # @return [::Dry::Monads::Either] the result of creating the shell out.
126
+ # @see https://www.terraform.io/docs/commands/destroy.html Terraform Command: version
127
+ def self.version(options: ::Kitchen::Terraform::Client::Options, working_directory:)
128
+ create(
129
+ options: options,
130
+ subcommand: "version",
131
+ working_directory: working_directory
132
+ )
133
+ end
134
+
135
+ private_class_method
136
+
137
+ # @api private
138
+ # @param options [::Kitchen::Terraform::Client::Options] options for the command.
139
+ # @param subcommand [::String] the subcommand to run through shell out.
140
+ # @param working_directory [::String] the path to the directory in which to run the shell out.
141
+ def self.create(options:, subcommand:, working_directory:)
142
+ Try ::Mixlib::ShellOut::InvalidCommandOption do
143
+ ::Mixlib::ShellOut.new(
144
+ "terraform #{subcommand} #{options}".strip,
145
+ cwd: working_directory
146
+ )
147
+ end
148
+ .to_either
149
+ .or do |error|
150
+ Left "Failed to create `terraform #{subcommand}`: #{error}"
151
+ end
152
+ end
153
+
154
+ def self.try_to_run(logger:, shell_out:, timeout:)
155
+ Try(
156
+ ::Errno::EACCES,
157
+ ::Errno::ENOENT,
158
+ ::Mixlib::ShellOut::CommandTimeout,
159
+ ::Mixlib::ShellOut::ShellCommandFailed
160
+ ) do
161
+ shell_out.live_stream = logger
162
+ shell_out.timeout = timeout
163
+ shell_out.run_command
164
+ shell_out.error!
165
+ end
166
+ .to_either
167
+ end
168
+ end
@@ -0,0 +1,275 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2016 New Context Services, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require "kitchen/terraform/client"
18
+
19
+ # Represents supported options for client commands.
20
+ class ::Kitchen::Terraform::Client::Options
21
+ # Adds -backend-config with arguments to the options.
22
+ #
23
+ # @param key [#to_s] the backend configuration key
24
+ # @param value [#to_s] the backend configuration value
25
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
26
+ def backend_config(key:, value:)
27
+ add option: "-backend-config='#{key}=#{value}'"
28
+ end
29
+
30
+ # Adds -backend-config with arguments to the options multiple times.
31
+ #
32
+ # @param keys_and_values [::Hash<#to_s, #to_s>] the backend configuration keys and values
33
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
34
+ def backend_configs(keys_and_values:)
35
+ keys_and_values
36
+ .inject self do |additional_options, (key, value)|
37
+ additional_options
38
+ .backend_config(
39
+ key: key,
40
+ value: value
41
+ )
42
+ end
43
+ end
44
+
45
+ # Adds -input=false to the options.
46
+ #
47
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
48
+ def disable_input
49
+ add option: "-input=false"
50
+ end
51
+
52
+ # Adds -auto-approve=true to the options.
53
+ #
54
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
55
+ def enable_auto_approve
56
+ add option: "-auto-approve=true"
57
+ end
58
+
59
+ # Adds -backend=true to the options.
60
+ #
61
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
62
+ def enable_backend
63
+ add option: "-backend=true"
64
+ end
65
+
66
+ # Adds -check-variables=true to the options.
67
+ #
68
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
69
+ def enable_check_variables
70
+ add option: "-check-variables=true"
71
+ end
72
+
73
+ # Adds -get=true to the options.
74
+ #
75
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
76
+ def enable_get
77
+ add option: "-get=true"
78
+ end
79
+
80
+ # Adds -force to the options.
81
+ #
82
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
83
+ def force
84
+ add option: "-force"
85
+ end
86
+
87
+ # Adds -force-copy to the options.
88
+ #
89
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
90
+ def force_copy
91
+ add option: "-force-copy"
92
+ end
93
+
94
+ # Adds -from-module with an argument to the options.
95
+ #
96
+ # @param source [#to_s] the module source
97
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
98
+ def from_module(source:)
99
+ add option: "-from-module=#{source}"
100
+ end
101
+
102
+ # Adds -json to the options.
103
+ #
104
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
105
+ def json
106
+ add option: "-json"
107
+ end
108
+
109
+ # Adds -lock=true to the options.
110
+ #
111
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
112
+ def enable_lock
113
+ add option: "-lock=true"
114
+ end
115
+
116
+ # Adds -refresh=true to the options.
117
+ #
118
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
119
+ def enable_refresh
120
+ add option: "-refresh=true"
121
+ end
122
+
123
+ # Adds -lock-timeout with an argument to the options.
124
+ #
125
+ # @param duration [#to_s] the lock timeout duration
126
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
127
+ def lock_timeout(duration:)
128
+ add option: "-lock-timeout=#{duration}"
129
+ end
130
+
131
+ # Conditionally adds -no-color to the options.
132
+ #
133
+ # @param toggle [::TrueClass, ::FalseClass] the flag toggle
134
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
135
+ def maybe_no_color(toggle:)
136
+ toggle and no_color or self
137
+ end
138
+
139
+ # Conditionally adds -plugin-dir to the options.
140
+ #
141
+ # @param path [::TrueClass, ::FalseClass] the path to the plugin directory
142
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
143
+ def maybe_plugin_dir(path:)
144
+ path and plugin_dir path: path or self
145
+ end
146
+
147
+ # Adds -no-color to the options.
148
+ #
149
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
150
+ def no_color
151
+ add option: "-no-color"
152
+ end
153
+
154
+ # Adds -parallelism with an argument to the options.
155
+ #
156
+ # @param concurrent_operations [#to_s] the number of concurrent operations
157
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
158
+ def parallelism(concurrent_operations:)
159
+ add option: "-parallelism=#{concurrent_operations}"
160
+ end
161
+
162
+ # Adds -plugin-dir with an argument to the options.
163
+ #
164
+ # @param path [#to_s] the path to the plugin directory
165
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
166
+ def plugin_dir(path:)
167
+ add option: "-plugin-dir=#{path}"
168
+ end
169
+
170
+ # Adds -state with an argument to the options.
171
+ #
172
+ # @param path [#to_s] the path to the input state file
173
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
174
+ def state(path:)
175
+ add option: "-state=#{path}"
176
+ end
177
+
178
+ # Adds -state-out with an argument to the options.
179
+ #
180
+ # @param path [#to_s] the path to the output state file
181
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
182
+ def state_out(path:)
183
+ add option: "-state-out=#{path}"
184
+ end
185
+
186
+ # Adds -upgrade to the options.
187
+ #
188
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
189
+ def upgrade
190
+ add option: "-upgrade"
191
+ end
192
+
193
+ # Adds -var with arguments to the options.
194
+ #
195
+ # @param key [#to_s] the variable key
196
+ # @param value [#to_s] the variable value
197
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
198
+ def var(key:, value:)
199
+ add option: "-var='#{key}=#{value}'"
200
+ end
201
+
202
+ # Adds -var with arguments to the options multiple times.
203
+ #
204
+ # @param keys_and_values [::Hash<#to_s, #to_s>] the variable keys and values
205
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
206
+ def vars(keys_and_values:)
207
+ keys_and_values
208
+ .inject self do |additional_options, (key, value)|
209
+ additional_options
210
+ .var(
211
+ key: key,
212
+ value: value
213
+ )
214
+ end
215
+ end
216
+
217
+ # Adds -var-file with an argument to the options.
218
+ #
219
+ # @param path [#to_s] the path to the variable file
220
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
221
+ def var_file(path:)
222
+ add option: "-var-file=#{path}"
223
+ end
224
+
225
+ # Adds -var-file with an argument to the options multiple times.
226
+ #
227
+ # @param paths [::Array<#to_s>] the paths to the variable files
228
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
229
+ def var_files(paths:)
230
+ paths
231
+ .inject self do |additional_options, path|
232
+ additional_options.var_file path: path
233
+ end
234
+ end
235
+
236
+ # Adds -verify-plugins with an argument to the options.
237
+ #
238
+ # @param toggle [#to_s] toggle to enable or disable
239
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
240
+ def verify_plugins(toggle:)
241
+ add option: "-verify-plugins=#{toggle}"
242
+ end
243
+
244
+ # The options expressed as a space delimited string.
245
+ #
246
+ # @return [::String] the options string
247
+ def to_s
248
+ @options.join " "
249
+ end
250
+
251
+ private
252
+
253
+ # Adds an option to the collection.
254
+ #
255
+ # @api private
256
+ # @param option [::String] the option to be added
257
+ # @return [::Kitchen::Terraform::Client::Options] the expanded options
258
+ def add(option:)
259
+ self
260
+ .class
261
+ .new(
262
+ option: option,
263
+ options: @options
264
+ )
265
+ end
266
+
267
+ # Initializes the collection of options.
268
+ #
269
+ # @api private
270
+ # @param option [::String] a new option to add to the collection.
271
+ # @param options [::Array] the current collection
272
+ def initialize(option: nil, options: [])
273
+ @options = options + [option].compact
274
+ end
275
+ end