kitchen-terraform 0.7.0 → 1.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +3 -1
- data/README.md +33 -359
- data/lib/kitchen/driver/terraform.rb +273 -57
- data/lib/kitchen/driver/terraform/verify_client_version.rb +44 -0
- data/lib/kitchen/driver/terraform/workflow.rb +90 -0
- data/lib/kitchen/provisioner/terraform.rb +31 -37
- data/lib/{terraform/get_command.rb → kitchen/terraform.rb} +3 -5
- data/lib/{terraform/deprecated_version.rb → kitchen/terraform/client.rb} +5 -12
- data/lib/kitchen/terraform/client/apply.rb +38 -0
- data/lib/kitchen/terraform/client/execute_command.rb +56 -0
- data/lib/kitchen/terraform/client/get.rb +35 -0
- data/lib/kitchen/terraform/client/output.rb +50 -0
- data/lib/kitchen/terraform/client/plan.rb +42 -0
- data/lib/kitchen/terraform/client/process_options.rb +87 -0
- data/lib/kitchen/terraform/client/validate.rb +35 -0
- data/lib/kitchen/terraform/client/version.rb +48 -0
- data/lib/{terraform/apply_timeout_config.rb → kitchen/terraform/create_directories.rb} +18 -11
- data/lib/kitchen/terraform/define_config_attribute.rb +39 -0
- data/lib/kitchen/terraform/define_integer_config_attribute.rb +43 -0
- data/lib/kitchen/terraform/define_string_config_attribute.rb +43 -0
- data/lib/kitchen/verifier/terraform.rb +186 -38
- data/lib/kitchen/verifier/terraform/configure_inspec_runner_attributes.rb +93 -0
- data/lib/kitchen/verifier/terraform/configure_inspec_runner_backend.rb +32 -0
- data/lib/kitchen/verifier/terraform/configure_inspec_runner_controls.rb +39 -0
- data/lib/{terraform/apply_command.rb → kitchen/verifier/terraform/configure_inspec_runner_host.rb} +11 -15
- data/lib/{terraform/deprecated_output_parser.rb → kitchen/verifier/terraform/configure_inspec_runner_port.rb} +16 -20
- data/lib/{terraform/deprecated_variables_coercer.rb → kitchen/verifier/terraform/configure_inspec_runner_user.rb} +16 -14
- data/lib/kitchen/verifier/terraform/enumerate_groups_and_hostnames.rb +67 -0
- data/lib/{terraform/version_command.rb → terraform.rb} +1 -5
- data/lib/terraform/configurable.rb +18 -61
- data/lib/terraform/debug_logger.rb +12 -12
- data/lib/terraform/project_version.rb +1 -1
- metadata +72 -135
- metadata.gz.sig +0 -0
- data/lib/terraform/cli_config.rb +0 -29
- data/lib/terraform/client.rb +0 -96
- data/lib/terraform/color_coercer.rb +0 -35
- data/lib/terraform/color_config.rb +0 -32
- data/lib/terraform/command.rb +0 -53
- data/lib/terraform/command_factory.rb +0 -111
- data/lib/terraform/command_option.rb +0 -65
- data/lib/terraform/command_options.rb +0 -103
- data/lib/terraform/destructive_plan_command.rb +0 -35
- data/lib/terraform/directory_config.rb +0 -32
- data/lib/terraform/file_configs.rb +0 -36
- data/lib/terraform/group.rb +0 -61
- data/lib/terraform/group_attributes.rb +0 -42
- data/lib/terraform/group_hostnames.rb +0 -38
- data/lib/terraform/groups_coercer.rb +0 -43
- data/lib/terraform/groups_config.rb +0 -32
- data/lib/terraform/integer_coercer.rb +0 -37
- data/lib/terraform/no_output_parser.rb +0 -28
- data/lib/terraform/output_command.rb +0 -23
- data/lib/terraform/output_parser.rb +0 -55
- data/lib/terraform/parallelism_config.rb +0 -32
- data/lib/terraform/pathname_coercer.rb +0 -40
- data/lib/terraform/plan_command.rb +0 -30
- data/lib/terraform/prepare_input_file.rb +0 -34
- data/lib/terraform/prepare_output_file.rb +0 -36
- data/lib/terraform/shell_out.rb +0 -59
- data/lib/terraform/show_command.rb +0 -30
- data/lib/terraform/simple_coercer.rb +0 -36
- data/lib/terraform/simple_config.rb +0 -28
- data/lib/terraform/unsupported_version.rb +0 -26
- data/lib/terraform/validate_command.rb +0 -23
- data/lib/terraform/variable_files_coercer.rb +0 -40
- data/lib/terraform/variable_files_config.rb +0 -32
- data/lib/terraform/variables_coercer.rb +0 -49
- data/lib/terraform/variables_config.rb +0 -32
- data/lib/terraform/version.rb +0 -73
@@ -0,0 +1,87 @@
|
|
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
|
+
|
20
|
+
# Processes Terraform Client function options in to Terraform Command-Line Interface (CLI) flags.
|
21
|
+
#
|
22
|
+
# @see https://www.terraform.io/docs/commands/index.html Terraform commands
|
23
|
+
module ::Kitchen::Terraform::Client::ProcessOptions
|
24
|
+
extend ::Dry::Monads::Either::Mixin
|
25
|
+
extend ::Dry::Monads::Maybe::Mixin
|
26
|
+
extend ::Dry::Monads::List::Mixin
|
27
|
+
extend ::Dry::Monads::Try::Mixin
|
28
|
+
|
29
|
+
OPTIONS_FLAGS = {
|
30
|
+
color: lambda do |value:|
|
31
|
+
"-no-color" if not value
|
32
|
+
end,
|
33
|
+
destroy: lambda do |value:|
|
34
|
+
"-destroy" if value
|
35
|
+
end,
|
36
|
+
input: lambda do |value:|
|
37
|
+
"-input=#{value}"
|
38
|
+
end,
|
39
|
+
json: lambda do |value:|
|
40
|
+
"-json" if value
|
41
|
+
end,
|
42
|
+
out: lambda do |value:|
|
43
|
+
"-out=#{value}"
|
44
|
+
end,
|
45
|
+
parallelism: lambda do |value:|
|
46
|
+
"-parallelism=#{value}"
|
47
|
+
end,
|
48
|
+
state: lambda do |value:|
|
49
|
+
"-state=#{value}"
|
50
|
+
end,
|
51
|
+
state_out: lambda do |value:|
|
52
|
+
"-state-out=#{value}"
|
53
|
+
end,
|
54
|
+
update: lambda do |value:|
|
55
|
+
"-update" if value
|
56
|
+
end,
|
57
|
+
var: lambda do |value:|
|
58
|
+
value.map do |variable_name, variable_value|
|
59
|
+
"-var='#{variable_name}=#{variable_value}'"
|
60
|
+
end
|
61
|
+
end,
|
62
|
+
var_file: lambda do |value:|
|
63
|
+
value.map do |file|
|
64
|
+
"-var-file=#{file}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
}.freeze
|
68
|
+
|
69
|
+
# Invokes the function.
|
70
|
+
#
|
71
|
+
# @param unprocessed_options [::Hash{::Symbol => TrueClass, FalseClass, #to_s, #map}] underscore delimited option keys
|
72
|
+
# associated with their values.
|
73
|
+
# @return [::Dry::Monads::Either] the result of the function.
|
74
|
+
def self.call(unprocessed_options:)
|
75
|
+
List(unprocessed_options.to_a).fmap(&method(:Right)).typed(::Dry::Monads::Either).traverse do |member|
|
76
|
+
member.bind do |key, value|
|
77
|
+
Maybe(::Kitchen::Terraform::Client::ProcessOptions::OPTIONS_FLAGS[key]).bind do |processor|
|
78
|
+
Right processor.call value: value
|
79
|
+
end.or do
|
80
|
+
Left ":#{key} is not a supported Terraform Client option"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end.fmap do |options|
|
84
|
+
options.value.flatten.compact.sort
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,35 @@
|
|
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
|
+
require "kitchen/terraform/client/execute_command"
|
19
|
+
|
20
|
+
# Validates the syntax of Terraform configuration files.
|
21
|
+
#
|
22
|
+
# @see https://www.terraform.io/docs/commands/validate.html Terraform validate command
|
23
|
+
module ::Kitchen::Terraform::Client::Validate
|
24
|
+
# Invokes the function.
|
25
|
+
#
|
26
|
+
# @param cli [::String] the path of the Terraform CLI to use to execute the validate command.
|
27
|
+
# @param directory [::String] the directory containing files to validate.
|
28
|
+
# @param logger [#<<] a logger to receive the stdout and stderr of the validate command.
|
29
|
+
# @param timeout [::Integer] the maximum execution time in seconds for the validate command.
|
30
|
+
# @return [::Dry::Monads::Either] the result of the function.
|
31
|
+
def self.call(cli:, directory:, logger:, timeout:)
|
32
|
+
::Kitchen::Terraform::Client::ExecuteCommand.call cli: cli, command: "validate", logger: logger, target: directory,
|
33
|
+
timeout: timeout
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,48 @@
|
|
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 "kitchen/terraform/client/execute_command"
|
20
|
+
|
21
|
+
# Retrieves the version of the Terraform Command-Line Interface (CLI).
|
22
|
+
#
|
23
|
+
# @see https://www.terraform.io/docs/commands/index.html Terraform commands
|
24
|
+
module ::Kitchen::Terraform::Client::Version
|
25
|
+
extend ::Dry::Monads::Either::Mixin
|
26
|
+
|
27
|
+
extend ::Dry::Monads::Maybe::Mixin
|
28
|
+
|
29
|
+
# Invokes the function.
|
30
|
+
#
|
31
|
+
# @param cli [::String] the path of the Terraform CLI to use to execute the version command.
|
32
|
+
# @param logger [#<<] a logger to receive the stdout and stderr of the version command.
|
33
|
+
# @param timeout [::Integer] the time in seconds to wait for the version command to finish.
|
34
|
+
# @return [::Dry::Monads::Either] the result of the function.
|
35
|
+
def self.call(cli:, logger:, timeout:)
|
36
|
+
::Kitchen::Terraform::Client::ExecuteCommand
|
37
|
+
.call(cli: cli, command: "version", logger: logger, timeout: timeout)
|
38
|
+
.bind do |output|
|
39
|
+
Maybe output.slice /v(\d+\.\d+)/, 1
|
40
|
+
end.bind do |major_minor_versions|
|
41
|
+
Right Float major_minor_versions
|
42
|
+
end.or do |error|
|
43
|
+
error.nil? and Left "Terraform client version output did not match 'vX.Y'" or Left error
|
44
|
+
end.or do |error|
|
45
|
+
Left "Unable to parse Terraform client version output\n#{error}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -14,19 +14,26 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
-
require
|
18
|
-
require
|
17
|
+
require "dry/monads"
|
18
|
+
require "fileutils"
|
19
|
+
require "kitchen/terraform"
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
# Creates directories on the filesystem.
|
22
|
+
module ::Kitchen::Terraform::CreateDirectories
|
23
|
+
extend ::Dry::Monads::Either::Mixin
|
24
|
+
extend ::Dry::Monads::Try::Mixin
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
# Invokes the function.
|
27
|
+
#
|
28
|
+
# @param directories [::Array<::String>, ::String] the list of directories to create.
|
29
|
+
# @return [::Dry::Monads::Either] the result of the function.
|
30
|
+
def self.call(directories:)
|
31
|
+
Try ::SystemCallError do
|
32
|
+
::FileUtils.makedirs directories
|
33
|
+
end.to_either.bind do
|
34
|
+
Right "Created directories #{directories}"
|
35
|
+
end.or do |error|
|
36
|
+
Left error.to_s
|
30
37
|
end
|
31
38
|
end
|
32
39
|
end
|
@@ -0,0 +1,39 @@
|
|
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-validation"
|
18
|
+
require "kitchen"
|
19
|
+
require "kitchen/terraform"
|
20
|
+
|
21
|
+
# Defines a configuration attribute for a plugin class.
|
22
|
+
#
|
23
|
+
# @see http://dry-rb.org/gems/dry-validation/ DRY Validation
|
24
|
+
module ::Kitchen::Terraform::DefineConfigAttribute
|
25
|
+
# Invokes the function.
|
26
|
+
#
|
27
|
+
# @param attribute [::Symbol] the name of the attribute.
|
28
|
+
# @param initialize_default_value [::Proc] a proc to lazily provide a default value.
|
29
|
+
# @param plugin_class [::Class] the plugin class on which the attribute will be defined.
|
30
|
+
# @param schema [::Proc] a proc to define the validation schema of the attribute.
|
31
|
+
def self.call(attribute:, initialize_default_value:, plugin_class:, schema:)
|
32
|
+
plugin_class.required_config attribute do |_attribute, value, plugin|
|
33
|
+
::Dry::Validation.Schema(&schema).call(value: value).messages.tap do |messages|
|
34
|
+
raise ::Kitchen::UserError, "#{plugin.class} configuration: #{attribute} #{messages}" if not messages.empty?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
plugin_class.default_config attribute, &initialize_default_value
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
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-validation"
|
18
|
+
require "kitchen"
|
19
|
+
require "kitchen/terraform"
|
20
|
+
require "kitchen/terraform/define_config_attribute"
|
21
|
+
|
22
|
+
# Defines an integer configuration attribute for a plugin class.
|
23
|
+
#
|
24
|
+
# @see http://dry-rb.org/gems/dry-validation/ DRY Validation
|
25
|
+
module ::Kitchen::Terraform::DefineIntegerConfigAttribute
|
26
|
+
# Invokes the function.
|
27
|
+
#
|
28
|
+
# @param attribute [::Symbol] the name of the attribute.
|
29
|
+
# @param plugin_class [::Class] the plugin class on which the attribute will be defined.
|
30
|
+
# @yieldparam plugin [::Kitchen::Driver::Terraform, ::Kitchen::Provisioner::Terraform, ::Kitchen::Verifier::Terraform]
|
31
|
+
# an instance of the plugin class.
|
32
|
+
# @yieldreturn [::Object] the default value of the attribute.
|
33
|
+
def self.call(attribute:, plugin_class:, &initialize_default_value)
|
34
|
+
::Kitchen::Terraform::DefineConfigAttribute.call(
|
35
|
+
attribute: attribute,
|
36
|
+
initialize_default_value: initialize_default_value,
|
37
|
+
plugin_class: plugin_class,
|
38
|
+
schema: lambda do
|
39
|
+
required(:value).filled :int?
|
40
|
+
end
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,43 @@
|
|
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-validation"
|
18
|
+
require "kitchen"
|
19
|
+
require "kitchen/terraform"
|
20
|
+
require "kitchen/terraform/define_config_attribute"
|
21
|
+
|
22
|
+
# Defines a string configuration attribute for a plugin class.
|
23
|
+
#
|
24
|
+
# @see http://dry-rb.org/gems/dry-validation/ DRY Validation
|
25
|
+
module ::Kitchen::Terraform::DefineStringConfigAttribute
|
26
|
+
# Invokes the function.
|
27
|
+
#
|
28
|
+
# @param attribute [::Symbol] the name of the attribute.
|
29
|
+
# @param plugin_class [::Class] the plugin class on which the attribute will be defined.
|
30
|
+
# @yieldparam plugin [::Kitchen::Driver::Terraform, ::Kitchen::Provisioner::Terraform, ::Kitchen::Verifier::Terraform]
|
31
|
+
# an instance of the plugin class.
|
32
|
+
# @yieldreturn [::Object] the default value of the attribute.
|
33
|
+
def self.call(attribute:, plugin_class:, &initialize_default_value)
|
34
|
+
::Kitchen::Terraform::DefineConfigAttribute.call(
|
35
|
+
attribute: attribute,
|
36
|
+
initialize_default_value: initialize_default_value,
|
37
|
+
plugin_class: plugin_class,
|
38
|
+
schema: lambda do
|
39
|
+
required(:value).filled :str?
|
40
|
+
end
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
@@ -14,56 +14,204 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
17
|
+
require "dry/monads"
|
18
|
+
require "kitchen"
|
19
|
+
require "kitchen/terraform/define_config_attribute"
|
20
|
+
require "kitchen/verifier/inspec"
|
21
|
+
require "terraform/configurable"
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
# The verifier utilizes the InSpec infrastructure testing framework to verify the behaviour and state of resources in
|
24
|
+
# the Terraform state.
|
25
|
+
#
|
26
|
+
# InSpec profiles are assumed to be located in `test/integration/<suite-name>/`.
|
27
|
+
#
|
28
|
+
# === Configuration
|
29
|
+
#
|
30
|
+
# ==== Example .kitchen.yml snippet
|
31
|
+
#
|
32
|
+
# verifier:
|
33
|
+
# name: terraform
|
34
|
+
# groups:
|
35
|
+
# - name: group_one
|
36
|
+
# attributes:
|
37
|
+
# foo: bar
|
38
|
+
# controls:
|
39
|
+
# - biz
|
40
|
+
# hostnames: hostnames_output
|
41
|
+
# port: 123
|
42
|
+
# username: test-user
|
43
|
+
# - name: group_two
|
44
|
+
#
|
45
|
+
# ==== Attributes
|
46
|
+
#
|
47
|
+
# ===== groups
|
48
|
+
#
|
49
|
+
# Description:: A collection of maps that configure which InSpec profile will be run against different resources in the
|
50
|
+
# Terraform state.
|
51
|
+
#
|
52
|
+
# Type:: Array
|
53
|
+
#
|
54
|
+
# Status:: Optional
|
55
|
+
#
|
56
|
+
# Default:: +[]+
|
57
|
+
#
|
58
|
+
# ====== name
|
59
|
+
#
|
60
|
+
# Description:: A label that is used to identify the group.
|
61
|
+
#
|
62
|
+
# Type:: String
|
63
|
+
#
|
64
|
+
# Status:: Required
|
65
|
+
#
|
66
|
+
# ====== attributes
|
67
|
+
#
|
68
|
+
# Description:: A map that associates InSpec profile attribute names to Terraform output variable names.
|
69
|
+
#
|
70
|
+
# Type:: Hash
|
71
|
+
#
|
72
|
+
# Status:: Optional
|
73
|
+
#
|
74
|
+
# Default:: +{}+
|
75
|
+
#
|
76
|
+
# ====== controls
|
77
|
+
#
|
78
|
+
# Description:: A collection of controls to selectively include from the suite's InSpec profile.
|
79
|
+
#
|
80
|
+
# Type:: Array
|
81
|
+
#
|
82
|
+
# Status:: Optional
|
83
|
+
#
|
84
|
+
# Default:: +[]+
|
85
|
+
#
|
86
|
+
# ====== hostnames
|
87
|
+
#
|
88
|
+
# Description:: The name of a Terraform output variable of type String or Array which contains one or more hostnames
|
89
|
+
# from the Terraform state that will be targeted with the suite's InSpec profile.
|
90
|
+
#
|
91
|
+
# Type:: String
|
92
|
+
#
|
93
|
+
# Status:: Optional
|
94
|
+
#
|
95
|
+
# ====== port
|
96
|
+
#
|
97
|
+
# Description:: The port to use when connecting to the group's hosts with Secure Shell (SSH).
|
98
|
+
#
|
99
|
+
# Type:: Integer
|
100
|
+
#
|
101
|
+
# Status:: Optional
|
102
|
+
#
|
103
|
+
# ====== username
|
104
|
+
#
|
105
|
+
# Description:: The username to use when connecting to the group's hosts with SSH.
|
106
|
+
#
|
107
|
+
# Type:: String
|
108
|
+
#
|
109
|
+
# Status:: Optional
|
110
|
+
#
|
111
|
+
# @see https://en.wikipedia.org/wiki/Secure_Shell Secure Shell
|
112
|
+
# @see https://www.inspec.io/ InSpec
|
113
|
+
# @see https://www.inspec.io/docs/reference/dsl_inspec/ InSpec Controls
|
114
|
+
# @see https://www.inspec.io/docs/reference/profiles/ InSpec Profiles
|
115
|
+
# @see https://www.terraform.io/docs/configuration/outputs.html Terraform Output Variables
|
116
|
+
# @see https://www.terraform.io/docs/state/index.html Terraform State
|
117
|
+
# @version 2
|
118
|
+
class ::Kitchen::Verifier::Terraform < ::Kitchen::Verifier::Inspec
|
119
|
+
kitchen_verifier_api_version 2
|
27
120
|
|
28
|
-
|
121
|
+
::Kitchen::Terraform::DefineConfigAttribute.call(
|
122
|
+
attribute: :groups,
|
123
|
+
initialize_default_value: lambda do |_plugin|
|
124
|
+
[]
|
125
|
+
end,
|
126
|
+
plugin_class: self,
|
127
|
+
schema: lambda do
|
128
|
+
configure do
|
129
|
+
def self.messages
|
130
|
+
super.merge en: {
|
131
|
+
errors: {
|
132
|
+
keys_are_strings_or_symbols?: "keys must be strings or symbols",
|
133
|
+
values_are_strings?: "values must be strings"
|
134
|
+
}
|
135
|
+
}
|
136
|
+
end
|
29
137
|
|
30
|
-
|
138
|
+
def keys_are_strings_or_symbols?(hash)
|
139
|
+
hash.keys.all? do |key|
|
140
|
+
key.is_a?(::String) | key.is_a?(::Symbol)
|
141
|
+
end
|
142
|
+
end
|
31
143
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
144
|
+
def values_are_strings?(hash)
|
145
|
+
hash.values.all? do |value|
|
146
|
+
value.is_a? ::String
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
required(:value).each do
|
151
|
+
schema do
|
152
|
+
required(:name).filled :str?
|
153
|
+
optional(:attributes).value :hash?, :keys_are_strings_or_symbols?, :values_are_strings?
|
154
|
+
optional(:controls).each :filled?, :str?
|
155
|
+
optional(:hostnames).value :str?
|
156
|
+
optional(:port).value :int?
|
157
|
+
optional(:username).value :str?
|
40
158
|
end
|
41
|
-
rescue ::Kitchen::StandardError, ::SystemCallError => error
|
42
|
-
raise ::Kitchen::ActionFailed, error.message
|
43
159
|
end
|
160
|
+
end
|
161
|
+
)
|
44
162
|
|
45
|
-
|
163
|
+
include ::Dry::Monads::Either::Mixin
|
46
164
|
|
47
|
-
|
165
|
+
include ::Terraform::Configurable
|
48
166
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
167
|
+
# The verifier enumerates through each hostname of each group and verifies the associated InSpec controls.
|
168
|
+
#
|
169
|
+
# @example
|
170
|
+
# `kitchen verify suite-name`
|
171
|
+
# @param state [::Hash] the mutable instance and verifier state.
|
172
|
+
# @raise [::Kitchen::ActionFailed] if the result of the action is a failure.
|
173
|
+
# @return [::Dry::Monads::Either] the result of the action.
|
174
|
+
def call(state)
|
175
|
+
self.class::EnumerateGroupsAndHostnames.call driver: driver, groups: config.fetch(:groups) do |group:, hostname:|
|
176
|
+
state.store :group, group
|
177
|
+
state.store :hostname, hostname
|
178
|
+
info "Verifying host '#{hostname}' of group '#{group.fetch :name}'"
|
179
|
+
super state
|
180
|
+
end.fmap do |success|
|
181
|
+
logger.debug success
|
182
|
+
end.or do |failure|
|
183
|
+
raise ::Kitchen::ActionFailed, failure
|
184
|
+
end
|
185
|
+
end
|
54
186
|
|
55
|
-
|
56
|
-
config[:groups]
|
57
|
-
.each { |group| group.resolve client: silent_client, &block }
|
58
|
-
end
|
187
|
+
private
|
59
188
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
189
|
+
# Modifies the Inspec Runner options generated by the kitchen-inspec verifier to support the verification of each
|
190
|
+
# group's hosts.
|
191
|
+
#
|
192
|
+
# @api private
|
193
|
+
# @return [::Hash] Inspec Runner options.
|
194
|
+
# @see https://github.com/chef/inspec/blob/master/lib/inspec/runner.rb ::Inspec::Runner
|
195
|
+
# @see https://github.com/chef/kitchen-inspec/blob/master/lib/kitchen/verifier.rb kitchen-inspec verifier
|
196
|
+
def runner_options(transport, state = {}, platform = nil, suite = nil)
|
197
|
+
super(transport, state, platform, suite).tap do |options|
|
198
|
+
self.class::ConfigureInspecRunnerBackend.call hostname: state.fetch(:hostname), options: options
|
199
|
+
self.class::ConfigureInspecRunnerHost.call hostname: state.fetch(:hostname), options: options
|
200
|
+
self.class::ConfigureInspecRunnerPort.call group: state.fetch(:group), options: options
|
201
|
+
self.class::ConfigureInspecRunnerUser.call group: state.fetch(:group), options: options
|
202
|
+
self.class::ConfigureInspecRunnerAttributes
|
203
|
+
.call(driver: driver, group: state.fetch(:group), terraform_state: driver[:state]).bind do |attributes|
|
204
|
+
config.store :attributes, attributes
|
65
205
|
end
|
66
|
-
|
206
|
+
self.class::ConfigureInspecRunnerControls.call group: state.fetch(:group), options: options
|
67
207
|
end
|
68
208
|
end
|
69
209
|
end
|
210
|
+
|
211
|
+
require "kitchen/verifier/terraform/configure_inspec_runner_attributes"
|
212
|
+
require "kitchen/verifier/terraform/configure_inspec_runner_backend"
|
213
|
+
require "kitchen/verifier/terraform/configure_inspec_runner_controls"
|
214
|
+
require "kitchen/verifier/terraform/configure_inspec_runner_host"
|
215
|
+
require "kitchen/verifier/terraform/configure_inspec_runner_port"
|
216
|
+
require "kitchen/verifier/terraform/configure_inspec_runner_user"
|
217
|
+
require "kitchen/verifier/terraform/enumerate_groups_and_hostnames"
|