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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7859976b571d449f146dc4b4a83703df3b8d96c5
4
- data.tar.gz: 9ce06a6a5ff1b398e0d98173bbc3c16c04c738e1
3
+ metadata.gz: bf0dc03c57101fc1ec8ea5a7910687185af00612
4
+ data.tar.gz: e0388efadde2ab8ee75d2cd47289c9d96a910e74
5
5
  SHA512:
6
- metadata.gz: 82db1d8b35049b2a0c2f0270722da4850680f552c38918390c2279dbfbd161a031eadec9c5c525facd4f131a6cb0ec12a33771a79e1aff496e689a7a28d02e3a
7
- data.tar.gz: 0fc52a6a09ad2bc8774c86a21aaa9535bcb43471e6ca4fd18bf54a3906a559590f98c4d9280376f29c60dbf639ce1cb9f8ffa9f6472ec1a20381f8c0541a6419
6
+ metadata.gz: 64d24a44a89f19009e8d9e32882688d6d9d9e02490d9a2755cec8ff0e9f098be0aa8000a5da35516833bd561ae4599162bce62065faa38e2ac888f8126bc85ee
7
+ data.tar.gz: 26382da8eca826218c70450749969b7c734fbea01e32d8b0ab19ac6a2bae8b713582ee3b6641a45347f2d0ba3b2e254bf7c636d201d87c8136c10b7dae88b95f
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -11,11 +11,11 @@ kitchen-terraform is a set of [Test Kitchen] plugins for testing
11
11
 
12
12
  ## Requirements
13
13
 
14
- - [Ruby] **(~> 2.1)**
14
+ - [Ruby] **(~> 2.2)**
15
15
 
16
16
  - [Bundler] **(~> 1.12)**
17
17
 
18
- - [Terraform] **(>= 0.7, < 0.10)**
18
+ - [Terraform] **(~> 0.10.2)**
19
19
 
20
20
  ## Installation
21
21
 
@@ -29,7 +29,7 @@ Gemfile:
29
29
 
30
30
  ```rb
31
31
  source "https://rubygems.org/" do
32
- gem "kitchen-terraform", "~> 1.0"
32
+ gem "kitchen-terraform", "~> 2.0"
33
33
  end
34
34
  ```
35
35
 
@@ -15,278 +15,420 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require "dry/monads"
18
+ require "fileutils"
19
+ require "json"
18
20
  require "kitchen"
19
- require "kitchen/terraform/client/output"
20
- require "kitchen/terraform/client/plan"
21
- require "kitchen/terraform/client/version"
22
- require "kitchen/terraform/define_config_attribute"
23
- require "kitchen/terraform/define_integer_config_attribute"
24
- require "kitchen/terraform/define_string_config_attribute"
25
- require "terraform/configurable"
26
-
27
- # The kitchen-terraform driver is the bridge between Test Kitchen and Terraform. It manages the state of the configured
28
- # root Terraform module by invoking its workflow in a constructive or destructive manner.
21
+ require "kitchen/terraform/clear_directory"
22
+ require "kitchen/terraform/client/command"
23
+ require "kitchen/terraform/client/options"
24
+ require "kitchen/terraform/client_version_verifier"
25
+ require "kitchen/terraform/config_attribute/backend_configurations"
26
+ require "kitchen/terraform/config_attribute/color"
27
+ require "kitchen/terraform/config_attribute/command_timeout"
28
+ require "kitchen/terraform/config_attribute/directory"
29
+ require "kitchen/terraform/config_attribute/lock_timeout"
30
+ require "kitchen/terraform/config_attribute/parallelism"
31
+ require "kitchen/terraform/config_attribute/plugin_directory"
32
+ require "kitchen/terraform/config_attribute/state"
33
+ require "kitchen/terraform/config_attribute/variable_files"
34
+ require "kitchen/terraform/config_attribute/variables"
35
+ require "kitchen/terraform/config_attribute/verify_plugins"
36
+ require "kitchen/terraform/create_directories"
37
+ require "kitchen/terraform/configurable"
38
+
39
+ # The kitchen-terraform driver is the bridge between Test Kitchen and Terraform.
40
+ #
41
+ # It manages the state of the configured root Terraform module by invoking its workflow in a constructive or destructive
42
+ # manner.
43
+ #
44
+ # === Test Kitchen Configuration
45
+ #
46
+ # The configuration of the driver is used to control the behaviour of the Terraform Client commands.
29
47
  #
