kitchen-terraform 0.5.1 → 0.6.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 +2 -2
- data/README.md +61 -6
- data/lib/kitchen/driver/terraform.rb +37 -22
- data/lib/kitchen/provisioner/terraform.rb +14 -18
- data/lib/kitchen/verifier/terraform.rb +25 -48
- data/lib/terraform/apply_command.rb +11 -20
- data/lib/terraform/apply_timeout_config.rb +9 -11
- data/lib/terraform/cli_config.rb +29 -0
- data/lib/terraform/client.rb +57 -52
- data/lib/terraform/color_coercer.rb +35 -0
- data/lib/terraform/color_config.rb +9 -11
- data/lib/terraform/command.rb +16 -30
- data/lib/terraform/command_factory.rb +111 -0
- data/lib/terraform/command_option.rb +65 -0
- data/lib/terraform/command_options.rb +95 -0
- data/lib/terraform/configurable.rb +42 -17
- data/lib/terraform/{zero_six_output.rb → debug_logger.rb} +10 -7
- data/lib/terraform/deprecated_output_parser.rb +41 -0
- data/lib/terraform/deprecated_variables_coercer.rb +35 -0
- data/lib/terraform/{command_extender.rb → deprecated_version.rb} +10 -7
- data/lib/terraform/destructive_plan_command.rb +35 -0
- data/lib/terraform/directory_config.rb +10 -5
- data/lib/terraform/file_configs.rb +36 -0
- data/lib/terraform/get_command.rb +3 -10
- data/lib/terraform/group.rb +29 -29
- data/lib/terraform/group_attributes.rb +42 -0
- data/lib/terraform/group_hostnames.rb +38 -0
- data/lib/terraform/groups_coercer.rb +43 -0
- data/lib/terraform/groups_config.rb +8 -54
- data/lib/terraform/integer_coercer.rb +37 -0
- data/lib/terraform/{plan_config.rb → no_output_parser.rb} +8 -7
- data/lib/terraform/output_command.rb +3 -39
- data/lib/terraform/output_parser.rb +55 -0
- data/lib/terraform/parallelism_config.rb +9 -11
- data/lib/terraform/pathname_coercer.rb +40 -0
- data/lib/terraform/plan_command.rb +7 -41
- data/lib/terraform/prepare_input_file.rb +34 -0
- data/lib/terraform/{zero_seven_output.rb → prepare_output_file.rb} +11 -9
- data/lib/terraform/project_version.rb +19 -0
- data/lib/terraform/shell_out.rb +59 -0
- data/lib/terraform/show_command.rb +7 -16
- data/lib/terraform/simple_coercer.rb +36 -0
- data/lib/terraform/{state_config.rb → simple_config.rb} +7 -6
- data/lib/terraform/{color_switch.rb → unsupported_version.rb} +6 -8
- data/lib/terraform/validate_command.rb +3 -10
- data/lib/terraform/variable_files_coercer.rb +40 -0
- data/lib/terraform/variable_files_config.rb +9 -10
- data/lib/terraform/variables_coercer.rb +49 -0
- data/lib/terraform/variables_config.rb +9 -24
- data/lib/terraform/version.rb +55 -1
- data/lib/terraform/version_command.rb +3 -10
- metadata +58 -9
- metadata.gz.sig +0 -0
- data/lib/terraform/command_executor.rb +0 -41
data/lib/terraform/client.rb
CHANGED
@@ -14,78 +14,83 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
require_relative 'show_command'
|
23
|
-
require_relative 'validate_command'
|
24
|
-
require_relative 'version_command'
|
17
|
+
require 'terraform/command_factory'
|
18
|
+
require 'terraform/no_output_parser'
|
19
|
+
require 'terraform/output_parser'
|
20
|
+
require 'terraform/shell_out'
|
21
|
+
require 'terraform/version'
|
25
22
|
|
26
23
|
module Terraform
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
def apply_execution_plan
|
32
|
-
execute command: ApplyCommand.new(
|
33
|
-
color: provisioner[:color], parallelism: provisioner[:parallelism],
|
34
|
-
state: provisioner[:state], target: provisioner[:plan]
|
35
|
-
), timeout: provisioner[:apply_timeout]
|
24
|
+
# Client to execute commands
|
25
|
+
class Client
|
26
|
+
def apply_constructively
|
27
|
+
apply plan_command: factory.plan_command
|
36
28
|
end
|
37
29
|
|
38
|
-
def
|
39
|
-
|
40
|
-
command: ShowCommand
|
41
|
-
.new(color: provisioner[:color], target: provisioner[:state])
|
42
|
-
) { |value| return value.gsub(/(\e\[\d+m|\n)/, '') }
|
30
|
+
def apply_destructively
|
31
|
+
apply plan_command: factory.destructive_plan_command
|
43
32
|
end
|
44
33
|
|
45
|
-
def
|
46
|
-
|
34
|
+
def each_output_name(&block)
|
35
|
+
output_parser(name: '').each_name(&block)
|
47
36
|
end
|
48
37
|
|
49
|
-
def
|
50
|
-
|
51
|
-
command: OutputCommand.new(
|
52
|
-
list: list, state: provisioner[:state], target: name, version: version
|
53
|
-
)
|
54
|
-
) { |value| list ? value.each(&block) : (return value) }
|
38
|
+
def iterate_output(name:, &block)
|
39
|
+
output_parser(name: name).iterate_parsed_output(&block)
|
55
40
|
end
|
56
41
|
|
57
|
-
def
|
58
|
-
execute(
|
59
|
-
|
60
|
-
|
61
|
-
return_raw: true
|
62
|
-
)
|
63
|
-
) { |output| JSON.parse(output).each_key(&block) }
|
64
|
-
end
|
65
|
-
|
66
|
-
def plan_execution(destroy:)
|
67
|
-
execute command: plan_command(destroy: destroy)
|
42
|
+
def load_state(&block)
|
43
|
+
execute(command: factory.show_command) do |state|
|
44
|
+
/\w+/.match state, &block
|
45
|
+
end
|
68
46
|
end
|
69
47
|
|
70
|
-
def
|
71
|
-
|
48
|
+
def output(name:)
|
49
|
+
output_parser(name: name).parsed_output
|
72
50
|
end
|
73
51
|
|
74
52
|
def version
|
75
|
-
execute command:
|
76
|
-
return value
|
53
|
+
execute command: factory.version_command do |value|
|
54
|
+
return ::Terraform::Version.create value: value
|
77
55
|
end
|
78
56
|
end
|
79
57
|
|
80
58
|
private
|
81
59
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
60
|
+
attr_accessor :apply_timeout, :cli, :factory, :logger
|
61
|
+
|
62
|
+
def apply(plan_command:)
|
63
|
+
execute command: factory.validate_command
|
64
|
+
execute command: factory.get_command
|
65
|
+
execute command: plan_command
|
66
|
+
::Terraform::ShellOut.new(
|
67
|
+
cli: cli, command: factory.apply_command, logger: logger,
|
68
|
+
timeout: apply_timeout
|
69
|
+
).execute
|
70
|
+
end
|
71
|
+
|
72
|
+
def execute(command:, &block)
|
73
|
+
::Terraform::ShellOut
|
74
|
+
.new(cli: cli, command: command, logger: logger).execute(&block)
|
75
|
+
end
|
76
|
+
|
77
|
+
def initialize(config: {}, logger:)
|
78
|
+
self.apply_timeout = config[:apply_timeout]
|
79
|
+
self.cli = config[:cli]
|
80
|
+
self.factory = ::Terraform::CommandFactory.new config: config
|
81
|
+
self.logger = logger
|
82
|
+
end
|
83
|
+
|
84
|
+
def output_parser(name:)
|
85
|
+
execute(
|
86
|
+
command: factory.output_command(target: name, version: version)
|
87
|
+
) do |value|
|
88
|
+
return ::Terraform::OutputParser.create output: value, version: version
|
89
|
+
end
|
90
|
+
rescue ::Kitchen::StandardError => exception
|
91
|
+
raise exception unless exception.message =~ /no outputs/
|
92
|
+
|
93
|
+
::Terraform::NoOutputParser.new
|
89
94
|
end
|
90
95
|
end
|
91
96
|
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
|
+
module Terraform
|
18
|
+
# A coercer for the [:color] value
|
19
|
+
class ColorCoercer
|
20
|
+
def coerce(attr:, value:)
|
21
|
+
configurable[attr] = [true, false].find(
|
22
|
+
proc { configurable.config_error attr: attr, expected: 'a boolean' },
|
23
|
+
&value.method(:==)
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_accessor :configurable
|
30
|
+
|
31
|
+
def initialize(configurable:)
|
32
|
+
self.configurable = configurable
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -14,21 +14,19 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
+
require_relative 'color_coercer'
|
18
|
+
require_relative 'simple_config'
|
19
|
+
|
17
20
|
module Terraform
|
18
21
|
# Behaviour for the [:color] config option
|
19
22
|
module ColorConfig
|
20
|
-
|
21
|
-
configurable_class.required_config :color do |_, value, configurable|
|
22
|
-
configurable.coerce_color value: value
|
23
|
-
end
|
24
|
-
configurable_class.default_config :color, true
|
25
|
-
end
|
23
|
+
include ::Terraform::SimpleConfig
|
26
24
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
def self.extended(configurable_class)
|
26
|
+
configurable_class
|
27
|
+
.configure_required attr: :color,
|
28
|
+
coercer_class: ::Terraform::ColorCoercer,
|
29
|
+
default_value: true
|
32
30
|
end
|
33
31
|
end
|
34
32
|
end
|
data/lib/terraform/command.rb
CHANGED
@@ -14,54 +14,40 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
-
require '
|
17
|
+
require 'terraform/command_options'
|
18
18
|
|
19
19
|
module Terraform
|
20
20
|
# Terraform command to be executed
|
21
21
|
class Command
|
22
|
-
|
23
|
-
''
|
24
|
-
end
|
22
|
+
attr_reader :options, :target
|
25
23
|
|
26
|
-
def
|
27
|
-
|
28
|
-
end
|
24
|
+
def name
|
25
|
+
/(\w+)Command/.match(self.class.to_s) { |match| return match[1].downcase }
|
29
26
|
|
30
|
-
|
31
|
-
processed_output raw_output: shell_out.stdout
|
27
|
+
'help'
|
32
28
|
end
|
33
29
|
|
34
|
-
def
|
35
|
-
|
36
|
-
shell_out.timeout = timeout
|
37
|
-
shell_out.run_command
|
38
|
-
shell_out.error!
|
39
|
-
rescue => exception
|
40
|
-
handle_error exception: exception
|
30
|
+
def prepare
|
31
|
+
preparations.each(&:execute)
|
41
32
|
end
|
42
33
|
|
43
34
|
def to_s
|
44
|
-
|
35
|
+
"#{name} #{options} #{target}".strip
|
45
36
|
end
|
46
37
|
|
47
38
|
private
|
48
39
|
|
49
|
-
attr_accessor :
|
40
|
+
attr_accessor :preparations
|
50
41
|
|
51
|
-
|
52
|
-
raise exception
|
53
|
-
end
|
54
|
-
|
55
|
-
def initialize(target: '', **keyword_arguments)
|
56
|
-
initialize_attributes(**keyword_arguments)
|
57
|
-
self.shell_out = Mixlib::ShellOut
|
58
|
-
.new "terraform #{name} #{options} #{target}", returns: 0
|
59
|
-
end
|
42
|
+
attr_writer :options, :target
|
60
43
|
|
61
|
-
def
|
44
|
+
def initialize(target: '', &block)
|
45
|
+
block ||= proc {}
|
62
46
|
|
63
|
-
|
64
|
-
|
47
|
+
self.options = ::Terraform::CommandOptions.new
|
48
|
+
self.preparations = []
|
49
|
+
self.target = target
|
50
|
+
block.call options
|
65
51
|
end
|
66
52
|
end
|
67
53
|
end
|
@@ -0,0 +1,111 @@
|
|
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 'terraform/apply_command'
|
18
|
+
require 'terraform/destructive_plan_command'
|
19
|
+
require 'terraform/get_command'
|
20
|
+
require 'terraform/output_command'
|
21
|
+
require 'terraform/plan_command'
|
22
|
+
require 'terraform/show_command'
|
23
|
+
require 'terraform/validate_command'
|
24
|
+
require 'terraform/version_command'
|
25
|
+
|
26
|
+
module Terraform
|
27
|
+
# A factory to create commands
|
28
|
+
class CommandFactory
|
29
|
+
def apply_command
|
30
|
+
::Terraform::ApplyCommand.new target: config[:plan] do |options|
|
31
|
+
options.color = config[:color]
|
32
|
+
options.input = false
|
33
|
+
options.parallelism = config[:parallelism]
|
34
|
+
options.state = config[:state]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def destructive_plan_command
|
39
|
+
::Terraform::DestructivePlanCommand
|
40
|
+
.new target: config[:directory] do |options|
|
41
|
+
configure_plan options: options
|
42
|
+
options.destroy = true
|
43
|
+
options.state = config[:state]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_command
|
48
|
+
::Terraform::GetCommand.new target: config[:directory] do |options|
|
49
|
+
options.update = true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def output_command(target:, version:)
|
54
|
+
version
|
55
|
+
.if_json_not_supported { return base_output_command target: target }
|
56
|
+
|
57
|
+
json_output_command target: target
|
58
|
+
end
|
59
|
+
|
60
|
+
def plan_command
|
61
|
+
::Terraform::PlanCommand.new target: config[:directory] do |options|
|
62
|
+
configure_plan options: options
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def show_command
|
67
|
+
::Terraform::ShowCommand.new target: config[:state] do |options|
|
68
|
+
options.color = config[:color]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def validate_command
|
73
|
+
::Terraform::ValidateCommand.new target: config[:directory]
|
74
|
+
end
|
75
|
+
|
76
|
+
def version_command
|
77
|
+
::Terraform::VersionCommand.new
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
attr_accessor :config
|
83
|
+
|
84
|
+
def base_output_command(target:, &block)
|
85
|
+
block ||= proc {}
|
86
|
+
|
87
|
+
::Terraform::OutputCommand.new target: target do |options|
|
88
|
+
options.color = config[:color]
|
89
|
+
options.state = config[:state]
|
90
|
+
block.call options
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def configure_plan(options:)
|
95
|
+
options.color = config[:color]
|
96
|
+
options.input = false
|
97
|
+
options.out = config[:plan]
|
98
|
+
options.parallelism = config[:parallelism]
|
99
|
+
options.var = config[:variables]
|
100
|
+
options.var_file = config[:variable_files]
|
101
|
+
end
|
102
|
+
|
103
|
+
def initialize(config:)
|
104
|
+
self.config = config
|
105
|
+
end
|
106
|
+
|
107
|
+
def json_output_command(target:)
|
108
|
+
base_output_command(target: target) { |options| options.json = true }
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,65 @@
|
|
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
|
+
module Terraform
|
18
|
+
# An option for a command
|
19
|
+
class CommandOption
|
20
|
+
attr_reader :key, :value
|
21
|
+
|
22
|
+
def ==(other)
|
23
|
+
tuple == other.tuple
|
24
|
+
end
|
25
|
+
|
26
|
+
alias eql? ==
|
27
|
+
|
28
|
+
def hash
|
29
|
+
stripped_key.hash & stripped_value.hash
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
"#{formatted_key}#{formatted_value}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def tuple
|
37
|
+
[stripped_key, stripped_value]
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
attr_accessor :stripped_key, :stripped_value
|
43
|
+
|
44
|
+
attr_writer :key, :value
|
45
|
+
|
46
|
+
def initialize(key:, value: '')
|
47
|
+
self.key = key
|
48
|
+
self.stripped_key = stripped_string config_string: key
|
49
|
+
self.stripped_value = stripped_string config_string: value
|
50
|
+
self.value = value
|
51
|
+
end
|
52
|
+
|
53
|
+
def formatted_key
|
54
|
+
"-#{stripped_key}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def formatted_value
|
58
|
+
stripped_value.sub(/(\S)/, '=\1')
|
59
|
+
end
|
60
|
+
|
61
|
+
def stripped_string(config_string:)
|
62
|
+
String(config_string).gsub(/\s/, '')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|