kitchen-terraform 0.7.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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"
|