30
- # === Configuration
48
+ # More information about the available configuration attributes is located with the respective modules.
31
49
  #
32
- # ==== Example .kitchen.yml snippet
50
+ # Test Kitchen configuration is defined in +.kitchen.yml+ and optionally overridden in +.kitchen.local.yml+.
51
+ #
52
+ # ==== Example
33
53
  #
34
54
  # driver:
35
- # name: terraform
55
+ # name: "terraform"
56
+ # backend_configurations:
57
+ # argument_name: "argument_value"
36
58
  # command_timeout: 1000
37
- # cli: /usr/local/bin/terraform
38
59
  # color: false
39
- # directory: /directory/containing/terraform/configuration
60
+ # directory: "/directory/containing/terraform/configuration"
61
+ # lock_timeout: 2000
40
62
  # parallelism: 2
41
- # plan: /terraform/plan
42
- # state: /terraform/state
63
+ # plugin_directory: "/plugin/directory"
64
+ # state: "/terraform/state"
43
65
  # variable_files:
44
- # - /first/terraform/variable/file
45
- # - /second/terraform/variable/file
66
+ # - "/first/terraform/variable/file"
67
+ # - "/second/terraform/variable/file"
46
68
  # variables:
47
- # variable_name: variable_value
48
- #
49
- # ==== Attributes
50
- #
51
- # ===== cli
52
- #
53
- # Description:: The path of the Terraform CLI to use for command execution.
54
- #
55
- # Type:: String
56
- #
57
- # Status:: Optional
58
- #
59
- # Default:: +"terraform"+
60
- #
61
- # ===== color
62
- #
63
- # Description:: Toggle to enable or disable colored output from the Terraform CLI commands.
64
- #
65
- # Type:: Boolean
66
- #
67
- # Status:: Optional
68
- #
69
- # Default:: +true+ if the Test Kitchen process is associated with a terminal device (tty); +false+ if it is not.
70
- #
71
- # ===== command_timeout
72
- #
73
- # Description:: The number of seconds to wait for the Terraform CLI commands to finish.
74
- #
75
- # Type:: Integer
76
- #
77
- # Status:: Optional
78
- #
79
- # Default:: +600+
80
- #
81
- # ===== directory
82
- #
83
- # Description:: The path of the directory containing the root Terraform module to be tested.
84
- #
85
- # Type:: String
86
- #
87
- # Status:: Optional
88
- #
89
- # Default:: The working directory of the Test Kitchen process.
90
- #
91
- # ===== parallelism
92
- #
93
- # Description:: The maximum number of concurrent operations to allow while walking the resource graph for the Terraform
94
- # CLI apply and plan commands.
95
- # Type:: Integer
96
- #
97
- # Status:: Optional
98
- #
99
- # Default:: +10+
100
- #
101
- # ===== plan
102
- #
103
- # Description:: The path of the Terraform execution plan that will be generated and applied.
104
- #
105
- # Type:: String
106
- #
107
- # Status:: Optional
108
- #
109
- # Default:: A descendant of the working directory of the Test Kitchen process:
110
- # +".kitchen/kitchen-terraform/<suite_name>/terraform.tfplan"+
111
- #
112
- # ===== state
113
- #
114
- # Description:: The path of the Terraform state that will be generated and managed.
115
- #
116
- # Type:: String
117
- #
118
- # Status:: Optional
119
- #
120
- # Default:: A descendant of the working directory of the Test Kitchen process:i
121
- # +".kitchen/kitchen-terraform/<suite_name>/terraform.tfstate"+.
122
- #
123
- # ===== variable_files
124
- #
125
- # Description:: A collection of paths of Terraform variable files to be evaluated during the creation of the Terraform
126
- # execution plan.
127
- #
128
- # Type:: Array
129
- #
130
- # Status:: Optional
131
- #
132
- # Default:: +[]+
133
- #
134
- # ===== variables
135
- #
136
- # Description:: A mapping of Terraform variable names and values to be overridden during the creation of the Terraform
137
- # execution plan.
138
- #
139
- # Type:: Hash
140
- #
141
- # Status:: Optional
142
- #
143
- # Default:: +{}+
144
- #
145
- # @see ::Kitchen::Driver::Terraform::Workflow
146
- # @see https://en.wikipedia.org/wiki/Working_directory Working directory
147
- # @see https://www.terraform.io/docs/commands/plan.html Terraform execution plan
148
- # @see https://www.terraform.io/docs/configuration/variables.html Terraform variables
149
- # @see https://www.terraform.io/docs/internals/graph.html Terraform resource graph
150
- # @see https://www.terraform.io/docs/state/index.html Terraform state
69
+ # variable_name: "variable_value"
70
+ # verify_plugins: false
71
+ #
72
+ # @see ::Kitchen::Terraform::Client::Command
73
+ # @see ::Kitchen::Terraform::ConfigAttribute::BackendConfigurations
74
+ # @see ::Kitchen::Terraform::ConfigAttribute::CommandTimeout
75
+ # @see ::Kitchen::Terraform::ConfigAttribute::Color
76
+ # @see ::Kitchen::Terraform::ConfigAttribute::Directory
77
+ # @see ::Kitchen::Terraform::ConfigAttribute::LockTimeout
78
+ # @see ::Kitchen::Terraform::ConfigAttribute::Parallelism
79
+ # @see ::Kitchen::Terraform::ConfigAttribute::PluginDirectory
80
+ # @see ::Kitchen::Terraform::ConfigAttribute::State
81
+ # @see ::Kitchen::Terraform::ConfigAttribute::VariableFiles
82
+ # @see ::Kitchen::Terraform::ConfigAttribute::Variables
83
+ # @see ::Kitchen::Terraform::ConfigAttribute::VerifyPlugins
84
+ # @see http://kitchen.ci/docs/getting-started/kitchen-yml Test Kitchen: .kitchen.yml
151
85
  # @version 2
