kitchen-terraform 0.1.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 +7 -0
- checksums.yaml.gz.sig +1 -0
- data.tar.gz.sig +0 -0
- data/lib/kitchen/driver/terraform.rb +57 -0
- data/lib/kitchen/provisioner/terraform.rb +58 -0
- data/lib/kitchen/verifier/terraform.rb +109 -0
- data/lib/terraform/apply_command.rb +32 -0
- data/lib/terraform/client.rb +102 -0
- data/lib/terraform/client_holder.rb +26 -0
- data/lib/terraform/command.rb +58 -0
- data/lib/terraform/command_options.rb +45 -0
- data/lib/terraform/error.rb +20 -0
- data/lib/terraform/get_command.rb +32 -0
- data/lib/terraform/inspec_runner.rb +44 -0
- data/lib/terraform/invalid_version.rb +34 -0
- data/lib/terraform/output_command.rb +38 -0
- data/lib/terraform/output_not_found.rb +23 -0
- data/lib/terraform/plan_command.rb +35 -0
- data/lib/terraform/validate_command.rb +32 -0
- data/lib/terraform/version.rb +19 -0
- data/lib/terraform/version_command.rb +32 -0
- data/spec/lib/kitchen/driver/terraform_spec.rb +126 -0
- data/spec/lib/kitchen/provisioner/terraform_spec.rb +106 -0
- data/spec/lib/kitchen/verifier/terraform_spec.rb +302 -0
- data/spec/lib/terraform/apply_command_spec.rb +32 -0
- data/spec/lib/terraform/client_spec.rb +211 -0
- data/spec/lib/terraform/command_options_spec.rb +34 -0
- data/spec/lib/terraform/get_command_spec.rb +30 -0
- data/spec/lib/terraform/inspec_runner_spec.rb +67 -0
- data/spec/lib/terraform/output_command_spec.rb +58 -0
- data/spec/lib/terraform/plan_command_spec.rb +46 -0
- data/spec/lib/terraform/validate_command_spec.rb +30 -0
- data/spec/lib/terraform/version_command_spec.rb +30 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/coverage.rb +21 -0
- data/spec/support/terraform/client_holder_context.rb +26 -0
- data/spec/support/terraform/client_holder_examples.rb +36 -0
- data/spec/support/terraform/command_examples.rb +80 -0
- data/spec/support/terraform/versions_are_set_examples.rb +35 -0
- metadata +329 -0
- metadata.gz.sig +2 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f03cf599dfe3f84c964a2ee046ee339fec308920
|
4
|
+
data.tar.gz: a796e35249231547ce68cef067bd1408f30295b7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fee5b34d17854a32f579363580050bd6406e3fa3e9628e88102d1b0c888e19546d2df7e259c4bdb4bfa3f133323304f4d3bf41daa5e6469ef61f44a9cbae38eb
|
7
|
+
data.tar.gz: 1c1cff573cf5973649ec40728443a78f7aaa147204ec09d10db9ffd21d6eeab99ccc89c33edf418bd67d49c0104691cec0884d41bcc440f9285f4ca4b5082e06
|
checksums.yaml.gz.sig
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
y�ޭ�H#�&��lmD���5��ō:N��/���[!�?�*�\a1f�2<�r�I�zi�OH8���o؊���xo�\����r�Ў��R#ҶL���ӓ�z�RJb~ĭ��M�-E,�q��*I�u��+�=��3�JK�"..��6��U�m1S�B�����b)�`�Z%�ħy��U�'��S�'ce�'���]v=���]�5Mi�n���L��[g�.�����r�au":�L��6���h���J��
|
data.tar.gz.sig
ADDED
Binary file
|
@@ -0,0 +1,57 @@
|
|
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 'terraform/client_holder'
|
19
|
+
require 'terraform/invalid_version'
|
20
|
+
require 'terraform/version'
|
21
|
+
|
22
|
+
module Kitchen
|
23
|
+
module Driver
|
24
|
+
# Terraform state lifecycle activities manager
|
25
|
+
class Terraform < Base
|
26
|
+
include ::Terraform::ClientHolder
|
27
|
+
|
28
|
+
kitchen_driver_api_version 2
|
29
|
+
|
30
|
+
plugin_version ::Terraform::VERSION
|
31
|
+
|
32
|
+
no_parallel_for
|
33
|
+
|
34
|
+
def create(_state = nil)
|
35
|
+
client.fetch_version do |output|
|
36
|
+
raise ::Terraform::InvalidVersion, supported_version, caller unless
|
37
|
+
output.match supported_version
|
38
|
+
end
|
39
|
+
rescue => error
|
40
|
+
raise Kitchen::ActionFailed, error.message, error.backtrace
|
41
|
+
end
|
42
|
+
|
43
|
+
def destroy(_state = nil)
|
44
|
+
client.validate_configuration_files
|
45
|
+
client.download_modules
|
46
|
+
client.plan_destructive_execution
|
47
|
+
client.apply_execution_plan
|
48
|
+
rescue => error
|
49
|
+
raise Kitchen::ActionFailed, error.message, error.backtrace
|
50
|
+
end
|
51
|
+
|
52
|
+
def supported_version
|
53
|
+
'v0.6'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,58 @@
|
|
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 'pathname'
|
19
|
+
require 'terraform/client_holder'
|
20
|
+
require 'terraform/version'
|
21
|
+
|
22
|
+
module Kitchen
|
23
|
+
module Provisioner
|
24
|
+
# Terraform configuration applier
|
25
|
+
class Terraform < Base
|
26
|
+
include ::Terraform::ClientHolder
|
27
|
+
|
28
|
+
kitchen_provisioner_api_version 2
|
29
|
+
|
30
|
+
plugin_version ::Terraform::VERSION
|
31
|
+
|
32
|
+
def call(_state = nil)
|
33
|
+
client.validate_configuration_files
|
34
|
+
client.download_modules
|
35
|
+
client.plan_execution
|
36
|
+
client.apply_execution_plan
|
37
|
+
rescue => error
|
38
|
+
raise Kitchen::ActionFailed, error.message, error.backtrace
|
39
|
+
end
|
40
|
+
|
41
|
+
def directory
|
42
|
+
config.fetch(:directory) { kitchen_root }
|
43
|
+
end
|
44
|
+
|
45
|
+
def kitchen_root
|
46
|
+
Pathname.new config.fetch :kitchen_root
|
47
|
+
end
|
48
|
+
|
49
|
+
def variable_files
|
50
|
+
config.fetch(:variable_files) { [] }
|
51
|
+
end
|
52
|
+
|
53
|
+
def variables
|
54
|
+
config.fetch(:variables) { [] }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,109 @@
|
|
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/verifier/inspec'
|
19
|
+
require 'terraform/client_holder'
|
20
|
+
require 'terraform/inspec_runner'
|
21
|
+
require 'terraform/version'
|
22
|
+
|
23
|
+
module Kitchen
|
24
|
+
module Verifier
|
25
|
+
# Runs tests post-converge to confirm that instances in the Terraform state
|
26
|
+
# are in an expected state
|
27
|
+
class Terraform < Inspec
|
28
|
+
include ::Terraform::ClientHolder
|
29
|
+
|
30
|
+
kitchen_verifier_api_version 2
|
31
|
+
|
32
|
+
plugin_version ::Terraform::VERSION
|
33
|
+
|
34
|
+
def attributes(group:)
|
35
|
+
group.fetch(:attributes) { {} }
|
36
|
+
end
|
37
|
+
|
38
|
+
def call(state)
|
39
|
+
groups.each do |group|
|
40
|
+
client.extract_list_output name: group.fetch(:hostnames) do |output|
|
41
|
+
verify group: group, hostnames: output, state: state
|
42
|
+
end
|
43
|
+
end
|
44
|
+
rescue => error
|
45
|
+
raise ActionFailed, error.message, error.backtrace
|
46
|
+
end
|
47
|
+
|
48
|
+
def controls(group:)
|
49
|
+
group.fetch(:controls) { [] }
|
50
|
+
end
|
51
|
+
|
52
|
+
def evaluate(exit_code:)
|
53
|
+
raise "Inspec Runner returns #{exit_code}" unless 0 == exit_code
|
54
|
+
end
|
55
|
+
|
56
|
+
def groups
|
57
|
+
config.fetch(:groups) { [] }
|
58
|
+
end
|
59
|
+
|
60
|
+
def initialize_runner(group:, hostname:, state:)
|
61
|
+
::Terraform::InspecRunner
|
62
|
+
.new runner_options_for_terraform group: group, hostname: hostname,
|
63
|
+
state: state do |runner|
|
64
|
+
resolve_attributes group: group do |name, value|
|
65
|
+
runner.define_attribute name: name, value: value
|
66
|
+
end
|
67
|
+
runner.add targets: collect_tests
|
68
|
+
yield runner
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def port(group:)
|
73
|
+
# FIXME: apply the principle of least knowledge
|
74
|
+
group.fetch(:port) { instance.transport.send(:config).fetch :port }
|
75
|
+
end
|
76
|
+
|
77
|
+
def resolve_attributes(group:)
|
78
|
+
attributes(group: group).each_pair do |method_name, variable_name|
|
79
|
+
client.extract_output name: variable_name do |output|
|
80
|
+
yield method_name, output
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def runner_options_for_terraform(group:, hostname:, state:)
|
86
|
+
runner_options(instance.transport, state)
|
87
|
+
.merge controls: controls(group: group), host: hostname,
|
88
|
+
port: port(group: group), user: username(group: group)
|
89
|
+
end
|
90
|
+
|
91
|
+
def username(group:)
|
92
|
+
# FIXME: apply the principle of least knowledge
|
93
|
+
group.fetch :username do
|
94
|
+
instance.transport.send(:config).fetch :username
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def verify(group:, hostnames:, state:)
|
99
|
+
hostnames.each do |hostname|
|
100
|
+
info "Verifying group: #{group.fetch :name}; hostname #{hostname}\n"
|
101
|
+
initialize_runner group: group, hostname: hostname,
|
102
|
+
state: state do |runner|
|
103
|
+
runner.verify_run verifier: self
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,32 @@
|
|
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_relative 'command'
|
18
|
+
|
19
|
+
module Terraform
|
20
|
+
# Command to apply an execution plan
|
21
|
+
class ApplyCommand
|
22
|
+
include Command
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def initialize_attributes(state:, plan:)
|
27
|
+
self.name = 'apply'
|
28
|
+
self.options = { input: false, state: state }
|
29
|
+
self.target = plan
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,102 @@
|
|
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_relative 'apply_command'
|
18
|
+
require_relative 'get_command'
|
19
|
+
require_relative 'output_command'
|
20
|
+
require_relative 'plan_command'
|
21
|
+
require_relative 'validate_command'
|
22
|
+
require_relative 'version_command'
|
23
|
+
|
24
|
+
module Terraform
|
25
|
+
# Runs Mixlib Terraform Command instances
|
26
|
+
class Client
|
27
|
+
extend Forwardable
|
28
|
+
|
29
|
+
def_delegators :provisioner, :directory, :info, :kitchen_root,
|
30
|
+
:variable_files, :variables
|
31
|
+
|
32
|
+
def apply_execution_plan
|
33
|
+
run command_class: ApplyCommand, state: state_pathname,
|
34
|
+
plan: plan_pathname
|
35
|
+
end
|
36
|
+
|
37
|
+
def download_modules
|
38
|
+
run command_class: GetCommand, dir: directory
|
39
|
+
end
|
40
|
+
|
41
|
+
def extract_list_output(name:)
|
42
|
+
extract_output(name: name) { |output| yield output.split ',' }
|
43
|
+
end
|
44
|
+
|
45
|
+
def extract_output(name:)
|
46
|
+
run(
|
47
|
+
command_class: OutputCommand, state: state_pathname, name: name
|
48
|
+
) { |output| yield output.chomp }
|
49
|
+
end
|
50
|
+
|
51
|
+
def fetch_version
|
52
|
+
run(command_class: VersionCommand) { |output| yield output }
|
53
|
+
end
|
54
|
+
|
55
|
+
def instance_directory
|
56
|
+
kitchen_root.join '.kitchen', 'kitchen-terraform', instance_name
|
57
|
+
end
|
58
|
+
|
59
|
+
def plan_destructive_execution
|
60
|
+
run command_class: PlanCommand, destroy: true, out: plan_pathname,
|
61
|
+
state: state_pathname, var: variables, var_file: variable_files,
|
62
|
+
dir: directory
|
63
|
+
end
|
64
|
+
|
65
|
+
def plan_execution
|
66
|
+
run command_class: PlanCommand, destroy: false, out: plan_pathname,
|
67
|
+
state: state_pathname, var: variables, var_file: variable_files,
|
68
|
+
dir: directory
|
69
|
+
end
|
70
|
+
|
71
|
+
def plan_pathname
|
72
|
+
instance_directory.join 'terraform.tfplan'
|
73
|
+
end
|
74
|
+
|
75
|
+
def run(command_class:, **parameters)
|
76
|
+
command_class.new(**parameters) do |command|
|
77
|
+
info command
|
78
|
+
command.execute do |output|
|
79
|
+
info output
|
80
|
+
yield output if block_given?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def state_pathname
|
86
|
+
instance_directory.join 'terraform.tfstate'
|
87
|
+
end
|
88
|
+
|
89
|
+
def validate_configuration_files
|
90
|
+
run command_class: ValidateCommand, dir: directory
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
attr_accessor :instance_name, :provisioner
|
96
|
+
|
97
|
+
def initialize(instance:)
|
98
|
+
self.instance_name = instance.name
|
99
|
+
self.provisioner = instance.provisioner
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,26 @@
|
|
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_relative 'client'
|
18
|
+
|
19
|
+
module Terraform
|
20
|
+
# Logic to provide a lazily initialized Client instance
|
21
|
+
module ClientHolder
|
22
|
+
def client
|
23
|
+
@client ||= Client.new instance: instance
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,58 @@
|
|
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 'mixlib/shellout'
|
18
|
+
require 'pathname'
|
19
|
+
require_relative 'command_options'
|
20
|
+
require_relative 'error'
|
21
|
+
|
22
|
+
module Terraform
|
23
|
+
# Common logic for Mixlib::ShellOut Terraform commands
|
24
|
+
module Command
|
25
|
+
attr_reader :name, :options, :target
|
26
|
+
|
27
|
+
def execute
|
28
|
+
# TODO: use the live output stream
|
29
|
+
shell_out.run_command
|
30
|
+
shell_out.error!
|
31
|
+
yield shell_out.stdout if block_given?
|
32
|
+
rescue => error
|
33
|
+
handle error: error
|
34
|
+
raise Error, error.message, error.backtrace
|
35
|
+
end
|
36
|
+
|
37
|
+
def handle(**_)
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
CommandOptions.new options do |command_options|
|
42
|
+
return "terraform #{name} #{command_options} #{target}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
attr_accessor :shell_out
|
49
|
+
|
50
|
+
attr_writer :name, :options, :target
|
51
|
+
|
52
|
+
def initialize(**keyword_arguments)
|
53
|
+
initialize_attributes(**keyword_arguments)
|
54
|
+
self.shell_out = Mixlib::ShellOut.new to_s, returns: 0
|
55
|
+
yield self if block_given?
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|