kitchen-terraform 3.3.1 → 4.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 +0 -0
- data/README.md +45 -28
- data/lib/kitchen/driver/terraform.rb +87 -66
- data/lib/kitchen/provisioner/terraform.rb +1 -1
- data/lib/kitchen/terraform/client_version_verifier.rb +3 -3
- data/lib/kitchen/terraform/command/output.rb +43 -40
- data/lib/kitchen/{verifier/terraform/configure_inspec_runner_host.rb → terraform/config_attribute/systems.rb} +18 -11
- data/lib/kitchen/terraform/config_attribute/variable_files.rb +1 -1
- data/lib/kitchen/terraform/config_schemas/system.rb +555 -0
- data/lib/kitchen/terraform/{breaking/kitchen_instance.rb → config_schemas/systems.rb} +16 -5
- data/lib/kitchen/terraform/configurable.rb +2 -6
- data/lib/kitchen/terraform/inspec.rb +74 -0
- data/lib/kitchen/terraform/inspec_options_mapper.rb +49 -0
- data/lib/kitchen/terraform/inspec_with_hosts.rb +49 -0
- data/lib/kitchen/terraform/inspec_without_hosts.rb +44 -0
- data/lib/kitchen/terraform/shell_out.rb +13 -10
- data/lib/kitchen/terraform/system.rb +120 -0
- data/lib/kitchen/terraform/system_attrs_resolver.rb +57 -0
- data/lib/kitchen/terraform/system_hosts_resolver.rb +45 -0
- data/lib/kitchen/terraform/version.rb +60 -17
- data/lib/kitchen/verifier/terraform.rb +162 -156
- metadata +45 -41
- metadata.gz.sig +0 -0
- data/lib/kitchen/terraform/config_attribute/groups.rb +0 -148
- data/lib/kitchen/terraform/config_schemas/groups.rb +0 -52
- data/lib/kitchen/terraform/deprecating/kitchen_instance.rb +0 -61
- data/lib/kitchen/terraform/kitchen_instance.rb +0 -49
- data/lib/kitchen/verifier/terraform/configure_inspec_runner_attributes.rb +0 -98
- data/lib/kitchen/verifier/terraform/configure_inspec_runner_backend.rb +0 -32
- data/lib/kitchen/verifier/terraform/configure_inspec_runner_controls.rb +0 -41
- data/lib/kitchen/verifier/terraform/configure_inspec_runner_port.rb +0 -40
- data/lib/kitchen/verifier/terraform/configure_inspec_runner_ssh_key.rb +0 -41
- data/lib/kitchen/verifier/terraform/configure_inspec_runner_user.rb +0 -40
- data/lib/kitchen/verifier/terraform/enumerate_groups_and_hostnames.rb +0 -82
@@ -14,10 +14,21 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
-
require "
|
18
|
-
require "kitchen"
|
19
|
-
require "kitchen/terraform/
|
17
|
+
require "dry/validation"
|
18
|
+
require "kitchen/terraform/config_schemas"
|
19
|
+
require "kitchen/terraform/config_schemas/system"
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
module Kitchen
|
22
|
+
module Terraform
|
23
|
+
module ConfigSchemas
|
24
|
+
# The value of the +systems+ key must be a sequence of systems.
|
25
|
+
#
|
26
|
+
# {include:Kitchen::Terraform::ConfigSchemas::System}
|
27
|
+
Systems = ::Dry::Validation.Schema do
|
28
|
+
required(:value).each do
|
29
|
+
schema ::Kitchen::Terraform::ConfigSchemas::System
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
23
34
|
end
|
@@ -16,7 +16,6 @@
|
|
16
16
|
|
17
17
|
require "kitchen"
|
18
18
|
require "kitchen/terraform"
|
19
|
-
require "kitchen/terraform/kitchen_instance"
|
20
19
|
require "kitchen/terraform/version"
|
21
20
|
|
22
21
|
# Refinements to Kitchen::Configurable.
|
@@ -27,10 +26,7 @@ module ::Kitchen::Terraform::Configurable
|
|
27
26
|
#
|
28
27
|
# @return [self]
|
29
28
|
def self.included(configurable_class)
|
30
|
-
::Kitchen::Terraform::Version
|
31
|
-
.new
|
32
|
-
.assign_plugin_version configurable_class: configurable_class
|
33
|
-
|
29
|
+
::Kitchen::Terraform::Version.assign_plugin_version configurable_class: configurable_class
|
34
30
|
self
|
35
31
|
end
|
36
32
|
|
@@ -51,7 +47,7 @@ module ::Kitchen::Terraform::Configurable
|
|
51
47
|
"Instance must be provided to #{self}"
|
52
48
|
)
|
53
49
|
|
54
|
-
@instance =
|
50
|
+
@instance = kitchen_instance
|
55
51
|
validate_config!
|
56
52
|
expand_paths!
|
57
53
|
load_needed_dependencies!
|
@@ -0,0 +1,74 @@
|
|
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 "inspec"
|
18
|
+
require "kitchen/terraform/error"
|
19
|
+
require "train"
|
20
|
+
|
21
|
+
module Kitchen
|
22
|
+
module Terraform
|
23
|
+
# InSpec is the class of objects which act as interfaces to InSpec.
|
24
|
+
class InSpec
|
25
|
+
class << self
|
26
|
+
# .logger= sets the logger for all InSpec processes.
|
27
|
+
#
|
28
|
+
# The logdev of the logger is extended to conform to interface expected by InSpec.
|
29
|
+
#
|
30
|
+
# @param logger [::Kitchen::Logger] the logger to use.
|
31
|
+
# @return [void]
|
32
|
+
def logger=(logger)
|
33
|
+
logger.logdev.define_singleton_method :filename do
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
::Inspec::Log.logger = logger
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# #exec executes InSpec.
|
42
|
+
#
|
43
|
+
# @return [self]
|
44
|
+
def exec
|
45
|
+
@runner.run.tap do |exit_code|
|
46
|
+
if 0 != exit_code
|
47
|
+
raise ::Kitchen::Terraform::Error, "InSpec Runner exited with #{exit_code}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
self
|
52
|
+
rescue ::ArgumentError, ::RuntimeError, ::Train::UserError => error
|
53
|
+
raise ::Kitchen::Terraform::Error, "Executing InSpec failed\n#{error.message}"
|
54
|
+
end
|
55
|
+
|
56
|
+
# #info logs an information message using the InSpec logger.
|
57
|
+
#
|
58
|
+
# @param message [::String] the message to be logged.
|
59
|
+
# @return [self]
|
60
|
+
def info(message:)
|
61
|
+
::Inspec::Log.info ::String.new message
|
62
|
+
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def initialize(options:, profile_path:)
|
69
|
+
@runner = ::Inspec::Runner.new options.merge logger: ::Inspec::Log.logger
|
70
|
+
@runner.add_target path: profile_path
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,49 @@
|
|
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"
|
18
|
+
|
19
|
+
# Kitchen::Terraform::InSpecOptionsMapper maps system configuration attributes to an InSpec options hash.
|
20
|
+
class ::Kitchen::Terraform::InSpecOptionsMapper
|
21
|
+
# map populates an InSpec options hash based on the intersection between the system keys and the supported options
|
22
|
+
# keys, converting keys from symbols to strings as required by InSpec.
|
23
|
+
#
|
24
|
+
# @param options [::Hash] the InSpec options hash to be populated.
|
25
|
+
# @return [void]
|
26
|
+
def map(options:)
|
27
|
+
system_keys.&(options_keys).each do |key|
|
28
|
+
options.store system_to_options.dig(key), system.fetch(key)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_accessor :system, :system_keys, :system_to_options, :options_keys
|
35
|
+
|
36
|
+
# @api private
|
37
|
+
def initialize(system:)
|
38
|
+
self.system = system
|
39
|
+
self.system_keys = system.keys
|
40
|
+
self.system_to_options = ::Hash.new do |hash, key|
|
41
|
+
hash.store key, key
|
42
|
+
end
|
43
|
+
system_to_options.store :reporter, "reporter"
|
44
|
+
self.options_keys = [:attrs, :backend, :backend_cache, :bastion_host, :bastion_port, :bastion_user, :controls,
|
45
|
+
:enable_password, :key_files, :password, :path, :port, :proxy_command, :reporter, :self_signed,
|
46
|
+
:shell, :shell_command, :shell_options, :show_progress, :ssl, :sudo, :sudo_command,
|
47
|
+
:sudo_options, :sudo_password, :user, :vendor_cache]
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,49 @@
|
|
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"
|
18
|
+
require "kitchen/terraform/error"
|
19
|
+
require "kitchen/terraform/inspec"
|
20
|
+
|
21
|
+
module Kitchen
|
22
|
+
module Terraform
|
23
|
+
# InSpec instances act as interfaces to the InSpec gem.
|
24
|
+
class InSpecWithHosts
|
25
|
+
# exec executes the InSpec controls of an InSpec profile.
|
26
|
+
#
|
27
|
+
# @raise [::Kitchen::Terraform::Error] if the execution of the InSpec controls fails.
|
28
|
+
# @return [void]
|
29
|
+
def exec(system:)
|
30
|
+
system.each_host do |host:|
|
31
|
+
::Kitchen::Terraform::InSpec
|
32
|
+
.new(options: options.merge(host: host), profile_path: profile_path)
|
33
|
+
.info(message: "Verifying host #{host} of #{system}").exec
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
attr_accessor :options, :profile_path
|
40
|
+
|
41
|
+
# @param options [::Hash] options for execution.
|
42
|
+
# @param profile_path [::String] the path to the InSpec profile which contains the controls to be executed.
|
43
|
+
def initialize(options:, profile_path:)
|
44
|
+
self.options = options
|
45
|
+
self.profile_path = profile_path
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,44 @@
|
|
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/inspec"
|
18
|
+
|
19
|
+
module Kitchen
|
20
|
+
module Terraform
|
21
|
+
# InSpec instances act as interfaces to the InSpec gem.
|
22
|
+
class InSpecWithoutHosts
|
23
|
+
# exec executes the InSpec controls of an InSpec profile.
|
24
|
+
#
|
25
|
+
# @raise [::Kitchen::Terraform::Error] if the execution of the InSpec controls fails.
|
26
|
+
# @return [void]
|
27
|
+
def exec(system:)
|
28
|
+
::Kitchen::Terraform::InSpec
|
29
|
+
.new(options: options, profile_path: profile_path).info(message: "Verifying #{system}").exec
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_accessor :options, :profile_path
|
35
|
+
|
36
|
+
# @param options [::Hash] options for execution.
|
37
|
+
# @param profile_path [::String] the path to the InSpec profile which contains the controls to be executed.
|
38
|
+
def initialize(options:, profile_path:)
|
39
|
+
self.options = options
|
40
|
+
self.profile_path = profile_path
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -26,14 +26,17 @@ require "mixlib/shellout"
|
|
26
26
|
module ::Kitchen::Terraform::ShellOut
|
27
27
|
# Runs a Terraform command.
|
28
28
|
#
|
29
|
+
# @option options [::String] :cwd the directory in which to run the command.
|
30
|
+
# @option options [::Kitchen::Logger] :live_stream a Test Kitchen logger to capture the output from running the
|
31
|
+
# command.
|
32
|
+
# @option options [::Integer] :timeout the maximum duration in seconds to run the command.
|
29
33
|
# @param command [::String] the command to run.
|
30
|
-
# @param
|
31
|
-
# @param logger [::Kitchen::Logger] a Test Kitchen logger to capture the output from running the command.
|
34
|
+
# @param options [::Hash] options which adjust the execution of the command.
|
32
35
|
# @raise [::Kitchen::Terraform::Error] if running the command fails.
|
33
36
|
# @return [::String] the standard output from running the command.
|
34
37
|
# @see https://rubygems.org/gems/mixlib-shellout mixlib-shellout
|
35
38
|
# @yieldparam standard_output [::String] the standard output from running the command.
|
36
|
-
def self.run(command:,
|
39
|
+
def self.run(command:, options:, &block)
|
37
40
|
block ||=
|
38
41
|
lambda do |standard_output:|
|
39
42
|
standard_output
|
@@ -41,8 +44,7 @@ module ::Kitchen::Terraform::ShellOut
|
|
41
44
|
|
42
45
|
run_shell_out(
|
43
46
|
command: command,
|
44
|
-
|
45
|
-
logger: logger,
|
47
|
+
options: options,
|
46
48
|
&block
|
47
49
|
)
|
48
50
|
rescue ::Errno::EACCES,
|
@@ -64,18 +66,19 @@ module ::Kitchen::Terraform::ShellOut
|
|
64
66
|
end
|
65
67
|
|
66
68
|
# @api private
|
67
|
-
def self.run_shell_out(command:,
|
69
|
+
def self.run_shell_out(command:, options:)
|
68
70
|
yield(
|
69
71
|
standard_output:
|
70
72
|
::Mixlib::ShellOut
|
71
73
|
.new(
|
72
74
|
"terraform #{command}",
|
73
|
-
environment: {"TF_IN_AUTOMATION" => "true"}
|
74
|
-
live_stream: logger,
|
75
|
-
timeout: duration
|
75
|
+
options.merge(environment: {"TF_IN_AUTOMATION" => "true", "TF_WARN_OUTPUT_ERRORS" => "1"})
|
76
76
|
)
|
77
77
|
.tap do |shell_out|
|
78
|
-
|
78
|
+
shell_out
|
79
|
+
.live_stream
|
80
|
+
.warn "Running command `#{shell_out.command}` in directory #{shell_out.cwd}"
|
81
|
+
|
79
82
|
shell_out.run_command
|
80
83
|
shell_out.error!
|
81
84
|
end
|
@@ -0,0 +1,120 @@
|
|
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/inspec_with_hosts"
|
18
|
+
require "kitchen/terraform/inspec_without_hosts"
|
19
|
+
|
20
|
+
module Kitchen
|
21
|
+
module Terraform
|
22
|
+
# System is the class of objects which are verified by the Terraform Verifier.
|
23
|
+
class System
|
24
|
+
# #add_attrs adds attributes to the system.
|
25
|
+
#
|
26
|
+
# @param attrs [#to_hash] the attributes to be added.
|
27
|
+
# @return [self]
|
28
|
+
def add_attrs(attrs:)
|
29
|
+
@attributes = @attributes.merge Hash attrs
|
30
|
+
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
# #add_hosts adds hosts to the system.
|
35
|
+
#
|
36
|
+
# @param hosts [#to_arr,#to_a] the hosts to be added.
|
37
|
+
# @return [self]
|
38
|
+
def add_hosts(hosts:)
|
39
|
+
@hosts = @hosts.+ Array hosts
|
40
|
+
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
# #each_host enumerates each host of the system.
|
45
|
+
#
|
46
|
+
# @yieldparam host [::String] the next host.
|
47
|
+
# @return [self]
|
48
|
+
def each_host
|
49
|
+
@hosts.each do |host|
|
50
|
+
yield host: host
|
51
|
+
end
|
52
|
+
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
# #resolve_attrs resolves the attributes of the system which are contained in Terraform outputs.
|
57
|
+
#
|
58
|
+
# @param system_attrs_resolver [::Kitchen::Terraform::SystemAttrsResolver] the resolver.
|
59
|
+
# @return [self]
|
60
|
+
def resolve_attrs(system_attrs_resolver:)
|
61
|
+
system_attrs_resolver.resolve attrs_outputs_keys: @attrs_outputs.keys,
|
62
|
+
attrs_outputs_values: @attrs_outputs.values, system: self
|
63
|
+
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
# #resolve_hosts resolves the hosts of the system which are contained a Terraform output.
|
68
|
+
#
|
69
|
+
# @param system_hosts_resolver [::Kitchen::Terraform::SystemHostsResolver] the resolver.
|
70
|
+
# @return [self]
|
71
|
+
def resolve_hosts(system_hosts_resolver:)
|
72
|
+
system_hosts_resolver.resolve(
|
73
|
+
hosts_output: @mapping.fetch(:hosts_output) do
|
74
|
+
return self
|
75
|
+
end,
|
76
|
+
system: self,
|
77
|
+
)
|
78
|
+
|
79
|
+
self
|
80
|
+
end
|
81
|
+
|
82
|
+
# #to_s returns a string representation of the system.
|
83
|
+
#
|
84
|
+
# @return [::String] the name of the system.
|
85
|
+
def to_s
|
86
|
+
@mapping.fetch :name
|
87
|
+
end
|
88
|
+
|
89
|
+
# #verify verifies the system by executing InSpec.
|
90
|
+
#
|
91
|
+
# @param inspec_options [::Hash] the options to be passed to InSpec.
|
92
|
+
# @param inspec_profile_path [::String] the path to the profile which InSpec will execute.
|
93
|
+
# @return [self]
|
94
|
+
def verify(inspec_options:, inspec_profile_path:)
|
95
|
+
if @hosts.empty?
|
96
|
+
::Kitchen::Terraform::InSpecWithoutHosts
|
97
|
+
else
|
98
|
+
::Kitchen::Terraform::InSpecWithHosts
|
99
|
+
end
|
100
|
+
.new(options: inspec_options.merge(attributes: @attributes), profile_path: inspec_profile_path)
|
101
|
+
.exec(system: self)
|
102
|
+
|
103
|
+
self
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def initialize(mapping:)
|
109
|
+
@attributes = {}
|
110
|
+
@attrs_outputs = mapping.fetch :attrs_outputs do
|
111
|
+
{}
|
112
|
+
end
|
113
|
+
@hosts = mapping.fetch :hosts do
|
114
|
+
[]
|
115
|
+
end
|
116
|
+
@mapping = mapping
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|