152
86
  class ::Kitchen::Driver::Terraform < ::Kitchen::Driver::Base
153
87
  kitchen_driver_api_version 2
154
88
 
155
89
  no_parallel_for
156
90
 
157
- ::Kitchen::Terraform::DefineStringConfigAttribute.call attribute: :cli,
158
- plugin_class: self do
159
- "terraform"
160
- end
91
+ include ::Dry::Monads::Either::Mixin
161
92
 
162
- ::Kitchen::Terraform::DefineIntegerConfigAttribute.call attribute: :command_timeout,
163
- plugin_class: self do
164
- 600
165
- end
93
+ include ::Dry::Monads::Try::Mixin
166
94
 
167
- ::Kitchen::Terraform::DefineConfigAttribute.call(
168
- attribute: :color,
169
- initialize_default_value: lambda do |_plugin|
170
- ::Kitchen.tty?
171
- end,
172
- plugin_class: self,
173
- schema: lambda do
174
- required(:value).filled :bool?
175
- end
176
- )
95
+ include ::Kitchen::Terraform::ConfigAttribute::BackendConfigurations
177
96
 
178
- ::Kitchen::Terraform::DefineStringConfigAttribute.call attribute: :directory,
179
- plugin_class: self do |plugin|
180
- plugin[:kitchen_root]
181
- end
97
+ include ::Kitchen::Terraform::ConfigAttribute::Color
182
98
 
183
- ::Kitchen::Terraform::DefineIntegerConfigAttribute.call attribute: :parallelism,
184
- plugin_class: self do
185
- 10
186
- end
99
+ include ::Kitchen::Terraform::ConfigAttribute::CommandTimeout
187
100
 
