kitchen-terraform 1.0.2 → 2.0.0

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