188
- ::Kitchen::Terraform::DefineStringConfigAttribute.call attribute: :plan,
189
- plugin_class: self do |plugin|
190
- plugin.instance_pathname filename: "terraform.tfplan"
191
- end
101
+ include ::Kitchen::Terraform::ConfigAttribute::Directory
192
102
 
193
- ::Kitchen::Terraform::DefineStringConfigAttribute.call attribute: :state,
194
- plugin_class: self do |plugin|
195
- plugin.instance_pathname filename: "terraform.tfstate"
196
- end
103
+ include ::Kitchen::Terraform::ConfigAttribute::LockTimeout
197
104
 
198
- ::Kitchen::Terraform::DefineConfigAttribute.call(
199
- attribute: :variable_files,
200
- initialize_default_value: lambda do |_plugin|
201
- []
202
- end,
203
- plugin_class: self,
204
- schema: lambda do
205
- required(:value).each :filled?, :str?
206
- end
207
- )
208
-
209
- ::Kitchen::Terraform::DefineConfigAttribute.call(
210
- attribute: :variables,
211
- initialize_default_value: lambda do |_plugin|
212
- {}
213
- end,
214
- plugin_class: self,
215
- schema: lambda do
216
- required(:value).value :hash?
217
- end
218
- )
105
+ include ::Kitchen::Terraform::ConfigAttribute::Parallelism
106
+
107
+ include ::Kitchen::Terraform::ConfigAttribute::PluginDirectory
108
+
109
+ include ::Kitchen::Terraform::ConfigAttribute::State
110
+
111
+ include ::Kitchen::Terraform::ConfigAttribute::VariableFiles
112
+
113
+ include ::Kitchen::Terraform::ConfigAttribute::Variables
114
+
115
+ include ::Kitchen::Terraform::ConfigAttribute::VerifyPlugins
219
116
 
220
- include ::Terraform::Configurable
117
+ include ::Kitchen::Terraform::Configurable
221
118
 
222
- # The driver invokes its workflow in a constructive manner.
119
+ # The driver invokes its workflow in a constructive manner by applying changes to the Terraform state.
223
120
  #
224
121
  # @example
122
+ # `kitchen help create`
123
+ # @example
225
124
  # `kitchen create suite-name`
226
- # @note The user must ensure that different suites utilize separate Terraform plan and state files if they are to run
125
+ # @note The user must ensure that different suites utilize separate Terraform state files if they are to run
227
126
  # the create action concurrently.
228
- # @param _state [::Hash] the mutable instance and driver state; this parameter is ignored.
127
+ # @param _state [::Hash] the mutable instance and driver state.
229
128
  # @raise [::Kitchen::ActionFailed] if the result of the action is a failure.
230
- # @return [::Dry::Monads::Either] the result of the workflow function.
231
- # @see ::Kitchen::Driver::Terraform::Workflow
129
+ # @see ::Kitchen::Driver::Terraform#run_apply
130
+ # @see ::Kitchen::Driver::Terraform#workflow
232
131
  def create(_state)
233
- self.class::Workflow.call(
234
- config: config,
235
- logger: logger
236
- ).or do |failure|
237
- raise ::Kitchen::ActionFailed, failure
132
+ workflow do
133
+ run_apply
238
134
  end
239
135
  end
240
136
 
241
- # The driver invokes its workflow in a destructive manner.
137
+ # The driver invokes its workflow in a destructive manner by destroying the Terraform state and removing the instance
138
+ # directory.
242
139
  #
243
140
  # @example
141
+ # `kitchen help destroy`
142
+ # @example
244
143
  # `kitchen destroy suite-name`
245
- # @note The user must ensure that different suites utilize separate Terraform plan and state files if they are to run
144
+ # @note The user must ensure that different suites utilize separate Terraform state files if they are to run
246
145
  # the destroy action concurrently.
247
- # @param _state [::Hash] the mutable instance and driver state; this parameter is ignored.
146
+ # @param _state [::Hash] the mutable instance and driver state.
248
147
  # @raise [::Kitchen::ActionFailed] if the result of the action is a failure.
249
- # @return [::Dry::Monads::Either] the result of the action.
250
- # @see ::Kitchen::Driver::Terraform::Workflow
148
+ # @see ::Kitchen::Driver::Terraform#remove_instance_directory
149
+ # @see ::Kitchen::Driver::Terraform#run_destroy
150
+ # @see ::Kitchen::Driver::Terraform#workflow
251
151
  def destroy(_state)
252
- self.class::Workflow.call(
253
- config: config,
254
- destroy: true,
255
- logger: logger
256
- ).or do |failure|
257
- raise ::Kitchen::ActionFailed, failure
152
+ workflow do
153
+ run_destroy.bind do
154
+ remove_instance_directory
155
+ end
258
156
  end
259
157
  end
260
158
 
261
- # The driver proxies the client output function.
159
+ # The driver parses the Terraform Client output subcomannd output as JSON.
262
160
  #
263
- # @return [::Dry::Monads::Either] the result of the Terraform Client Output function.
264
- # @see ::Kitchen::Terraform::Client::Output
161
+ # @return [::Dry::Monads::Either] the result of parsing the output.
162
+ # @see ::Kitchen::Terraform::Client::Command.Output
163
+ # @see ::JSON.parse
265
164
  def output
266
- ::Kitchen::Terraform::Client::Output.call cli: config.fetch(:cli), logger: debug_logger,
267
- options: {color: config.fetch(:color), state: config.fetch(:state)},
268
- timeout: config.fetch(:command_timeout)
165
+ run_output
166
+ .bind do |output|
167
+ Try ::JSON::ParserError do
168
+ ::JSON.parse output
169
+ end
170
+ .to_either
171
+ end
172
+ .or do |error|
173
+ Left "parsing Terraform client output as JSON failed\n#{error}"
174
+ end
269
175
  end
270
176
 
271
177
  # The driver verifies that the client version is supported.
272
178
  #
273
179
  # @raise [::Kitchen::UserError] if the version is not supported.
274
- # @return [::Dry::Monads::Either] the result of the client version verification function.
275
- # @see ::Kitchen::Driver::Terraform::VerifyClientVersion
276
- # @see ::Kitchen::Terraform::Client::Version
180
+ # @see ::Kitchen::Terraform::Client::Command.version
181
+ # @see ::Kitchen::Terraform::ClientVersionVerifier#verify
277
182
  def verify_dependencies
278
- ::Kitchen::Terraform::Client::Version.call(
279
- cli: config.fetch(:cli), logger: debug_logger, timeout: config.fetch(:command_timeout)
280
- ).bind do |version|
281
- self.class::VerifyClientVersion.call version: version
282
- end.fmap do |verified_client_version|
283
- logger.warn verified_client_version
284
- verified_client_version
285
- end.or do |failure|
286
- raise ::Kitchen::UserError, failure
183
+ run_version
184
+ .bind do |output|
185
+ ::Kitchen::Terraform::ClientVersionVerifier
186
+ .new
187
+ .verify version_output: output
188
+ end
189
+ .bind do |verified_client_version|
190
+ Right logger.warn verified_client_version
191
+ end
192
+ .or do |failure|
193
+ raise(
194
+ ::Kitchen::UserError,
195
+ failure
196
+ )
197
+ end
198
+ end
199
+
200
+ private
201
+
202
+ # The driver creates the instance directory or clears it of Terraform configuration if it already exists.
203
+ #
204
+ # @api private
205
+ # @return [::Dry::Monads::Either] the result of creating or clearing the instance directory.
206
+ # @see ::KItchen::Terraform::ClearDirectory.call
207
+ # @see ::Kitchen::Driver::Terraform#instance_directory
208
+ # @see ::Kitchen::Terraform::CreateDirectories.call
209
+ def prepare_instance_directory
210
+ ::Kitchen::Terraform::CreateDirectories
211
+ .call(
212
+ directories: [instance_directory]
213
+ )
214
+ .bind do |created_directories|
215
+ logger.debug created_directories
216
+ ::Kitchen::Terraform::ClearDirectory
217
+ .call(
218
+ directory: instance_directory,
219
+ files: [
220
+ "*.tf",
221
+ "*.tf.json"
222
+ ]
223
+ )
224
+ end
225
+ .bind do |cleared_directory|
226
+ Right logger.debug cleared_directory
227
+ end
228
+ end
229
+
230
+ # The driver removes the instance directory.
231
+ #
232
+ # @api private
233
+ # @see ::FileUtils.remove_dir
234
+ # @see ::Kitchen::Driver::Terraform#instance_directory
235
+ def remove_instance_directory
236
+ Try do
237
+ ::FileUtils.remove_dir instance_directory
287
238
  end
239
+ .to_either
240
+ end
241
+
242
+ # Runs a Terraform Client command shell out with the default logger and the configured timeout.
243
+ #
244
+ # @api private
245
+ # @param result [::Dry::Monads::Either] the result of a shell out creation
246
+ # @return [::Dry::Monads::Either] the result of running the shell out
247
+ def run(result:)
248
+ result
249
+ .bind do |shell_out|
250
+ ::Kitchen::Terraform::Client::Command
251
+ .run(
252
+ logger: logger,
253
+ shell_out: shell_out,
254
+ timeout: config_command_timeout
255
+ )
256
+ end
288
257
  end
289
- end
290
258
 
291
- require "kitchen/driver/terraform/workflow"
292
- require "kitchen/driver/terraform/verify_client_version"
259
+ # Runs the Terraform Client apply subcommand.
260
+ #
261
+ # @api private
262
+ # @return [::Dry::Monads::Either] the result of the apply subcommand.
263
+ # @see ::Kitchen::Terraform::Client::Command.apply
264
+ def run_apply
265
+ run(
266
+ result:
267
+ ::Kitchen::Terraform::Client::Command
268
+ .apply(
269
+ options:
270
+ ::Kitchen::Terraform::Client::Options
271
+ .new
272
+ .enable_lock
273
+ .lock_timeout(duration: config_lock_timeout)
274
+ .disable_input
275
+ .enable_auto_approve
276
+ .maybe_no_color(toggle: !config_color)
277
+ .parallelism(concurrent_operations: config_parallelism)
278
+ .enable_refresh
279
+ .state(path: config_state)
280
+ .state_out(path: config_state)
281
+ .vars(keys_and_values: config_variables)
282
+ .var_files(paths: config_variable_files),
283
+ working_directory: instance_directory
284
+ )
285
+ )
286
+ end
287
+
288
+ # Runs the Terraform Client destroy subcommand.
289
+ #
290
+ # @api private
291
+ # @return [::Dry::Monads::Either] the result of the destroy subcommand.
292
+ # @see ::Kitchen::Terraform::Client::Command.destroy
293
+ def run_destroy
294
+ run(
295
+ result:
296
+ ::Kitchen::Terraform::Client::Command
297
+ .destroy(
298
+ options:
299
+ ::Kitchen::Terraform::Client::Options
300
+ .new
301
+ .enable_lock
302
+ .lock_timeout(duration: config_lock_timeout)
303
+ .disable_input
304
+ .maybe_no_color(toggle: !config_color)
305
+ .parallelism(concurrent_operations: config_parallelism)
306
+ .enable_refresh
307
+ .state(path: config_state)
308
+ .state_out(path: config_state)
309
+ .vars(keys_and_values: config_variables)
310
+ .var_files(paths: config_variable_files)
311
+ .force,
312
+ working_directory: instance_directory
313
+ )
314
+ )
315
+ end
316
+
317
+ # Runs the Terraform Client init subcommand.
318
+ #
319
+ # @api private
320
+ # @return [::Dry::Monads::Either] the result of the init subcommand.
321
+ # @see ::Kitchen::Terraform::Client::Command.init
322
+ def run_init
323
+ run(
324
+ result:
325
+ ::Kitchen::Terraform::Client::Command
326
+ .init(
327
+ options:
328
+ ::Kitchen::Terraform::Client::Options
329
+ .new
330
+ .disable_input
331
+ .enable_lock
332
+ .lock_timeout(duration: config_lock_timeout)
333
+ .maybe_no_color(toggle: !config_color)
334
+ .upgrade
335
+ .from_module(source: config_directory)
336
+ .enable_backend
337
+ .force_copy
338
+ .backend_configs(keys_and_values: config_backend_configurations)
339
+ .enable_get
340
+ .maybe_plugin_dir(path: config_plugin_directory)
341
+ .verify_plugins(toggle: config_verify_plugins),
342
+ working_directory: instance_directory
343
+ )
344
+ )
345
+ end
346
+
347
+ # Runs the Terraform Client output subcommand.
348
+ #
349
+ # @api private
350
+ # @return [::Dry::Monads::Either] the result of the init subcommand.
351
+ # @see ::Kitchen::Terraform::Client::Command.output
352
+ def run_output
353
+ run(
354
+ result:
355
+ ::Kitchen::Terraform::Client::Command.output(
356
+ options:
357
+ ::Kitchen::Terraform::Client::Options
358
+ .new
359
+ .json
360
+ .state(path: config_state),
361
+ working_directory: instance_directory
362
+ )
363
+ )
364
+ end
365
+
366
+ # Runs the Terraform Client validate subcommand.
367
+ #
368
+ # @api private
369
+ # @return [::Dry::Monads::Either] the result of the validate subcommand.
370
+ # @see ::Kitchen::Terraform::Client::Command.validate
371
+ def run_validate
372
+ run(
373
+ result:
374
+ ::Kitchen::Terraform::Client::Command
375
+ .validate(
376
+ options:
377
+ ::Kitchen::Terraform::Client::Options
378
+ .new
379
+ .enable_check_variables
380
+ .maybe_no_color(toggle: !config_color)
381
+ .vars(keys_and_values: config_variables)
382
+ .var_files(paths: config_variable_files),
383
+ working_directory: instance_directory
384
+ )
385
+ )
386
+ end
387
+
388
+ # Runs the Terraform Client version subcommand.
389
+ #
390
+ # @api private
391
+ # @return [::Dry::Monads::Either] the result of the version subcommand.
392
+ # @see ::Kitchen::Terraform::Client::Command.version
393
+ def run_version
394
+ run result: ::Kitchen::Terraform::Client::Command.version(working_directory: config.fetch(:kitchen_root))
395
+ end
396
+
397
+ # Memoizes the path to the Test Kitchen suite instance directory at `.kitchen/kitchen-terraform/<suite>-<platform>`.
398
+ #
399
+ # @api private
400
+ # @return [::String] the path to the Test Kitchen suite instance directory.
401
+ def instance_directory
402
+ @instance_directory ||= instance_pathname filename: "/"
403
+ end
404
+
405
+ # 1. Prepares the instance directory
406
+ # 2. Executes `terraform init` in the instance directory
407
+ # 3. Executes `terraform validate` in the instance directory
408
+ # 4. Executes a provided subcommand in the instance directory
409
+ #
410
+ # @api private
411
+ # @raise [::Kitchen::ActionFailed] if the result of the action is a failure.
412
+ # @see ::Kitchen::Driver::Terraform#prepare_instance_directory
413
+ # @see ::Kitchen::Driver::Terraform#run_init
414
+ # @see ::Kitchen::Driver::Terraform#run_validate
415
+ # @yieldreturn [::Dry::Monads::Either] the result of a Terraform Client subcommand.
416
+ def workflow
417
+ prepare_instance_directory
418
+ .bind do
419
+ run_init
420
+ end
421
+ .bind do
422
+ run_validate
423
+ end
424
+ .bind do
425
+ yield
426
+ end
427
+ .or do |failure|
428
+ raise(
429
+ ::Kitchen::ActionFailed,
430
+ failure
431
+ )
432
+ end
433
+ end
434
+ end